diff --git a/.editorconfig b/.editorconfig
index efe9133c8ff..72707109516 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -103,6 +103,8 @@ dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
# Suggest more modern language features when available
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
+# Background Info: https://github.com/dotnet/runtime/pull/100250
+dotnet_style_prefer_collection_expression = when_types_exactly_match
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
@@ -117,6 +119,13 @@ csharp_prefer_simple_default_expression = true:suggestion
dotnet_code_quality_unused_parameters = non_public:suggestion
+# Dotnet diagnostic settings:
+[*.cs]
+
+# CA1859: Use concrete types when possible for improved performance
+# https://learn.microsoft.com/en-gb/dotnet/fundamentals/code-analysis/quality-rules/ca1859
+dotnet_diagnostic.CA1859.severity = suggestion
+
# CSharp code style settings:
[*.cs]
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 7996891b5f7..fdb18f82c9d 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,57 +1,6 @@
version: 2
updates:
- - package-ecosystem: "nuget"
- directory: "/"
- schedule:
- interval: "daily"
- labels:
- - "CL-BuildPackaging"
- ignore:
- - dependency-name: "System.*"
- - dependency-name: "Microsoft.Win32.Registry.AccessControl"
- - dependency-name: "Microsoft.Windows.Compatibility"
-
- - package-ecosystem: "nuget"
- directory: "/tools/packaging/projects/reference/Microsoft.PowerShell.Commands.Utility"
- schedule:
- interval: "daily"
- labels:
- - "CL-BuildPackaging"
- ignore:
- - dependency-name: "System.*"
- - dependency-name: "Microsoft.Win32.Registry.AccessControl"
- - dependency-name: "Microsoft.Windows.Compatibility"
-
- - package-ecosystem: "nuget"
- directory: "/tools/packaging/projects/reference/System.Management.Automation"
- schedule:
- interval: "daily"
- labels:
- - "CL-BuildPackaging"
- ignore:
- - dependency-name: "System.*"
- - dependency-name: "Microsoft.Win32.Registry.AccessControl"
- - dependency-name: "Microsoft.Windows.Compatibility"
-
- - package-ecosystem: "nuget"
- directory: "/test/tools/Modules"
- schedule:
- interval: "daily"
- labels:
- - "CL-BuildPackaging"
- ignore:
- - dependency-name: "System.*"
- - dependency-name: "Microsoft.Win32.Registry.AccessControl"
- - dependency-name: "Microsoft.Windows.Compatibility"
-
- - package-ecosystem: "nuget"
- directory: "/src/Modules"
- schedule:
- interval: "daily"
- labels:
- - "CL-BuildPackaging"
-
- package-ecosystem: "github-actions"
directory: "/"
schedule:
diff --git a/.github/workflows/AssignPrs.yml b/.github/workflows/AssignPrs.yml
index d398cd7cffe..a01c0bb0950 100644
--- a/.github/workflows/AssignPrs.yml
+++ b/.github/workflows/AssignPrs.yml
@@ -7,6 +7,7 @@ permissions:
jobs:
run:
+ if: github.repository_owner == 'PowerShell'
runs-on: ubuntu-latest
permissions:
issues: write
diff --git a/.github/workflows/createReminders.yml b/.github/workflows/createReminders.yml
index 3e8c0180b3d..d9c4da0efb7 100644
--- a/.github/workflows/createReminders.yml
+++ b/.github/workflows/createReminders.yml
@@ -9,6 +9,8 @@ permissions:
jobs:
reminder:
+ if: github.repository_owner == 'PowerShell'
+
permissions:
issues: write # for agrc/create-reminder-action to set reminders on issues
pull-requests: write # for agrc/create-reminder-action to set reminders on PRs
@@ -16,4 +18,4 @@ jobs:
steps:
- name: check for reminder
- uses: agrc/create-reminder-action@1bc8a409a8b377b781b2be426be54067b7a2dcab # v1.1.16
+ uses: agrc/create-reminder-action@9ff30cde74284045941af16a04362938957253b1 # v1.1.17
diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml
new file mode 100644
index 00000000000..a580c1f5185
--- /dev/null
+++ b/.github/workflows/labels.yml
@@ -0,0 +1,31 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+name: Verify PR Labels
+
+on:
+ pull_request:
+ types: [opened, reopened, edited, labeled, unlabeled, synchronize]
+
+permissions:
+ contents: read
+ pull-requests: read
+
+jobs:
+ verify-labels:
+ if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell'
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check out the repository
+ uses: actions/checkout@v4
+
+ - name: Verify PR has label starting with 'cl-'
+ id: verify-labels
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const labels = context.payload.pull_request.labels.map(label => label.name.toLowerCase());
+ if (!labels.some(label => label.startsWith('cl-'))) {
+ core.setFailed("Every PR must have at least one label starting with 'cl-'.");
+ }
diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml
index 68b651c7e46..54282fc62f6 100644
--- a/.github/workflows/linux-ci.yml
+++ b/.github/workflows/linux-ci.yml
@@ -37,6 +37,7 @@ env:
system_debug: 'false'
jobs:
changes:
+ if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell'
name: Change Detection
runs-on: ubuntu-latest
# Required permissions
@@ -47,10 +48,10 @@ jobs:
source: ${{ steps.filter.outputs.source }}
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
# For pull requests it's not necessary to checkout the code
- - uses: dorny/paths-filter@v3
+ - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0
id: filter
with:
list-files: json
@@ -69,12 +70,12 @@ jobs:
ci_build:
name: Build PowerShell
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.source == 'true' }}
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
@@ -86,10 +87,10 @@ jobs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Linux Unelevated CI
@@ -103,10 +104,10 @@ jobs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Linux Elevated CI
@@ -120,10 +121,10 @@ jobs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Linux Unelevated Others
@@ -137,10 +138,10 @@ jobs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Linux Elevated Others
@@ -157,7 +158,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Verify xUnit test results
@@ -194,7 +195,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
+ uses: github/codeql-action/init@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -220,7 +221,7 @@ jobs:
shell: pwsh
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
+ uses: github/codeql-action/analyze@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13
ready_to_merge:
name: Linux ready to merge
@@ -232,7 +233,7 @@ jobs:
- linux_test_unelevated_others
- analyze
if: always()
- uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master
+ uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0
with:
needs_context: ${{ toJson(needs) }}
# TODO: Enable this when we have a Linux packaging workflow
@@ -247,7 +248,7 @@ jobs:
# runs-on: ubuntu-20.04
# steps:
# - name: checkout
- # uses: actions/checkout@v4.1.0
+ # uses: actions/checkout@v4
# with:
# fetch-depth: 1000
# - name: Verify xUnit test results
diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml
index b414afebfc9..fcb69332740 100644
--- a/.github/workflows/macos-ci.yml
+++ b/.github/workflows/macos-ci.yml
@@ -38,6 +38,7 @@ jobs:
changes:
name: Change Detection
runs-on: ubuntu-latest
+ if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell'
# Required permissions
permissions:
pull-requests: read
@@ -46,10 +47,10 @@ jobs:
source: ${{ steps.filter.outputs.source }}
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
# For pull requests it's not necessary to checkout the code
- - uses: dorny/paths-filter@v3
+ - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0
id: filter
with:
list-files: json
@@ -73,7 +74,7 @@ jobs:
if: ${{ needs.changes.outputs.source == 'true' }}
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Build
@@ -87,7 +88,7 @@ jobs:
runs-on: macos-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: macOS Unelevated CI
@@ -104,7 +105,7 @@ jobs:
runs-on: macos-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: macOS Elevated CI
@@ -121,7 +122,7 @@ jobs:
runs-on: macos-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: macOS Unelevated Others
@@ -138,7 +139,7 @@ jobs:
runs-on: macos-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: macOS Elevated Others
@@ -155,7 +156,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Verify xUnit test results
@@ -169,7 +170,7 @@ jobs:
- macos-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
- name: Bootstrap packaging
if: success() || failure()
run: |-
@@ -186,6 +187,6 @@ jobs:
- macos_test_unelevated_ci
- macos_test_unelevated_others
if: always()
- uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master
+ uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0
with:
needs_context: ${{ toJson(needs) }}
diff --git a/.github/workflows/markdownLink.yml b/.github/workflows/markdownLink.yml
index b451885acea..27e0f9eff5d 100644
--- a/.github/workflows/markdownLink.yml
+++ b/.github/workflows/markdownLink.yml
@@ -10,6 +10,8 @@ permissions:
jobs:
markdown-link-check:
runs-on: ubuntu-latest
+ if: github.repository_owner == 'PowerShell'
+
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1
@@ -31,7 +33,7 @@ jobs:
# list of changed files within `super-linter`
fetch-depth: 0
- name: Lint Markdown
- uses: super-linter/super-linter@85f7611e0f7b53c8573cca84aa0ed4344f6f6a4d # v7.2.1
+ uses: super-linter/super-linter@4e8a7c2bf106c4c766c816b35ec612638dc9b6b2 # v7.3.0
env:
VALIDATE_ALL_CODEBASE: false
DEFAULT_BRANCH: master
diff --git a/.github/workflows/processReminders.yml b/.github/workflows/processReminders.yml
index 82734c829d6..339234a3c56 100644
--- a/.github/workflows/processReminders.yml
+++ b/.github/workflows/processReminders.yml
@@ -10,6 +10,7 @@ permissions:
jobs:
reminder:
+ if: github.repository_owner == 'PowerShell'
permissions:
issues: write # for agrc/reminder-action to set reminders on issues
pull-requests: write # for agrc/reminder-action to set reminders on PRs
@@ -17,4 +18,4 @@ jobs:
steps:
- name: check reminders and notify
- uses: agrc/reminder-action@45201302ec0071cce809a483111bda4cdc7d10f2 # v1.0.15
+ uses: agrc/reminder-action@96f2ec2e1a7a53ead156504922e9bc36d64f49ee # v1.0.16
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 7651d3f1959..a8e136cc63f 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -20,6 +20,7 @@ permissions: read-all
jobs:
analysis:
name: Scorecard analysis
+ if: github.repository_owner == 'PowerShell'
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
@@ -36,7 +37,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
+ uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
@@ -58,7 +59,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@@ -66,6 +67,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
+ uses: github/codeql-action/upload-sarif@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13
with:
sarif_file: results.sarif
diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml
index c93983a765f..a18029bfbe0 100644
--- a/.github/workflows/windows-ci.yml
+++ b/.github/workflows/windows-ci.yml
@@ -39,6 +39,7 @@ jobs:
changes:
name: Change Detection
runs-on: ubuntu-latest
+ if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell'
# Required permissions
permissions:
pull-requests: read
@@ -47,10 +48,10 @@ jobs:
source: ${{ steps.filter.outputs.source }}
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
# For pull requests it's not necessary to checkout the code
- - uses: dorny/paths-filter@v3
+ - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0
id: filter
with:
list-files: json
@@ -74,7 +75,7 @@ jobs:
runs-on: windows-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Build
@@ -88,7 +89,7 @@ jobs:
runs-on: windows-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Windows Unelevated CI
@@ -105,7 +106,7 @@ jobs:
runs-on: windows-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Windows Elevated CI
@@ -122,7 +123,7 @@ jobs:
runs-on: windows-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Windows Unelevated Others
@@ -139,7 +140,7 @@ jobs:
runs-on: windows-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Windows Elevated Others
@@ -156,7 +157,7 @@ jobs:
runs-on: windows-latest
steps:
- name: checkout
- uses: actions/checkout@v4.1.0
+ uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Verify xUnit test results
@@ -170,6 +171,6 @@ jobs:
- windows_test_unelevated_ci
- windows_test_unelevated_others
if: always()
- uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master
+ uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0
with:
needs_context: ${{ toJson(needs) }}
diff --git a/.pipelines/PowerShell-Coordinated_Packages-Official.yml b/.pipelines/PowerShell-Coordinated_Packages-Official.yml
index 6c84067ce47..902c31f8a96 100644
--- a/.pipelines/PowerShell-Coordinated_Packages-Official.yml
+++ b/.pipelines/PowerShell-Coordinated_Packages-Official.yml
@@ -151,6 +151,8 @@ extends:
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_signing_setup_enabled
value: false
+ - name: ob_sdl_sbom_enabled
+ value: false
steps:
- checkout: self
diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml
index 7fce394ca19..30b9e415215 100644
--- a/.pipelines/PowerShell-Packages-Official.yml
+++ b/.pipelines/PowerShell-Packages-Official.yml
@@ -51,7 +51,7 @@ variables:
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: WindowsContainerImage
- value: 'onebranch.azurecr.io/windows/ltsc2019/vse2022:latest' # Docker image which is used to build the project
+ value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # Docker image which is used to build the project
- name: LinuxContainerImage
value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0
- group: mscodehub-feed-read-general
@@ -64,7 +64,7 @@ variables:
resources:
pipelines:
- pipeline: CoOrdinatedBuildPipeline
- source: 'PowerShell-Coordinated Packages-Official'
+ source: 'PowerShell-Coordinated Binaries-Official'
trigger:
branches:
include:
@@ -83,6 +83,9 @@ extends:
cloudvault:
enabled: false
featureFlags:
+ WindowsHostVersion:
+ Version: 2022
+ Network: KS3
linuxEsrpSigning: true
globalSdl:
disableLegacyManifest: true
diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml
index acba669ffa3..2d644c7a5dd 100644
--- a/.pipelines/PowerShell-Release-Official-Azure.yml
+++ b/.pipelines/PowerShell-Release-Official-Azure.yml
@@ -56,7 +56,7 @@ resources:
pipelines:
- pipeline: CoOrdinatedBuildPipeline
- source: 'PowerShell-Coordinated Packages-Official'
+ source: 'PowerShell-Coordinated Binaries-Official'
- pipeline: PSPackagesOfficial
source: 'PowerShell-Packages-Official'
diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml
index 335ef4f71d3..bb83c98ae81 100644
--- a/.pipelines/PowerShell-Release-Official.yml
+++ b/.pipelines/PowerShell-Release-Official.yml
@@ -72,7 +72,7 @@ resources:
pipelines:
- pipeline: CoOrdinatedBuildPipeline
- source: 'PowerShell-Coordinated Packages-Official'
+ source: 'PowerShell-Coordinated Binaries-Official'
- pipeline: PSPackagesOfficial
source: 'PowerShell-Packages-Official'
diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml
index c2dcfc49735..8a3679d1210 100644
--- a/.pipelines/PowerShell-vPack-Official.yml
+++ b/.pipelines/PowerShell-vPack-Official.yml
@@ -142,18 +142,27 @@ extends:
$vstsCommandString = "vso[task.setvariable variable=PackageArtifactName]$packageArtifactName"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
- displayName: 'Set package artifact name'
+
+ $packageArtifactPath = '$(Pipeline.Workspace)\PSPackagesOfficial'
+ $vstsCommandString = "vso[task.setvariable variable=PackageArtifactPath]$packageArtifactPath"
+ Write-Host "sending " + $vstsCommandString
+ Write-Host "##$vstsCommandString"
+ displayName: 'Set package artifact variables'
- download: PSPackagesOfficial
artifact: $(PackageArtifactName)
displayName: Download package
- - pwsh: 'Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name'
+ - pwsh: 'Get-ChildItem $(PackageArtifactPath)\* -recurse | Select-Object -ExpandProperty Name'
displayName: 'Capture Artifact Listing'
- pwsh: |
$message = @()
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object {
+ $packages = Get-ChildItem $(PackageArtifactPath)\* -recurse -include *.zip, *.msi
+
+ if($packages.count -eq 0) {throw "No packages found in $(PackageArtifactPath)"}
+
+ $packages | ForEach-Object {
if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}')
{
$messageInstance = "$($_.Name) is not a valid package name"
@@ -166,7 +175,7 @@ extends:
displayName: 'Validate Zip and MSI Package Names'
- pwsh: |
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object {
+ Get-ChildItem $(PackageArtifactPath)\* -recurse -include *.zip | ForEach-Object {
if($_.Name -match 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(${{ parameters.architecture }})\.(zip){1}')
{
Expand-Archive -Path $_.FullName -DestinationPath $(ob_outputDirectory)
@@ -197,7 +206,11 @@ extends:
- pwsh: |
Write-Verbose "VPack Version: $(ob_createvpack_version)" -Verbose
- Get-ChildItem -Path $(ob_outputDirectory)\* -Recurse
+ $vpackFiles = Get-ChildItem -Path $(ob_outputDirectory)\* -Recurse
+ if($vpackFiles.Count -eq 0) {
+ throw "No files found in $(ob_outputDirectory)"
+ }
+ $vpackFiles
displayName: Debug Output Directory and Version
condition: succeededOrFailed()
@@ -207,5 +220,5 @@ extends:
command: 'sign'
signing_environment: 'azure-ado'
cp_code: $(windows_build_tools_cert_id)
- files_to_sign: '**/*.exe;**/*.dll;**/*.ps1;**/*.psm1'
+ files_to_sign: '**/*.exe;**/System.Management.Automation.dll'
search_root: $(ob_outputDirectory)
diff --git a/.pipelines/templates/checkAzureContainer.yml b/.pipelines/templates/checkAzureContainer.yml
index a5ce2b1c666..a6a86214d07 100644
--- a/.pipelines/templates/checkAzureContainer.yml
+++ b/.pipelines/templates/checkAzureContainer.yml
@@ -51,22 +51,13 @@ jobs:
}
displayName: 'Check suppress.json'
- # Needed as per FAQ here: https://eng.ms/docs/products/onebranch/build/troubleshootingfaqs
- - task: PowerShell@2
- displayName: 'Update Az.Storage Module'
- inputs:
- targetType: 'inline'
- script: |
- Get-PackageProvider -Name NuGet -ForceBootstrap
- Install-Module -Name Az.Storage -Verbose -Force -AllowClobber
- Uninstall-AzureRm -Verbose
-
- task: AzurePowerShell@5
displayName: Check if blob exists and delete if specified
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
- azurePowerShellVersion: latestVersion
+ azurePowerShellVersion: LatestVersion
+ pwsh: true
inline: |
$containersToDelete = @('$(AzureVersion)', '$(AzureVersion)-private', '$(AzureVersion)-nuget', '$(AzureVersion)-gc')
diff --git a/.pipelines/templates/compliance/apiscan.yml b/.pipelines/templates/compliance/apiscan.yml
index bfe97827801..4e945b40349 100644
--- a/.pipelines/templates/compliance/apiscan.yml
+++ b/.pipelines/templates/compliance/apiscan.yml
@@ -78,19 +78,6 @@ jobs:
workingDirectory: '$(repoRoot)'
retryCountOnTaskFailure: 2
- - pwsh: |
- $modules = 'Az.Accounts', 'Az.Storage'
- foreach($module in $modules) {
- if(!(get-module $module -listavailable)) {
- Write-Verbose "installing $module..." -verbose
- Install-Module $module -force -AllowClobber
- } else {
- Write-Verbose "$module already installed." -verbose
- }
- }
- displayName: Install PowerShell modules
- workingDirectory: '$(repoRoot)'
-
- task: AzurePowerShell@5
displayName: Download winverify-private Artifacts
inputs:
diff --git a/.pipelines/templates/compliance/generateNotice.yml b/.pipelines/templates/compliance/generateNotice.yml
index 9a00ed6f01d..b9d489795b1 100644
--- a/.pipelines/templates/compliance/generateNotice.yml
+++ b/.pipelines/templates/compliance/generateNotice.yml
@@ -95,29 +95,6 @@ jobs:
Get-PackageProvider -Name NuGet -ForceBootstrap
displayName: Initalize PowerShellGet
- - powershell: |
- $modules = 'Az.Accounts', 'Az.Storage'
- foreach($module in $modules) {
- if(!(get-module $module -listavailable)) {
- Write-Verbose "installing $module..." -verbose
- Install-Module $module -force -AllowClobber
- } else {
- Write-Verbose "$module already installed." -verbose
- #Update-Module $module -verbose
- }
- }
- displayName: Install PowerShell modules
-
- - powershell: |
- if(Get-Command -Name Uninstall-AzureRm -ErrorAction Ignore){
- Write-Verbose "running Uninstall-AzureRm" -verbose
- Uninstall-AzureRm
- } else {
- Write-Verbose "Uninstall-AzureRm not present" -verbose
- }
- displayName: Uninstall Uninstall-AzureRm
- continueOnError: true
-
- task: AzurePowerShell@5
displayName: Upload Notice
inputs:
diff --git a/.pipelines/templates/nupkg.yml b/.pipelines/templates/nupkg.yml
index c1f7616110c..dc43e841332 100644
--- a/.pipelines/templates/nupkg.yml
+++ b/.pipelines/templates/nupkg.yml
@@ -128,13 +128,13 @@ jobs:
Start-PSBuild -Clean -Runtime linux-x64 -Configuration Release -ReleaseTag $(ReleaseTagVar)
$sharedModules | Foreach-Object {
- $refFile = Get-ChildItem -Path "$(PowerShellRoot)\src\$_\obj\Release\net9.0\refint\$_.dll"
+ $refFile = Get-ChildItem -Path "$(PowerShellRoot)\src\$_\obj\Release\net10.0\refint\$_.dll"
Write-Verbose -Verbose "RefAssembly: $refFile"
Copy-Item -Path $refFile -Destination "$refAssemblyFolder\$_.dll" -Verbose
- $refDoc = "$(PowerShellRoot)\src\$_\bin\Release\net9.0\$_.xml"
+ $refDoc = "$(PowerShellRoot)\src\$_\bin\Release\net10.0\$_.xml"
if (-not (Test-Path $refDoc)) {
Write-Warning "$refDoc not found"
- Get-ChildItem -Path "$(PowerShellRoot)\src\$_\bin\Release\net9.0\" | Out-String | Write-Verbose -Verbose
+ Get-ChildItem -Path "$(PowerShellRoot)\src\$_\bin\Release\net10.0\" | Out-String | Write-Verbose -Verbose
}
else {
Copy-Item -Path $refDoc -Destination "$refAssemblyFolder\$_.xml" -Verbose
@@ -144,13 +144,13 @@ jobs:
Start-PSBuild -Clean -Runtime win7-x64 -Configuration Release -ReleaseTag $(ReleaseTagVar)
$winOnlyModules | Foreach-Object {
- $refFile = Get-ChildItem -Path "$(PowerShellRoot)\src\$_\obj\Release\net9.0\refint\*.dll"
+ $refFile = Get-ChildItem -Path "$(PowerShellRoot)\src\$_\obj\Release\net10.0\refint\*.dll"
Write-Verbose -Verbose 'RefAssembly: $refFile'
Copy-Item -Path $refFile -Destination "$refAssemblyFolder\$_.dll" -Verbose
- $refDoc = "$(PowerShellRoot)\src\$_\bin\Release\net9.0\$_.xml"
+ $refDoc = "$(PowerShellRoot)\src\$_\bin\Release\net10.0\$_.xml"
if (-not (Test-Path $refDoc)) {
Write-Warning "$refDoc not found"
- Get-ChildItem -Path "$(PowerShellRoot)\src\$_\bin\Release\net9.0" | Out-String | Write-Verbose -Verbose
+ Get-ChildItem -Path "$(PowerShellRoot)\src\$_\bin\Release\net10.0" | Out-String | Write-Verbose -Verbose
}
else {
Copy-Item -Path $refDoc -Destination "$refAssemblyFolder\$_.xml" -Verbose
diff --git a/.pipelines/templates/release-MakeBlobPublic.yml b/.pipelines/templates/release-MakeBlobPublic.yml
index f11a0839e47..c8f12938d25 100644
--- a/.pipelines/templates/release-MakeBlobPublic.yml
+++ b/.pipelines/templates/release-MakeBlobPublic.yml
@@ -52,17 +52,6 @@ jobs:
Get-ChildItem Env:
displayName: 'Capture Environment Variables'
- - pwsh: |
- $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
- if ($azureRmModule) {
- Write-Host 'AzureRM module exists. Removing it'
- Uninstall-AzureRm
- Write-Host 'AzureRM module removed'
- }
-
- Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
- displayName: Remove AzRM modules
-
- task: AzurePowerShell@5
displayName: Copy blobs to PSInfra storage
inputs:
@@ -150,17 +139,6 @@ jobs:
Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
displayName: 'Capture Environment Variables'
- - pwsh: |
- $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
- if ($azureRmModule) {
- Write-Host 'AzureRM module exists. Removing it'
- Uninstall-AzureRm
- Write-Host 'AzureRM module removed'
- }
-
- Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
- displayName: Remove AzRM modules
-
- task: AzurePowerShell@5
displayName: Copy blobs to PSInfra storage
inputs:
diff --git a/.pipelines/templates/release-create-msix.yml b/.pipelines/templates/release-create-msix.yml
index cdb86544baf..3714e623b5e 100644
--- a/.pipelines/templates/release-create-msix.yml
+++ b/.pipelines/templates/release-create-msix.yml
@@ -27,18 +27,6 @@ jobs:
artifact: drop_windows_package_package_win_x86
displayName: Download x86 msix
patterns: '**/*.msix'
-
- - pwsh: |
- $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
- if ($azureRmModule) {
- Write-Host 'AzureRM module exists. Removing it'
- Uninstall-AzureRm
- Write-Host 'AzureRM module removed'
- }
-
- Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
- displayName: Remove AzRM modules and install Az.Storage
-
# Finds the makeappx tool on the machine with image: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest'
- pwsh: |
diff --git a/.pipelines/templates/release-upload-buildinfo.yml b/.pipelines/templates/release-upload-buildinfo.yml
index 27af6c87b64..8d59078b905 100644
--- a/.pipelines/templates/release-upload-buildinfo.yml
+++ b/.pipelines/templates/release-upload-buildinfo.yml
@@ -104,17 +104,6 @@ jobs:
}
displayName: Create json files
- - pwsh: |
- $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
- if ($azureRmModule) {
- Write-Host 'AzureRM module exists. Removing it'
- Uninstall-AzureRm
- Write-Host 'AzureRM module removed'
- }
-
- Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
- displayName: Remove AzRM modules
-
- task: AzurePowerShell@5
displayName: Upload buildjson to blob
inputs:
diff --git a/.pipelines/templates/release-validate-packagenames.yml b/.pipelines/templates/release-validate-packagenames.yml
index df467eacc28..983d6690036 100644
--- a/.pipelines/templates/release-validate-packagenames.yml
+++ b/.pipelines/templates/release-validate-packagenames.yml
@@ -28,18 +28,6 @@ jobs:
Write-Host "##vso[build.updatebuildnumber]$name"
displayName: Set Release Name
- - pwsh: |
- $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
- if ($azureRmModule) {
- Write-Host 'AzureRM module exists. Removing it'
- Uninstall-AzureRm
- Write-Host 'AzureRM module removed'
- }
-
- Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
-
- displayName: Remove AzRM modules and install Az.Storage
-
- task: AzurePowerShell@5
displayName: Upload packages to blob
inputs:
diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml
index cd6f7d6739c..3bcceeb1af7 100644
--- a/.pipelines/templates/uploadToAzure.yml
+++ b/.pipelines/templates/uploadToAzure.yml
@@ -256,18 +256,6 @@ jobs:
New-Item -Path $(Build.ArtifactStagingDirectory)/uploaded -ItemType Directory -Force
displayName: Create output directory for packages
- - pwsh: |
- $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
- if ($azureRmModule) {
- Write-Host 'AzureRM module exists. Removing it'
- Uninstall-AzureRm
- Write-Host 'AzureRM module removed'
- }
-
- Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
-
- displayName: Remove AzRM modules
-
- task: AzurePowerShell@5
displayName: Upload packages to blob
inputs:
diff --git a/.pipelines/templates/windows-hosted-build.yml b/.pipelines/templates/windows-hosted-build.yml
index f5cebac1316..929aa54b8a7 100644
--- a/.pipelines/templates/windows-hosted-build.yml
+++ b/.pipelines/templates/windows-hosted-build.yml
@@ -275,7 +275,7 @@ jobs:
)
$sourceModulePath = Join-Path '$(GlobalToolArtifactPath)' 'publish' 'PowerShell.Windows.x64' 'release' 'Modules'
- $destModulesPath = Join-Path "$outputPath" 'temp' 'tools' 'net9.0' 'any' 'modules'
+ $destModulesPath = Join-Path "$outputPath" 'temp' 'tools' 'net10.0' 'any' 'modules'
$modulesToCopy | ForEach-Object {
$modulePath = Join-Path $sourceModulePath $_
@@ -283,7 +283,7 @@ jobs:
}
# Copy ref assemblies
- Copy-Item '$(Pipeline.Workspace)/Symbols_$(Architecture)/ref' "$outputPath\temp\tools\net9.0\any\ref" -Recurse -Force
+ Copy-Item '$(Pipeline.Workspace)/Symbols_$(Architecture)/ref' "$outputPath\temp\tools\net10.0\any\ref" -Recurse -Force
$contentPath = Join-Path "$outputPath\temp" 'content'
$contentFilesPath = Join-Path "$outputPath\temp" 'contentFiles'
@@ -291,14 +291,14 @@ jobs:
Remove-Item -Path $contentPath,$contentFilesPath -Recurse -Force
# remove PDBs to reduce the size of the nupkg
- Remove-Item -Path "$outputPath\temp\tools\net9.0\any\*.pdb" -Recurse -Force
+ Remove-Item -Path "$outputPath\temp\tools\net10.0\any\*.pdb" -Recurse -Force
# create powershell.config.json
$config = [ordered]@{}
$config.Add("Microsoft.PowerShell:ExecutionPolicy", "RemoteSigned")
$config.Add("WindowsPowerShellCompatibilityModuleDenyList", @("PSScheduledJob", "BestPractices", "UpdateServices"))
- $configPublishPath = Join-Path "$outputPath" 'temp' 'tools' 'net9.0' 'any' "powershell.config.json"
+ $configPublishPath = Join-Path "$outputPath" 'temp' 'tools' 'net10.0' 'any' "powershell.config.json"
Set-Content -Path $configPublishPath -Value ($config | ConvertTo-Json) -Force -ErrorAction Stop
Compress-Archive -Path "$outputPath\temp\*" -DestinationPath "$outputPath\$nupkgName" -Force
diff --git a/.vsts-ci/linux-internal.yml b/.vsts-ci/linux-internal.yml
new file mode 100644
index 00000000000..6286a03fb52
--- /dev/null
+++ b/.vsts-ci/linux-internal.yml
@@ -0,0 +1,116 @@
+# Pipeline to run Linux CI internally
+name: PR-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)$(Rev:.rr)
+trigger:
+ # Batch merge builds together while a merge build is running
+ batch: true
+ branches:
+ include:
+ - master
+ - release*
+ - feature*
+ paths:
+ include:
+ - '*'
+ exclude:
+ - .vsts-ci/misc-analysis.yml
+ - .github/ISSUE_TEMPLATE/*
+ - .github/workflows/*
+ - .dependabot/config.yml
+ - .pipelines/*
+ - test/perf/*
+pr:
+ branches:
+ include:
+ - master
+ - release*
+ - feature*
+ paths:
+ include:
+ - '*'
+ exclude:
+ - .dependabot/config.yml
+ - .github/ISSUE_TEMPLATE/*
+ - .github/workflows/*
+ - .vsts-ci/misc-analysis.yml
+ - .vsts-ci/windows.yml
+ - .vsts-ci/windows/*
+ - tools/cgmanifest.json
+ - LICENSE.txt
+ - test/common/markdown/*
+ - test/perf/*
+ - tools/releaseBuild/*
+ - tools/install*
+ - tools/releaseBuild/azureDevOps/templates/*
+ - README.md
+ - .spelling
+ - .pipelines/*
+
+variables:
+ DOTNET_CLI_TELEMETRY_OPTOUT: 1
+ POWERSHELL_TELEMETRY_OPTOUT: 1
+ # Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds
+ DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
+ __SuppressAnsiEscapeSequences: 1
+ nugetMultiFeedWarnLevel: none
+
+resources:
+ repositories:
+ - repository: Docker
+ type: github
+ endpoint: PowerShell
+ name: PowerShell/PowerShell-Docker
+ ref: master
+
+stages:
+- stage: BuildLinuxStage
+ displayName: Build for Linux
+ jobs:
+ - template: templates/ci-build.yml
+ parameters:
+ pool: ubuntu-20.04
+ jobName: linux_build
+ displayName: linux Build
+
+- stage: TestUbuntu
+ displayName: Test for Ubuntu
+ dependsOn: [BuildLinuxStage]
+ jobs:
+ - template: templates/nix-test.yml
+ parameters:
+ name: Ubuntu
+ pool: ubuntu-20.04
+ purpose: UnelevatedPesterTests
+ tagSet: CI
+
+ - template: templates/nix-test.yml
+ parameters:
+ name: Ubuntu
+ pool: ubuntu-20.04
+ purpose: ElevatedPesterTests
+ tagSet: CI
+
+ - template: templates/nix-test.yml
+ parameters:
+ name: Ubuntu
+ pool: ubuntu-20.04
+ purpose: UnelevatedPesterTests
+ tagSet: Others
+
+ - template: templates/nix-test.yml
+ parameters:
+ name: Ubuntu
+ pool: ubuntu-20.04
+ purpose: ElevatedPesterTests
+ tagSet: Others
+
+ - template: templates/verify-xunit.yml
+ parameters:
+ pool: ubuntu-20.04
+
+- stage: PackageLinux
+ displayName: Package Linux
+ dependsOn: ["BuildLinuxStage"]
+ jobs:
+ - template: linux/templates/packaging.yml
+ parameters:
+ pool: ubuntu-20.04
diff --git a/.vsts-ci/linux.yml b/.vsts-ci/linux.yml
index b1bb74197a0..338821e37dd 100644
--- a/.vsts-ci/linux.yml
+++ b/.vsts-ci/linux.yml
@@ -34,24 +34,16 @@ pr:
- feature*
paths:
include:
- - '*'
- exclude:
- - .dependabot/config.yml
- - .github/ISSUE_TEMPLATE/*
- - .github/workflows/*
- - .vsts-ci/misc-analysis.yml
- - .vsts-ci/windows.yml
- - .vsts-ci/windows/*
- - tools/cgmanifest.json
- - LICENSE.txt
- - test/common/markdown/*
- - test/perf/*
- - tools/releaseBuild/*
- - tools/install*
- - tools/releaseBuild/azureDevOps/templates/*
- - README.md
- - .spelling
- - .pipelines/*
+ - .vsts-ci/linux.yml
+ - .vsts-ci/linux/templates/packaging.yml
+ - assets/manpage/*
+ - build.psm1
+ - global.json
+ - nuget.config
+ - PowerShell.Common.props
+ - src/*.csproj
+ - tools/ci.psm1
+ - tools/packaging/*
variables:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
diff --git a/.vsts-ci/windows/templates/windows-packaging.yml b/.vsts-ci/windows/templates/windows-packaging.yml
index 02dbf1bf892..d23b745c30f 100644
--- a/.vsts-ci/windows/templates/windows-packaging.yml
+++ b/.vsts-ci/windows/templates/windows-packaging.yml
@@ -47,9 +47,6 @@ jobs:
displayName: Capture PowerShell Version Table
condition: succeededOrFailed()
-
- - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml
-
- pwsh: |
Import-Module .\tools\ci.psm1
Switch-PSNugetConfig -Source Public
diff --git a/CHANGELOG/7.4.md b/CHANGELOG/7.4.md
index a269b1abf98..1a7d64868d0 100644
--- a/CHANGELOG/7.4.md
+++ b/CHANGELOG/7.4.md
@@ -1,5 +1,81 @@
# 7.4 Changelog
+## [7.4.9]
+
+### Notes
+
+_This release is internal only. It is not available for download._
+
+### Tools
+
+- Check GH token availability for `Get-Changelog` (#25156)
+
+### Build and Packaging Improvements
+
+
+
+
+
+Update .NET SDK to 8.0.407
+
+
+
+
+Update branch for release (#25101)
+Only build Linux for packaging changes (#25161)
+Skip additional packages when generating component manifest (#25160)
+Remove Az module installs and AzureRM uninstalls in pipeline (#25157)
+Add GitHub Actions workflow to verify PR labels (#25158)
+Update security extensions (#25099)
+Make Component Manifest Updater use neutral target in addition to RID target (#25100)
+
+
+
+
+[7.4.9]: https://github.com/PowerShell/PowerShell/compare/v7.4.8...v7.4.9
+
+## [7.4.8]
+
+### Notes
+
+_This release is internal only. It is not available for download._
+
+### Build and Packaging Improvements
+
+
+
+
+
+Update .NET SDK to 8.0.406
+
+
+
+
+Update branch for release (#25085) (#24884)
+Add UseDotnet task for installing dotnet (#25080)
+Add Justin Chung as PowerShell team member in releaseTools.psm1
(#25074)
+Fix V-Pack download package name (#25078)
+Fix MSIX stage in release pipeline (#25079)
+Give the pipeline runs meaningful names (#25081)
+Make sure the vPack pipeline does not produce an empty package (#25082)
+Update CODEOWNERS (#25083)
+Add setup dotnet action to the build composite action (#25084)
+Remove AzDO credscan as it is now in GitHub (#25077)
+Use workload identity service connection to download makeappx tool from storage account (#25075)
+Update .NET SDK (#24993)
+Fix GitHub Action filter overmatching (#24957)
+Fix release branch filters (#24960)
+Convert powershell/PowerShell-CI-macos to GitHub Actions (#24955)
+Convert powershell/PowerShell-CI-linux to GitHub Actions (#24945)
+Convert powershell/PowerShell-Windows-CI to GitHub Actions (#24932)
+PMC parse state correctly from update command's response (#24860)
+Add EV2 support for publishing PowerShell packages to PMC (#24857)
+
+
+
+
+[7.4.8]: https://github.com/PowerShell/PowerShell/compare/v7.4.7...v7.4.8
+
## [7.4.7]
### Build and Packaging Improvements
@@ -13,8 +89,8 @@
-[release/v7.4] Update branch for release - Transitive - true - minor (#24546)
-[release/v7.4] Fix backport mistake in #24429 (#24545)
+Update branch for release - Transitive - true - minor (#24546)
+Fix backport mistake in #24429 (#24545)
Fix seed max value for Container Linux CI (#24510) (#24543)
Add a way to use only NuGet feed sources (#24528) (#24542)
Bump Microsoft.PowerShell.PSResourceGet to 1.0.6 (#24419)
@@ -28,13 +104,13 @@
Update changelog for v7.4.6 release (Internal 32983)
Fix backport issues with release pipeline (#24835)
Remove duplicated parameter (#24832)
-[release/v7.4] Make the AssemblyVersion
not change for servicing releases 7.4.7 and onward (#24821)
+Make the AssemblyVersion
not change for servicing releases 7.4.7 and onward (#24821)
Add *.props and sort path filters for windows CI (#24822) (#24823)
Take the newest windows signature nuget packages (#24818)
Use work load identity service connection to download makeappx tool from storage account (#24817) (#24820)
Update path filters for Windows CI (#24809) (#24819)
Fixed release pipeline errors and switched to KS3 (#24751) (#24816)
-[release/v7.4] Update branch for release - Transitive - true - minor (#24806)
+Update branch for release - Transitive - true - minor (#24806)
Add ability to capture MSBuild Binary logs when restore fails (#24128) (#24799)
Download package from package build for generating vpack (#24481) (#24801)
Add a parameter that skips verify packages step (#24763) (#24803)
diff --git a/CHANGELOG/preview.md b/CHANGELOG/preview.md
index ecc87bf031c..2663b2e5f0c 100644
--- a/CHANGELOG/preview.md
+++ b/CHANGELOG/preview.md
@@ -1,5 +1,131 @@
# Preview Changelog
+## [7.6.0-preview.4]
+
+### Breaking Changes
+
+- Fix `WildcardPattern.Escape` to escape lone backticks correctly (#25211) (Thanks @ArmaanMcleod!)
+- Convert `-ChildPath` parameter to `string[]` for `Join-Path` cmdlet (#24677) (Thanks @ArmaanMcleod!)
+
+PowerShell 7.6-preview.4 includes the following updated modules:
+
+- **Microsoft.PowerShell.ThreadJob** v2.2.0
+- **ThreadJob** v2.1.0
+The **ThreadJob** module was renamed to **Microsoft.PowerShell.ThreadJob**. There is no difference
+in the functionality of the module. To ensure backward compatibility for scripts that use the old
+name, the **ThreadJob** v2.1.0 module is a proxy module that points to the
+**Microsoft.PowerShell.ThreadJob** v2.2.0.
+
+### Engine Updates and Fixes
+
+- Add `PipelineStopToken` to `Cmdlet` which will be signaled when the pipeline is stopping (#24620) (Thanks @jborean93!)
+- Fallback to AppLocker after `WldpCanExecuteFile` (#24912)
+- Move .NET method invocation logging to after the needed type conversion is done for method arguments (#25022)
+- Fix share completion with provider and spaces (#19440) (Thanks @MartinGC94!)
+
+### General Cmdlet Updates and Fixes
+
+- Exclude `-OutVariable` assignments within the same `CommandAst` when inferring variables (#25224) (Thanks @MartinGC94!)
+- Fix infinite loop in variable type inference (#25206) (Thanks @MartinGC94!)
+- Update `Microsoft.PowerShell.PSResourceGet` version in `PSGalleryModules.csproj` (#25135)
+- Add tooltips for hashtable key completions (#17864) (Thanks @MartinGC94!)
+- Fix type inference of parameters in classic functions (#25172) (Thanks @MartinGC94!)
+- Improve assignment type inference (#21143) (Thanks @MartinGC94!)
+- Fix `TypeName.GetReflectionType()` to work when the `TypeName` instance represents a generic type definition within a `GenericTypeName` (#24985)
+- Remove the old fuzzy suggestion and fix the local script filename suggestion (#25177)
+- Improve variable type inference (#19830) (Thanks @MartinGC94!)
+- Fix parameter completion when script requirements fail (#17687) (Thanks @MartinGC94!)
+- Improve the completion for attribute arguments (#25129) (Thanks @MartinGC94!)
+- Fix completion that relies on pseudobinding in script blocks (#25122) (Thanks @MartinGC94!)
+- Don't complete duplicate command names (#21113) (Thanks @MartinGC94!)
+- Make `SystemPolicy` public APIs visible but non-op on Unix platforms so that they can be included in `PowerShellStandard.Library` (#25051)
+- Set standard handles explicitly when starting a process with `-NoNewWindow` (#25061)
+- Fix tooltip for variable expansion and include desc (#25112) (Thanks @jborean93!)
+- Add type inference for functions without OutputType attribute and anonymous functions (#21127) (Thanks @MartinGC94!)
+- Add completion for variables assigned by command redirection (#25104) (Thanks @MartinGC94!)
+- Handle type inference for redirected commands (#21131) (Thanks @MartinGC94!)
+- Allow empty prefix string in `Import-Module -Prefix` to override default prefix in manifest (#20409) (Thanks @MartinGC94!)
+- Update variable/property assignment completion so it can fallback to type inference (#21134) (Thanks @MartinGC94!)
+- Use `Get-Help` approach to find `about_*.help.txt` files with correct locale for completions (#24194) (Thanks @MartinGC94!)
+- Use script filepath when completing relative paths for using statements (#20017) (Thanks @MartinGC94!)
+- Fix completion of variables assigned inside Do loops (#25076) (Thanks @MartinGC94!)
+- Fix completion of provider paths when a path returns itself instead of its children (#24755) (Thanks @MartinGC94!)
+- Enable completion of scoped variables without specifying scope (#20340) (Thanks @MartinGC94!)
+- Fix issue with incomplete results when completing paths with wildcards in non-filesystem providers (#24757) (Thanks @MartinGC94!)
+- Allow DSC parsing through OS architecture translation layers (#24852) (Thanks @bdeb1337!)
+
+### Code Cleanup
+
+
+
+
+
+We thank the following contributors!
+@ArmaanMcleod, @pressRtowin
+
+
+
+
+Refactor and add comments to CompletionRequiresQuotes
to clarify implementation (#25223) (Thanks @ArmaanMcleod!)
+Add QuoteCompletionText
method to CompletionHelpers class (#25180) (Thanks @ArmaanMcleod!)
+Remove CompletionHelpers escape
parameter from CompletionRequiresQuotes
(#25178) (Thanks @ArmaanMcleod!)
+Refactor CompletionHelpers HandleDoubleAndSingleQuote
to have less nesting logic (#25179) (Thanks @ArmaanMcleod!)
+Make the use of Oxford commas consistent (#25139)(#25140)(Thanks @pressRtowin!)
+Move common completion methods to CompletionHelpers class (#25138) (Thanks @ArmaanMcleod!)
+Return Array.Empty
instead of collection []
(#25137) (Thanks @ArmaanMcleod!)
+
+
+
+
+### Tools
+
+- Check GH token availability for Get-Changelog (#25133)
+
+### Tests
+
+- Add XUnit test for `HandleDoubleAndSingleQuote` in CompletionHelpers class (#25181) (Thanks @ArmaanMcleod!)
+
+### Build and Packaging Improvements
+
+
+
+
+Switch to ubuntu-lastest for CI (#25247)
+Update outdated package references (#25026)(#25232)
+Bump Microsoft.PowerShell.ThreadJob
and ThreadJob
modules (#25232)
+Bump github/codeql-action from 3.27.9 to 3.28.13 (#25218)(#25231)
+Update .NET SDK to 10.0.100-preview.2
(#25154)(#25225)
+Remove obsolete template from Windows Packaging CI (#25226)
+Bump actions/upload-artifact from 4.5.0 to 4.6.2 (#25220)
+Bump agrc/reminder-action from 1.0.15 to 1.0.16 (#25222)
+Bump actions/checkout from 2 to 4 (#25221)
+Add NoWarn NU1605
to System.ServiceModel.* (#25219)
+Bump actions/github-script from 6 to 7 (#25217)
+Bump ossf/scorecard-action from 2.4.0 to 2.4.1 (#25216)
+Bump super-linter/super-linter from 7.2.1 to 7.3.0 (#25215)
+Bump agrc/create-reminder-action from 1.1.16 to 1.1.17 (#25214)
+Remove dependabot updates that don't work (#25213)
+Update GitHub Actions to work in private GitHub repo (#25197)
+Cleanup old release pipelines (#25201)
+Update package pipeline windows image version (#25191)
+Skip additional packages when generating component manifest (#25102)
+Only build Linux for packaging changes (#25103)
+Remove Az module installs and AzureRM uninstalls in pipeline (#25118)
+Add GitHub Actions workflow to verify PR labels (#25145)
+Add back-port workflow using dotnet/arcade (#25106)
+Make Component Manifest Updater use neutral target in addition to RID target (#25094)
+Make sure the vPack pipeline does not produce an empty package (#24988)
+
+
+
+
+### Documentation and Help Content
+
+- Add 7.4.9 changelog (#25169)
+- Create changelog for 7.4.8 (#25089)
+
+[7.6.0-preview.4]: https://github.com/PowerShell/PowerShell/compare/v7.6.0-preview.3...v7.6.0-preview.4
+
## [7.6.0-preview.3]
### Breaking Changes
diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json
index a019407c86a..9ca72b0577c 100644
--- a/DotnetRuntimeMetadata.json
+++ b/DotnetRuntimeMetadata.json
@@ -4,7 +4,7 @@
"quality": "daily",
"qualityFallback": "preview",
"packageVersionPattern": "9.0.0-preview.6",
- "sdkImageVersion": "9.0.200",
+ "sdkImageVersion": "10.0.100-preview.2.25164.34",
"nextChannel": "9.0.0-preview.7",
"azureFeed": "",
"sdkImageOverride": ""
diff --git a/PowerShell.Common.props b/PowerShell.Common.props
index 36e100811a6..5dce6eac9a5 100644
--- a/PowerShell.Common.props
+++ b/PowerShell.Common.props
@@ -144,7 +144,7 @@
(c) Microsoft Corporation.
PowerShell 7
- net9.0
+ net10.0
13.0
true
diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt
index f45bc2f3c2b..28a06a82744 100644
--- a/ThirdPartyNotices.txt
+++ b/ThirdPartyNotices.txt
@@ -119,7 +119,7 @@ SOFTWARE.
---------------------------------------------------------
-JsonSchema.Net 7.3.3 - MIT
+JsonSchema.Net 7.3.4 - MIT
Copyright (c) .NET Foundation and Contributors
@@ -151,7 +151,7 @@ SOFTWARE.
---------------------------------------------------------
-Microsoft.ApplicationInsights 2.22.0 - MIT
+Microsoft.ApplicationInsights 2.23.0 - MIT
(c) Microsoft Corporation
@@ -170,7 +170,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.Bcl.AsyncInterfaces 9.0.2 - MIT
+Microsoft.Bcl.AsyncInterfaces 9.0.3 - MIT
Copyright (c) 2021
@@ -260,7 +260,7 @@ SOFTWARE.
---------------------------------------------------------
-Microsoft.CodeAnalysis.Common 4.12.0 - MIT
+Microsoft.CodeAnalysis.Common 4.13.0 - MIT
(c) Microsoft Corporation
@@ -280,7 +280,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.CodeAnalysis.CSharp 4.12.0 - MIT
+Microsoft.CodeAnalysis.CSharp 4.13.0 - MIT
(c) Microsoft Corporation
@@ -305,7 +305,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.Extensions.ObjectPool 9.0.2 - MIT
+Microsoft.Extensions.ObjectPool 9.0.3 - MIT
Copyright Jorn Zaefferer
@@ -375,7 +375,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.Security.Extensions 1.3.0 - MIT
+Microsoft.Security.Extensions 1.4.0 - MIT
(c) Microsoft Corporation
@@ -395,79 +395,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.Win32.Registry 5.0.0 - MIT
-
-
-(c) Microsoft Corporation
-Copyright (c) Andrew Arnott
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 1998 Microsoft. To
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 2012-2014, Yann Collet
-Copyright (c) 1991-2020 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright 2012 the V8 project authors
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Portions (c) International Organization
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-Microsoft.Win32.Registry.AccessControl 9.0.2 - MIT
+Microsoft.Win32.Registry.AccessControl 9.0.3 - MIT
Copyright (c) 2021
@@ -557,7 +485,7 @@ SOFTWARE.
---------------------------------------------------------
-Microsoft.Win32.SystemEvents 9.0.2 - MIT
+Microsoft.Win32.SystemEvents 9.0.3 - MIT
Copyright (c) 2021
@@ -647,7 +575,7 @@ SOFTWARE.
---------------------------------------------------------
-Microsoft.Windows.Compatibility 9.0.2 - MIT
+Microsoft.Windows.Compatibility 9.0.3 - MIT
(c) Microsoft Corporation
@@ -700,7 +628,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
-runtime.android-arm.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.android-arm.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -790,7 +718,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.android-arm64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.android-arm64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -880,7 +808,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.android-x64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.android-x64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -970,7 +898,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.android-x86.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.android-x86.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1060,7 +988,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-arm.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-arm.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1150,7 +1078,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1240,7 +1168,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1330,7 +1258,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1420,7 +1348,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1510,7 +1438,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1600,7 +1528,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1690,7 +1618,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.linux-x64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.linux-x64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1780,7 +1708,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -1870,7 +1798,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -2005,7 +1933,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -2095,7 +2023,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -2185,7 +2113,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.osx-x64.runtime.native.System.IO.Ports 9.0.2 - MIT
+runtime.osx-x64.runtime.native.System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -2275,7 +2203,7 @@ SOFTWARE.
---------------------------------------------------------
-System.CodeDom 9.0.2 - MIT
+System.CodeDom 9.0.3 - MIT
Copyright (c) 2021
@@ -2365,19 +2293,22 @@ SOFTWARE.
---------------------------------------------------------
-System.Collections.Immutable 8.0.0 - MIT
+System.ComponentModel.Composition 9.0.3 - MIT
+Copyright (c) 2021
Copyright (c) Six Labors
(c) Microsoft Corporation
+Copyright (c) 2022 FormatJS
Copyright (c) Andrew Arnott
Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
Copyright 2018 Daniel Lemire
Copyright (c) .NET Foundation
Copyright (c) 2011, Google Inc.
Copyright (c) 2020 Dan Shechter
(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 1998 Microsoft. To
+Copyright (c) 2015 Andrew Gallant
Copyright (c) 2022, Wojciech Mula
Copyright (c) 2017 Yoshifumi Kawai
Copyright (c) 2022, Geoff Langdale
@@ -2387,23 +2318,24 @@ Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
Copyright (c) 1991-2022 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
Copyright (c) 1999 Lucent Technologies
Copyright (c) 2008-2016, Wojciech Mula
Copyright (c) 2011-2020 Microsoft Corp
Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2021 csFastFloat authors
+Copyright (c) 2015-2018, Wojciech Mula
Copyright (c) 2005-2007, Nick Galbreath
Copyright (c) 2015 The Chromium Authors
Copyright (c) 2018 Alexander Chermyanin
Copyright (c) The Internet Society 1997
-Portions (c) International Organization
Copyright (c) 2004-2006 Intel Corporation
Copyright (c) 2011-2015 Intel Corporation
Copyright (c) 2013-2017, Milosz Krajewski
Copyright (c) 2016-2017, Matthieu Darbois
Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
+(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
@@ -2411,12 +2343,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
Copyright (c) 2019 Microsoft Corporation, Daan Leijen
Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
@@ -2451,7 +2383,7 @@ SOFTWARE.
---------------------------------------------------------
-System.ComponentModel.Composition 9.0.2 - MIT
+System.ComponentModel.Composition.Registration 9.0.3 - MIT
Copyright (c) 2021
@@ -2541,7 +2473,7 @@ SOFTWARE.
---------------------------------------------------------
-System.ComponentModel.Composition.Registration 9.0.2 - MIT
+System.Configuration.ConfigurationManager 9.0.3 - MIT
Copyright (c) 2021
@@ -2631,7 +2563,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Configuration.ConfigurationManager 9.0.2 - MIT
+System.Data.Odbc 9.0.3 - MIT
Copyright (c) 2021
@@ -2721,7 +2653,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Data.Odbc 9.0.2 - MIT
+System.Data.OleDb 9.0.3 - MIT
Copyright (c) 2021
@@ -2811,7 +2743,26 @@ SOFTWARE.
---------------------------------------------------------
-System.Data.OleDb 9.0.2 - MIT
+System.Data.SqlClient 4.9.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Diagnostics.EventLog 9.0.3 - MIT
Copyright (c) 2021
@@ -2901,26 +2852,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Data.SqlClient 4.9.0 - MIT
-
-
-(c) Microsoft Corporation
-
-MIT License
-
-Copyright (c)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Diagnostics.DiagnosticSource 9.0.2 - MIT
+System.Diagnostics.PerformanceCounter 9.0.3 - MIT
Copyright (c) 2021
@@ -3010,7 +2942,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Diagnostics.EventLog 9.0.2 - MIT
+System.DirectoryServices 9.0.3 - MIT
Copyright (c) 2021
@@ -3100,7 +3032,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Diagnostics.PerformanceCounter 9.0.2 - MIT
+System.DirectoryServices.AccountManagement 9.0.3 - MIT
Copyright (c) 2021
@@ -3190,7 +3122,7 @@ SOFTWARE.
---------------------------------------------------------
-System.DirectoryServices 9.0.2 - MIT
+System.DirectoryServices.Protocols 9.0.3 - MIT
Copyright (c) 2021
@@ -3280,7 +3212,42 @@ SOFTWARE.
---------------------------------------------------------
-System.DirectoryServices.AccountManagement 9.0.2 - MIT
+System.Drawing.Common 9.0.3 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) Sven Groot (Ookii.org) 2009
+Copyright (c) .NET Foundation and Contributors
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.IO.Packaging 9.0.3 - MIT
Copyright (c) 2021
@@ -3370,7 +3337,7 @@ SOFTWARE.
---------------------------------------------------------
-System.DirectoryServices.Protocols 9.0.2 - MIT
+System.IO.Ports 9.0.3 - MIT
Copyright (c) 2021
@@ -3460,12 +3427,66 @@ SOFTWARE.
---------------------------------------------------------
-System.Drawing.Common 9.0.2 - MIT
+System.Management 9.0.3 - MIT
+Copyright (c) 2021
+Copyright (c) Six Labors
(c) Microsoft Corporation
-Copyright (c) Sven Groot (Ookii.org) 2009
+Copyright (c) 2022 FormatJS
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 2015 Andrew Gallant
+Copyright (c) 2022, Wojciech Mula
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2018 Nemanja Mijailovic
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2015-2018, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright (c) .NET Foundation Contributors
+(c) 1995-2024 Jean-loup Gailly and Mark Adler
+Copyright (c) 2020 Mara Bos
Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
The MIT License (MIT)
@@ -3491,11 +3512,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
---------------------------------------------------------
---------------------------------------------------------
-System.IO.Packaging 9.0.2 - MIT
+System.Net.Http.WinHttpHandler 9.0.3 - MIT
Copyright (c) 2021
@@ -3585,7 +3607,43 @@ SOFTWARE.
---------------------------------------------------------
-System.IO.Ports 9.0.2 - MIT
+System.Private.ServiceModel 4.10.3 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Reflection.Context 9.0.3 - MIT
Copyright (c) 2021
@@ -3675,7 +3733,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Management 9.0.2 - MIT
+System.Runtime.Caching 9.0.3 - MIT
Copyright (c) 2021
@@ -3765,7 +3823,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Net.Http.WinHttpHandler 9.0.2 - MIT
+System.Security.Cryptography.Pkcs 9.0.3 - MIT
Copyright (c) 2021
@@ -3855,590 +3913,20 @@ SOFTWARE.
---------------------------------------------------------
-System.Numerics.Vectors 4.5.0 - MIT
+System.Security.Cryptography.ProtectedData 9.0.3 - MIT
-(c) 2023 GitHub, Inc.
+Copyright (c) 2021
+Copyright (c) Six Labors
(c) Microsoft Corporation
+Copyright (c) 2022 FormatJS
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
Copyright (c) .NET Foundation
Copyright (c) 2011, Google Inc.
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 1991-2017 Unicode, Inc.
-Copyright (c) 2015 The Chromium Authors
-Portions (c) International Organization
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) .NET Foundation Contributors
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Private.ServiceModel 4.10.3 - MIT
-
-
-(c) Microsoft Corporation
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Reflection.Context 9.0.2 - MIT
-
-
-Copyright (c) 2021
-Copyright (c) Six Labors
-(c) Microsoft Corporation
-Copyright (c) 2022 FormatJS
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright (c) 1998 Microsoft
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 2015 Andrew Gallant
-Copyright (c) 2022, Wojciech Mula
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2022, Geoff Langdale
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) 2012-2021 Yann Collet
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2018 Nemanja Mijailovic
-Copyright 2012 the V8 project authors
-Copyright (c) 1999 Lucent Technologies
-Copyright (c) 2008-2016, Wojciech Mula
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2015-2018, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2011-2015 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-(c) 1995-2024 Jean-loup Gailly and Mark Adler
-Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2012 - present, Victor Zverovich
-Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
-Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Portions (c) International Organization for Standardization 1986
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright (c) 1980, 1986, 1993 The Regents of the University of California
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Reflection.DispatchProxy 4.7.1 - MIT
-
-
-(c) Microsoft Corporation.
-Copyright (c) .NET Foundation.
-Copyright (c) 2011, Google Inc.
-(c) 1997-2005 Sean Eron Anderson.
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2017 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Portions (c) International Organization
-Copyright (c) 2015 The Chromium Authors.
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) .NET Foundation Contributors
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Reflection.Metadata 8.0.0 - MIT
-
-
-Copyright (c) Six Labors
-Gets the Copyright Table
-(c) Microsoft Corporation
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 1998 Microsoft. To
-Copyright (c) 2022, Wojciech Mula
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2022, Geoff Langdale
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) 2012-2021 Yann Collet
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright 2012 the V8 project authors
-Copyright (c) 1999 Lucent Technologies
-Copyright (c) 2008-2016, Wojciech Mula
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2021 csFastFloat authors
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Portions (c) International Organization
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2011-2015 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2012 - present, Victor Zverovich
-Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
-Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright (c) 1980, 1986, 1993 The Regents of the University of California
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Runtime.Caching 9.0.2 - MIT
-
-
-Copyright (c) 2021
-Copyright (c) Six Labors
-(c) Microsoft Corporation
-Copyright (c) 2022 FormatJS
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright (c) 1998 Microsoft
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 2015 Andrew Gallant
-Copyright (c) 2022, Wojciech Mula
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2022, Geoff Langdale
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) 2012-2021 Yann Collet
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2018 Nemanja Mijailovic
-Copyright 2012 the V8 project authors
-Copyright (c) 1999 Lucent Technologies
-Copyright (c) 2008-2016, Wojciech Mula
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2015-2018, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2011-2015 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-(c) 1995-2024 Jean-loup Gailly and Mark Adler
-Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2012 - present, Victor Zverovich
-Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
-Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Portions (c) International Organization for Standardization 1986
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright (c) 1980, 1986, 1993 The Regents of the University of California
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Security.AccessControl 6.0.1 - MIT
-
-
-(c) Microsoft Corporation
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 1998 Microsoft. To
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 2012-2014, Yann Collet
-Copyright (c) 1991-2020 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright 2012 the V8 project authors
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Portions (c) International Organization
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Security.Cryptography.Pkcs 9.0.2 - MIT
-
-
-Copyright (c) 2021
-Copyright (c) Six Labors
-(c) Microsoft Corporation
-Copyright (c) 2022 FormatJS
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright (c) 1998 Microsoft
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 2015 Andrew Gallant
-Copyright (c) 2022, Wojciech Mula
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2022, Geoff Langdale
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) 2012-2021 Yann Collet
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2018 Nemanja Mijailovic
-Copyright 2012 the V8 project authors
-Copyright (c) 1999 Lucent Technologies
-Copyright (c) 2008-2016, Wojciech Mula
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2015-2018, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2011-2015 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-(c) 1995-2024 Jean-loup Gailly and Mark Adler
-Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2012 - present, Victor Zverovich
-Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
-Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Portions (c) International Organization for Standardization 1986
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright (c) 1980, 1986, 1993 The Regents of the University of California
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Security.Cryptography.ProtectedData 9.0.2 - MIT
-
-
-Copyright (c) 2021
-Copyright (c) Six Labors
-(c) Microsoft Corporation
-Copyright (c) 2022 FormatJS
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright (c) 1998 Microsoft
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
+Copyright (c) 2020 Dan Shechter
(c) 1997-2005 Sean Eron Anderson
Copyright (c) 2015 Andrew Gallant
Copyright (c) 2022, Wojciech Mula
@@ -4515,7 +4003,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Security.Cryptography.Xml 9.0.2 - MIT
+System.Security.Cryptography.Xml 9.0.3 - MIT
Copyright (c) 2021
@@ -4605,7 +4093,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Security.Permissions 9.0.2 - MIT
+System.Security.Permissions 9.0.3 - MIT
Copyright (c) 2021
@@ -4691,75 +4179,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Security.Principal.Windows 5.0.0 - MIT
-
-
-(c) Microsoft Corporation.
-Copyright (c) Andrew Arnott
-Copyright 2018 Daniel Lemire
-Copyright 2012 the V8 project
-Copyright (c) .NET Foundation.
-Copyright (c) 2011, Google Inc.
-Copyright (c) 1998 Microsoft. To
-(c) 1997-2005 Sean Eron Anderson.
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 2012-2014, Yann Collet
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2018 Alexander Chermyanin
-Portions (c) International Organization
-Copyright (c) 2015 The Chromium Authors.
-Copyright (c) The Internet Society 1997.
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) .NET Foundation Contributors
-Copyright (c) The Internet Society (2003).
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California.
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass.
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
---------------------------------------------------------
---------------------------------------------------------
@@ -4944,97 +4363,7 @@ SOFTWARE.
---------------------------------------------------------
-System.ServiceModel.Syndication 9.0.2 - MIT
-
-
-Copyright (c) 2021
-Copyright (c) Six Labors
-(c) Microsoft Corporation
-Copyright (c) 2022 FormatJS
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright (c) 1998 Microsoft
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 2015 Andrew Gallant
-Copyright (c) 2022, Wojciech Mula
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2022, Geoff Langdale
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) 2012-2021 Yann Collet
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2018 Nemanja Mijailovic
-Copyright 2012 the V8 project authors
-Copyright (c) 1999 Lucent Technologies
-Copyright (c) 2008-2016, Wojciech Mula
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2015-2018, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2011-2015 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-(c) 1995-2024 Jean-loup Gailly and Mark Adler
-Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2012 - present, Victor Zverovich
-Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
-Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Portions (c) International Organization for Standardization 1986
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright (c) 1980, 1986, 1993 The Regents of the University of California
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.ServiceProcess.ServiceController 9.0.2 - MIT
+System.ServiceModel.Syndication 9.0.3 - MIT
Copyright (c) 2021
@@ -5124,7 +4453,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Speech 9.0.2 - MIT
+System.ServiceProcess.ServiceController 9.0.3 - MIT
Copyright (c) 2021
@@ -5214,7 +4543,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Text.Encoding.CodePages 9.0.2 - MIT
+System.Speech 9.0.3 - MIT
Copyright (c) 2021
@@ -5304,7 +4633,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Text.Encodings.Web 9.0.2 - MIT
+System.Threading.AccessControl 9.0.3 - MIT
Copyright (c) 2021
@@ -5394,99 +4723,12 @@ SOFTWARE.
---------------------------------------------------------
-System.Threading.AccessControl 9.0.2 - MIT
+System.Web.Services.Description 8.1.1 - MIT
-Copyright (c) 2021
-Copyright (c) Six Labors
(c) Microsoft Corporation
-Copyright (c) 2022 FormatJS
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright (c) 1998 Microsoft
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 2015 Andrew Gallant
-Copyright (c) 2022, Wojciech Mula
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2022, Geoff Langdale
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) 2012-2021 Yann Collet
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2018 Nemanja Mijailovic
-Copyright 2012 the V8 project authors
-Copyright (c) 1999 Lucent Technologies
-Copyright (c) 2008-2016, Wojciech Mula
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2015-2018, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2011-2015 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-(c) 1995-2024 Jean-loup Gailly and Mark Adler
-Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2012 - present, Victor Zverovich
-Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
-Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Portions (c) International Organization for Standardization 1986
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright (c) 1980, 1986, 1993 The Regents of the University of California
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-
-The MIT License (MIT)
-
Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Web.Services.Description 4.10.0 - MIT
-
-
+Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Provided
The MIT License (MIT)
@@ -5517,7 +4759,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Windows.Extensions 9.0.2 - MIT
+System.Windows.Extensions 9.0.3 - MIT
Copyright (c) 2021
@@ -5797,3 +5039,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
diff --git a/assets/manpage/pwsh.1.ronn b/assets/manpage/pwsh.1.ronn
index 13126164551..98320cc60c8 100644
--- a/assets/manpage/pwsh.1.ronn
+++ b/assets/manpage/pwsh.1.ronn
@@ -40,7 +40,7 @@ Some parameters have abbreviated forms
* `-Command` | `-c`:
Executes the specified commands (and any parameters) as though they were
typed at the PowerShell command prompt, and then exits, unless NoExit is
- specified. The value of Command can be `-`, a string or a script block. If
+ specified. The value of Command can be `-`, a string, or a script block. If
the value of Command is `-`, the command text is read from standard input. If
the value of Command is a script block, the script block must be enclosed in
braces (`{}`). You can specify a script block only when running PowerShell in
@@ -171,7 +171,7 @@ Some parameters have abbreviated forms
* `-WindowStyle` | `-w`
Sets the window style for the session. Valid values are Normal, Minimized,
- Maximized and Hidden. This parameter only applies to Windows. Using this
+ Maximized, and Hidden. This parameter only applies to Windows. Using this
parameter on non-Windows platforms results in an error.
* `-WorkingDirectory` | `-wd` | `-wo`
diff --git a/build.psm1 b/build.psm1
index d03e763e4f5..6a809d4231d 100644
--- a/build.psm1
+++ b/build.psm1
@@ -2,7 +2,7 @@
# Licensed under the MIT License.
param(
- # Skips a check that prevents building PowerShell on unsupported Linux distributions
+ # Skips a check that prevents building PowerShell on unsupported Linux distributions.
[parameter(Mandatory = $false)][switch]$SkipLinuxDistroCheck = $false
)
@@ -11,7 +11,7 @@ param(
# CI runs with PowerShell 5.0, so don't use features like ?: && ||
Set-StrictMode -Version 3.0
-# On Unix paths is separated by colon
+# On Unix paths is separated by colon.
# On Windows paths is separated by semicolon
$script:TestModulePathSeparator = [System.IO.Path]::PathSeparator
$script:Options = $null
@@ -984,8 +984,8 @@ function New-PSOptions {
[ValidateSet('Debug', 'Release', 'CodeCoverage', 'StaticAnalysis', '')]
[string]$Configuration,
- [ValidateSet("net9.0")]
- [string]$Framework = "net9.0",
+ [ValidateSet("net10.0")]
+ [string]$Framework = "net10.0",
# These are duplicated from Start-PSBuild
# We do not use ValidateScript since we want tab completion
@@ -3701,7 +3701,7 @@ function Clear-NativeDependencies
$filesToDeleteWinDesktop = @()
$deps = Get-Content "$PublishFolder/pwsh.deps.json" -Raw | ConvertFrom-Json -Depth 20
- $targetRuntime = ".NETCoreApp,Version=v9.0/$($script:Options.Runtime)"
+ $targetRuntime = ".NETCoreApp,Version=v10.0/$($script:Options.Runtime)"
$runtimePackNetCore = $deps.targets.${targetRuntime}.PSObject.Properties.Name -like 'runtimepack.Microsoft.NETCore.App.Runtime*'
$runtimePackWinDesktop = $deps.targets.${targetRuntime}.PSObject.Properties.Name -like 'runtimepack.Microsoft.WindowsDesktop.App.Runtime*'
diff --git a/global.json b/global.json
index 58b8fbe1952..c30f249d4b2 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "9.0.200"
+ "version": "10.0.100-preview.2.25164.34"
}
}
diff --git a/src/GlobalTools/PowerShell.Windows.x64/PowerShell.Windows.x64.csproj b/src/GlobalTools/PowerShell.Windows.x64/PowerShell.Windows.x64.csproj
index f18bdae611d..49d607ebfed 100644
--- a/src/GlobalTools/PowerShell.Windows.x64/PowerShell.Windows.x64.csproj
+++ b/src/GlobalTools/PowerShell.Windows.x64/PowerShell.Windows.x64.csproj
@@ -2,7 +2,7 @@
Exe
- net9.0
+ net10.0
enable
enable
true
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj
index 900f65f5d34..3b01307f437 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj
index 6bb99cd03fd..387da67b864 100644
--- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj
+++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj
@@ -47,7 +47,7 @@
-
+
diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs
index bdeef0dd7a0..71ef5df8f08 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs
@@ -32,7 +32,8 @@ public class JoinPathCommand : CoreCommandWithCredentialsBase
[Parameter(Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true)]
[AllowNull]
[AllowEmptyString]
- public string ChildPath { get; set; }
+ [AllowEmptyCollection]
+ public string[] ChildPath { get; set; }
///
/// Gets or sets additional childPaths to the command.
@@ -64,7 +65,15 @@ protected override void ProcessRecord()
Path != null,
"Since Path is a mandatory parameter, paths should never be null");
- string combinedChildPath = ChildPath;
+ string combinedChildPath = string.Empty;
+
+ if (this.ChildPath != null)
+ {
+ foreach (string childPath in this.ChildPath)
+ {
+ combinedChildPath = SessionState.Path.Combine(combinedChildPath, childPath, CmdletProviderContext);
+ }
+ }
// join the ChildPath elements
if (AdditionalChildPath != null)
diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs
index 2203c920c1e..3b791d37a1a 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs
@@ -2054,25 +2054,6 @@ internal static bool IsComputerNameValid(string computerName)
return !allDigits;
}
- ///
- /// System Restore APIs are not supported on the ARM platform. Skip the system restore operation is necessary.
- ///
- ///
- ///
- internal static bool SkipSystemRestoreOperationForARMPlatform(PSCmdlet cmdlet)
- {
- bool retValue = false;
- if (PsUtils.IsRunningOnProcessorArchitectureARM())
- {
- var ex = new InvalidOperationException(ComputerResources.SystemRestoreNotSupported);
- var er = new ErrorRecord(ex, "SystemRestoreNotSupported", ErrorCategory.InvalidOperation, null);
- cmdlet.WriteError(er);
- retValue = true;
- }
-
- return retValue;
- }
-
///
/// Invokes the Win32Shutdown command on provided target computer using WSMan
/// over a CIMSession. The flags parameter determines the type of shutdown operation
diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs
index ba4bf137ef0..caef4af84dc 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs
@@ -227,7 +227,7 @@ public IEnumerable CompleteArgument(
CommandAst commandAst,
IDictionary fakeBoundParameters)
=> IsRegistryProvider(fakeBoundParameters)
- ? CompletionCompleters.GetMatchingResults(
+ ? CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: s_RegistryPropertyTypes,
toolTipMapping: GetRegistryPropertyTypeToolTip,
diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs
index e149ece4c87..56efe65b4bb 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs
@@ -16,7 +16,6 @@
using System.Net;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
-using System.Security;
using System.Security.Principal;
using System.Text;
using System.Threading;
@@ -1677,7 +1676,7 @@ public SwitchParameter LoadUserProfile
private SwitchParameter _loaduserprofile = SwitchParameter.Present;
///
- /// Starts process in a new window.
+ /// Starts process in the current console window.
///
[Parameter(ParameterSetName = "Default")]
[Alias("nnw")]
@@ -1965,7 +1964,9 @@ protected override void BeginProcessing()
startInfo.WindowStyle = _windowstyle;
- if (_nonewwindow)
+ // When starting a process as another user, the 'CreateNoWindow' property value is ignored and a new window is created.
+ // See details at https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.createnowindow?view=net-9.0#remarks
+ if (_nonewwindow && _credential is null)
{
startInfo.CreateNoWindow = _nonewwindow;
}
@@ -2405,33 +2406,60 @@ private static byte[] ConvertEnvVarsToByteArray(StringDictionary sd)
private void SetStartupInfo(ProcessStartInfo startinfo, ref ProcessNativeMethods.STARTUPINFO lpStartupInfo, ref int creationFlags)
{
- bool hasRedirection = false;
+ // If we are starting a process using the current console window, we need to set its standard handles
+ // explicitly when they are not redirected because otherwise they won't be set and the new process will
+ // fail with the "invalid handle" error.
+ //
+ // However, if we are starting a process with a new console window, we should not explicitly set those
+ // standard handles when they are not redirected, but instead let Windows figure out the default to use
+ // when creating the process. Otherwise, the standard input handles of the current window and the new
+ // window will get weirdly tied together and cause problems.
+ bool hasRedirection = startinfo.CreateNoWindow
+ || _redirectstandardinput is not null
+ || _redirectstandardoutput is not null
+ || _redirectstandarderror is not null;
+
// RedirectionStandardInput
if (_redirectstandardinput != null)
{
- hasRedirection = true;
startinfo.RedirectStandardInput = true;
_redirectstandardinput = ResolveFilePath(_redirectstandardinput);
lpStartupInfo.hStdInput = GetSafeFileHandleForRedirection(_redirectstandardinput, FileMode.Open);
}
+ else if (startinfo.CreateNoWindow)
+ {
+ lpStartupInfo.hStdInput = new SafeFileHandle(
+ ProcessNativeMethods.GetStdHandle(-10),
+ ownsHandle: false);
+ }
// RedirectionStandardOutput
if (_redirectstandardoutput != null)
{
- hasRedirection = true;
startinfo.RedirectStandardOutput = true;
_redirectstandardoutput = ResolveFilePath(_redirectstandardoutput);
lpStartupInfo.hStdOutput = GetSafeFileHandleForRedirection(_redirectstandardoutput, FileMode.Create);
}
+ else if (startinfo.CreateNoWindow)
+ {
+ lpStartupInfo.hStdOutput = new SafeFileHandle(
+ ProcessNativeMethods.GetStdHandle(-11),
+ ownsHandle: false);
+ }
// RedirectionStandardError
if (_redirectstandarderror != null)
{
- hasRedirection = true;
startinfo.RedirectStandardError = true;
_redirectstandarderror = ResolveFilePath(_redirectstandarderror);
lpStartupInfo.hStdError = GetSafeFileHandleForRedirection(_redirectstandarderror, FileMode.Create);
}
+ else if (startinfo.CreateNoWindow)
+ {
+ lpStartupInfo.hStdError = new SafeFileHandle(
+ ProcessNativeMethods.GetStdHandle(-12),
+ ownsHandle: false);
+ }
if (hasRedirection)
{
@@ -2664,7 +2692,7 @@ public IEnumerable CompleteArgument(
// -Verb is not supported on non-Windows platforms as well as Windows headless SKUs
if (!Platform.IsWindowsDesktop)
{
- return [];
+ return Array.Empty();
}
// Completion: Start-Process -FilePath -Verb
@@ -2698,7 +2726,7 @@ public IEnumerable CompleteArgument(
}
}
- return [];
+ return Array.Empty();
}
///
@@ -2708,7 +2736,7 @@ public IEnumerable CompleteArgument(
/// The file path to get verbs.
/// List of file verbs to complete.
private static IEnumerable CompleteFileVerbs(string wordToComplete, string filePath)
- => CompletionCompleters.GetMatchingResults(
+ => CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: new ProcessStartInfo(filePath).Verbs);
}
@@ -2754,6 +2782,9 @@ public void Dispose()
internal static class ProcessNativeMethods
{
+ [DllImport(PinvokeDllNames.GetStdHandleDllName, SetLastError = true)]
+ public static extern IntPtr GetStdHandle(int whichHandle);
+
[DllImport(PinvokeDllNames.CreateProcessWithLogonWDllName, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CreateProcessWithLogonW(string userName,
diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
index e6db0c9ba06..5926c2ec20f 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
+++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
@@ -32,10 +32,10 @@
-
-
-
-
+
+
+
+
diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx
index 40f02e7a37f..a57d044a8be 100644
--- a/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx
+++ b/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx
@@ -478,7 +478,7 @@ All parameters are case-insensitive.
-WindowStyle | -w
Sets the window style for the session. Valid values are Normal, Minimized,
- Maximized and Hidden.
+ Maximized, and Hidden.
-WorkingDirectory | -wd
diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj
index b5360a74c89..f5556d7e8e1 100644
--- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj
+++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj
index f6ff666a7a0..4ac82f133eb 100644
--- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj
+++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj
@@ -16,27 +16,28 @@
-
-
+
+
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj
index ddba654b6ad..66a9653e5d2 100644
--- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj
+++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj
index 5f9f89a4563..b90e537ca21 100644
--- a/src/Modules/PSGalleryModules.csproj
+++ b/src/Modules/PSGalleryModules.csproj
@@ -5,7 +5,7 @@
Microsoft Corporation
(c) Microsoft Corporation.
- net9.0
+ net10.0
true
@@ -13,10 +13,11 @@
-
+
-
+
+
diff --git a/src/ResGen/ResGen.csproj b/src/ResGen/ResGen.csproj
index a6448b1dc7d..7fcf1ff3f35 100644
--- a/src/ResGen/ResGen.csproj
+++ b/src/ResGen/ResGen.csproj
@@ -2,7 +2,7 @@
Generates C# typed bindings for .resx files
- net9.0
+ net10.0
resgen
Exe
true
diff --git a/src/System.Management.Automation/CoreCLR/CorePsStub.cs b/src/System.Management.Automation/CoreCLR/CorePsStub.cs
index 6f94acbc389..e439cc30ff2 100644
--- a/src/System.Management.Automation/CoreCLR/CorePsStub.cs
+++ b/src/System.Management.Automation/CoreCLR/CorePsStub.cs
@@ -431,7 +431,7 @@ namespace System.Management.Automation.Security
///
/// Application white listing security policies only affect Windows OSs.
///
- internal sealed class SystemPolicy
+ public sealed class SystemPolicy
{
private SystemPolicy() { }
@@ -455,7 +455,7 @@ internal static void LogWDACAuditMessage(
///
/// Gets the system lockdown policy.
///
- /// Always return SystemEnforcementMode.None in CSS (trusted)
+ /// Always return SystemEnforcementMode.None on non-Windows platforms.
public static SystemEnforcementMode GetSystemLockdownPolicy()
{
return SystemEnforcementMode.None;
@@ -464,7 +464,7 @@ public static SystemEnforcementMode GetSystemLockdownPolicy()
///
/// Gets lockdown policy as applied to a file.
///
- /// Always return SystemEnforcementMode.None in CSS (trusted)
+ /// Always return SystemEnforcementMode.None on non-Windows platforms.
public static SystemEnforcementMode GetLockdownPolicy(string path, System.Runtime.InteropServices.SafeHandle handle)
{
return SystemEnforcementMode.None;
@@ -493,7 +493,7 @@ public static SystemScriptFileEnforcement GetFilePolicyEnforcement(
///
/// How the policy is being enforced.
///
- internal enum SystemEnforcementMode
+ public enum SystemEnforcementMode
{
/// Not enforced at all
None = 0,
diff --git a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj
index 33afc31b37e..00a5188ca5c 100644
--- a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj
+++ b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj
@@ -14,7 +14,7 @@
-
-
+
+
diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj
index 1e0aba0e3bb..59fc5e09445 100644
--- a/src/System.Management.Automation/System.Management.Automation.csproj
+++ b/src/System.Management.Automation/System.Management.Automation.csproj
@@ -30,23 +30,26 @@
-
+
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
diff --git a/src/System.Management.Automation/engine/CommandBase.cs b/src/System.Management.Automation/engine/CommandBase.cs
index 4d90a7c2490..3708611df07 100644
--- a/src/System.Management.Automation/engine/CommandBase.cs
+++ b/src/System.Management.Automation/engine/CommandBase.cs
@@ -8,8 +8,7 @@
using System.Management.Automation.Internal.Host;
using System.Management.Automation.Language;
using System.Management.Automation.Runspaces;
-
-using Dbg = System.Management.Automation.Diagnostics;
+using System.Threading;
namespace System.Management.Automation.Internal
{
@@ -132,6 +131,13 @@ internal bool IsStopping
}
}
+ ///
+ /// Gets the CancellationToken that is signaled when the pipeline is stopping.
+ ///
+ internal CancellationToken StopToken => commandRuntime is MshCommandRuntime mcr
+ ? mcr.PipelineProcessor.PipelineStopToken
+ : default;
+
///
/// The information about the command.
///
diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs
index e98f577090c..42a60ab7e0e 100644
--- a/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs
+++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs
@@ -693,6 +693,19 @@ internal List GetResultHelper(CompletionContext completionCont
return completions;
}
}
+ else if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
+ {
+ foreach (AttributeBaseAst attribute in paramAst.Attributes)
+ {
+ if (IsCursorWithinOrJustAfterExtent(_cursorPosition, attribute.Extent))
+ {
+ completionContext.ReplacementIndex = replacementIndex += tokenAtCursor.Text.Length;
+ completionContext.ReplacementLength = replacementLength = 0;
+ result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
+ break;
+ }
+ }
+ }
else
{
// Handle scenarios such as 'configuration foo { File ab { Attributes ='
@@ -928,6 +941,18 @@ internal List GetResultHelper(CompletionContext completionCont
{
result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
}
+
+ if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
+ {
+ foreach (AttributeBaseAst attribute in paramAst.Attributes)
+ {
+ if (IsCursorWithinOrJustAfterExtent(_cursorPosition, attribute.Extent))
+ {
+ result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
+ break;
+ }
+ }
+ }
break;
case TokenKind.Ieq:
@@ -1003,6 +1028,21 @@ internal List GetResultHelper(CompletionContext completionCont
break;
}
+ if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
+ {
+ foreach (AttributeBaseAst attribute in paramAst.Attributes)
+ {
+ if (IsCursorWithinOrJustAfterExtent(_cursorPosition, attribute.Extent))
+ {
+ completionContext.ReplacementLength = replacementLength = 0;
+ result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
+ break;
+ }
+ }
+
+ break;
+ }
+
result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty, ref replacementIndex, ref replacementLength, out _);
break;
}
@@ -1421,18 +1461,115 @@ private static List CompletePropertyAssignment(MemberExpressio
{
if (SafeExprEvaluator.TrySafeEval(memberExpression, context.ExecutionContext, out var evalValue))
{
- if (evalValue is null)
+ if (evalValue is not null)
{
+ Type type = evalValue.GetType();
+ if (type.IsEnum)
+ {
+ return GetResultForEnum(type, context);
+ }
+
return null;
}
+ }
- Type type = evalValue.GetType();
- if (type.IsEnum)
+ _ = TryGetInferredCompletionsForAssignment(memberExpression, context, out List result);
+ return result;
+ }
+
+ private static bool TryGetInferredCompletionsForAssignment(Ast expression, CompletionContext context, out List result)
+ {
+ result = null;
+ IList inferredTypes;
+ if (expression.Parent is ConvertExpressionAst convertExpression)
+ {
+ inferredTypes = new PSTypeName[] { new(convertExpression.Type.TypeName) };
+ }
+ else if (expression is MemberExpressionAst)
+ {
+ inferredTypes = AstTypeInference.InferTypeOf(expression);
+ }
+ else if (expression is VariableExpressionAst varExpression)
+ {
+ PSTypeName typeConstraint = CompletionCompleters.GetLastDeclaredTypeConstraint(varExpression, context.TypeInferenceContext);
+ if (typeConstraint is null)
{
- return GetResultForEnum(type, context);
+ return false;
}
+
+ inferredTypes = new PSTypeName[] { typeConstraint };
}
- return null;
+ else
+ {
+ return false;
+ }
+
+ if (inferredTypes.Count == 0)
+ {
+ return false;
+ }
+
+ var values = new SortedSet();
+ foreach (PSTypeName type in inferredTypes)
+ {
+ Type loadedType = type.Type;
+ if (loadedType is not null)
+ {
+ if (loadedType.IsEnum)
+ {
+ foreach (string value in Enum.GetNames(loadedType))
+ {
+ _ = values.Add(value);
+ }
+ }
+ }
+ else if (type is not null && type.TypeDefinitionAst.IsEnum)
+ {
+ foreach (MemberAst member in type.TypeDefinitionAst.Members)
+ {
+ if (member is PropertyMemberAst property)
+ {
+ _ = values.Add(property.Name);
+ }
+ }
+ }
+ }
+
+ string wordToComplete;
+ if (string.IsNullOrEmpty(context.WordToComplete))
+ {
+ if (context.TokenAtCursor is not null && context.TokenAtCursor.Kind != TokenKind.Equals)
+ {
+ wordToComplete = context.TokenAtCursor.Text + "*";
+ }
+ else
+ {
+ wordToComplete = "*";
+ }
+ }
+ else
+ {
+ wordToComplete = context.WordToComplete + "*";
+ }
+
+ result = new List();
+ var pattern = new WildcardPattern(wordToComplete, WildcardOptions.IgnoreCase);
+ foreach (string name in values)
+ {
+ string quotedName = GetQuotedString(name, context);
+ if (pattern.IsMatch(quotedName))
+ {
+ result.Add(new CompletionResult(quotedName, name, CompletionResultType.Property, name));
+ }
+ }
+
+ if (result.Count == 0)
+ {
+ result = null;
+ return false;
+ }
+
+ return true;
}
private static bool TryGetCompletionsForVariableAssignment(
@@ -1501,7 +1638,7 @@ bool TryGetResultForSet(Type typeConstraint, ValidateSetAttribute setConstraint,
// If the assignment itself was unconstrained, the variable still might be
if (!TryGetTypeConstraintOnVariable(completionContext, variableAst.VariablePath.UserPath, out typeConstraint, out setConstraint))
{
- return false;
+ return TryGetInferredCompletionsForAssignment(variableAst, completionContext, out completions);
}
// Again try the [ValidateSet()] constraint first
@@ -1963,7 +2100,12 @@ private static List GetResultForIdentifier(CompletionContext c
switch (usingState.UsingStatementKind)
{
case UsingStatementKind.Assembly:
- break;
+ HashSet assemblyExtensions = new(StringComparer.OrdinalIgnoreCase)
+ {
+ StringLiterals.PowerShellILAssemblyExtension
+ };
+ return CompletionCompleters.CompleteFilename(completionContext, containerOnly: false, assemblyExtensions).ToList();
+
case UsingStatementKind.Command:
break;
case UsingStatementKind.Module:
@@ -1998,9 +2140,25 @@ private static List GetResultForIdentifier(CompletionContext c
}
}
}
- if (completionContext.TokenAtCursor.TokenFlags == TokenFlags.MemberName && (lastAst is NamedAttributeArgumentAst || lastAst.Parent is NamedAttributeArgumentAst))
+
+ if (completionContext.TokenAtCursor.TokenFlags == TokenFlags.MemberName)
{
- result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
+ if (lastAst is NamedAttributeArgumentAst || lastAst.Parent is NamedAttributeArgumentAst)
+ {
+ result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
+ }
+ else if (lastAst is VariableExpressionAst && lastAst.Parent is ParameterAst paramAst && paramAst.Attributes.Count > 0)
+ {
+ foreach (AttributeBaseAst attribute in paramAst.Attributes)
+ {
+ if (IsCursorWithinOrJustAfterExtent(completionContext.CursorPosition, attribute.Extent))
+ {
+ result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
+ break;
+ }
+ }
+ }
+
if (result is not null)
{
return result;
diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
index 9e227cce91d..e9a28c2a165 100644
--- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
+++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
@@ -89,7 +89,7 @@ private static List CompleteCommand(CompletionContext context,
var addAmpersandIfNecessary = IsAmpersandNeeded(context, false);
string commandName = context.WordToComplete;
- string quote = HandleDoubleAndSingleQuote(ref commandName);
+ string quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref commandName);
List commandResults = null;
@@ -234,7 +234,7 @@ internal static CompletionResult GetCommandNameCompletionResult(string name, obj
syntax = string.IsNullOrEmpty(syntax) ? name : syntax;
bool needAmpersand;
- if (CompletionRequiresQuotes(name, false))
+ if (CompletionHelpers.CompletionRequiresQuotes(name))
{
needAmpersand = quote == string.Empty && addAmpersandIfNecessary;
string quoteInUse = quote == string.Empty ? "'" : quote;
@@ -329,50 +329,72 @@ internal static List MakeCommandsUnique(IEnumerable
}
}
- List endResults = null;
foreach (var keyValuePair in commandTable)
{
- var commandList = keyValuePair.Value as List;
- if (commandList != null)
+ if (keyValuePair.Value is List commandList)
{
- endResults ??= new List();
-
- // The first command might be an un-prefixed commandInfo that we get by importing a module with the -Prefix parameter,
- // in that case, we should add the module name qualification because if the module is not in the module path, calling
- // 'Get-Foo' directly doesn't work
- string completionName = keyValuePair.Key;
- if (!includeModulePrefix)
+ var modulesWithCommand = new HashSet(StringComparer.OrdinalIgnoreCase);
+ var importedModules = new HashSet(StringComparer.OrdinalIgnoreCase);
+ var commandInfoList = new List(commandList.Count);
+ for (int i = 0; i < commandList.Count; i++)
{
- var commandInfo = commandList[0] as CommandInfo;
- if (commandInfo != null && !string.IsNullOrEmpty(commandInfo.Prefix))
+ if (commandList[i] is not CommandInfo commandInfo)
{
- Diagnostics.Assert(!string.IsNullOrEmpty(commandInfo.ModuleName), "the module name should exist if commandInfo.Prefix is not an empty string");
- if (!ModuleCmdletBase.IsPrefixedCommand(commandInfo))
- {
- completionName = commandInfo.ModuleName + "\\" + completionName;
- }
+ continue;
+ }
+
+ commandInfoList.Add(commandInfo);
+ if (commandInfo.CommandType == CommandTypes.Application)
+ {
+ continue;
+ }
+
+ modulesWithCommand.Add(commandInfo.ModuleName);
+ if ((commandInfo.CommandType == CommandTypes.Cmdlet && commandInfo.CommandMetadata.CommandType is not null)
+ || (commandInfo.CommandType is CommandTypes.Function or CommandTypes.Filter && commandInfo.Definition != string.Empty)
+ || (commandInfo.CommandType == CommandTypes.Alias && commandInfo.Definition is not null))
+ {
+ // Checks if the command or source module has been imported.
+ _ = importedModules.Add(commandInfo.ModuleName);
}
}
- results.Add(GetCommandNameCompletionResult(completionName, commandList[0], addAmpersandIfNecessary, quote));
+ if (commandInfoList.Count == 0)
+ {
+ continue;
+ }
- // For the other commands that are hidden, we need to disambiguate,
- // but put these at the end as it's less likely any of the hidden
- // commands are desired. If we can't add anything to disambiguate,
- // then we'll skip adding a completion result.
- for (int index = 1; index < commandList.Count; index++)
+ int moduleCount = modulesWithCommand.Count;
+ modulesWithCommand.Clear();
+ int index;
+ if (commandInfoList[0].CommandType == CommandTypes.Application
+ || importedModules.Count == 1
+ || moduleCount < 2)
{
- var commandInfo = commandList[index] as CommandInfo;
- Diagnostics.Assert(commandInfo != null, "Elements should always be CommandInfo");
+ // We can use the short name for this command because there's no ambiguity about which command it resolves to.
+ // If the first element is an application then we know there's no conflicting commands/aliases (because of the command precedence).
+ // If there's just 1 module imported then the short name refers to that module (and it will be the first element in the list)
+ // If there's less than 2 unique modules exporting that command then we can use the short name because it can only refer to that module.
+ index = 1;
+ results.Add(GetCommandNameCompletionResult(keyValuePair.Key, commandInfoList[0], addAmpersandIfNecessary, quote));
+ modulesWithCommand.Add(commandInfoList[0].ModuleName);
+ }
+ else
+ {
+ index = 0;
+ }
+ for (; index < commandInfoList.Count; index++)
+ {
+ CommandInfo commandInfo = commandInfoList[index];
if (commandInfo.CommandType == CommandTypes.Application)
{
- endResults.Add(GetCommandNameCompletionResult(commandInfo.Definition, commandInfo, addAmpersandIfNecessary, quote));
+ results.Add(GetCommandNameCompletionResult(commandInfo.Definition, commandInfo, addAmpersandIfNecessary, quote));
}
- else if (!string.IsNullOrEmpty(commandInfo.ModuleName))
+ else if (!string.IsNullOrEmpty(commandInfo.ModuleName) && modulesWithCommand.Add(commandInfo.ModuleName))
{
var name = commandInfo.ModuleName + "\\" + commandInfo.Name;
- endResults.Add(GetCommandNameCompletionResult(name, commandInfo, addAmpersandIfNecessary, quote));
+ results.Add(GetCommandNameCompletionResult(name, commandInfo, addAmpersandIfNecessary, quote));
}
}
}
@@ -399,11 +421,6 @@ internal static List MakeCommandsUnique(IEnumerable
}
}
- if (endResults != null && endResults.Count > 0)
- {
- results.AddRange(endResults);
- }
-
return results;
}
@@ -426,7 +443,7 @@ internal static List CompleteModuleName(CompletionContext cont
{
var wordToComplete = context.WordToComplete ?? string.Empty;
var result = new List();
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
// Indicates if we should search for modules where the last part of the name matches the input text
// eg: Host finds Microsoft.PowerShell.Host
@@ -507,17 +524,7 @@ internal static List CompleteModuleName(CompletionContext cont
+ moduleInfo.ModuleType.ToString() + "\r\nPath: "
+ moduleInfo.Path;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, toolTip));
}
@@ -1792,7 +1799,7 @@ private static void ProcessParameter(
RemoveLastNullCompletionResult(result);
string wordToComplete = context.WordToComplete ?? string.Empty;
- string quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ string quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
var pattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
var setList = new List();
@@ -1827,23 +1834,8 @@ private static void ProcessParameter(
{
string realEntry = entry;
string completionText = entry;
- if (quote == string.Empty)
- {
- if (CompletionRequiresQuotes(entry, false))
- {
- realEntry = CodeGeneration.EscapeSingleQuotedStringContent(entry);
- completionText = "'" + realEntry + "'";
- }
- }
- else
- {
- if (quote.Equals("'", StringComparison.OrdinalIgnoreCase))
- {
- realEntry = CodeGeneration.EscapeSingleQuotedStringContent(entry);
- }
- completionText = quote + realEntry + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, entry, CompletionResultType.ParameterValue, entry));
}
@@ -1869,7 +1861,7 @@ private static void ProcessParameter(
}
string wordToComplete = context.WordToComplete ?? string.Empty;
- string quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ string quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
var pattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
var enumList = new List();
@@ -3181,7 +3173,7 @@ private static void NativeCompletionEventLogCommands(CompletionContext context,
RemoveLastNullCompletionResult(result);
var logName = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref logName);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref logName);
if (!logName.EndsWith('*'))
{
@@ -3203,17 +3195,7 @@ private static void NativeCompletionEventLogCommands(CompletionContext context,
var completionText = eventLog.Log.ToString();
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
if (pattern.IsMatch(listItemText))
{
@@ -3232,7 +3214,7 @@ private static void NativeCompletionJobCommands(CompletionContext context, strin
return;
var wordToComplete = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
if (!wordToComplete.EndsWith('*'))
{
@@ -3294,17 +3276,7 @@ private static void NativeCompletionJobCommands(CompletionContext context, strin
var completionText = psJob.Name;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -3319,7 +3291,7 @@ private static void NativeCompletionScheduledJobCommands(CompletionContext conte
return;
var wordToComplete = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
if (!wordToComplete.EndsWith('*'))
{
@@ -3369,17 +3341,7 @@ private static void NativeCompletionScheduledJobCommands(CompletionContext conte
var completionText = psJob.Name;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -3453,7 +3415,7 @@ private static void NativeCompletionProcessCommands(CompletionContext context, s
return;
var wordToComplete = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
if (!wordToComplete.EndsWith('*'))
{
@@ -3509,17 +3471,7 @@ private static void NativeCompletionProcessCommands(CompletionContext context, s
continue;
uniqueSet.Add(completionText);
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
// on macOS, system processes names will be empty if PowerShell isn't run as `sudo`
if (string.IsNullOrEmpty(listItemText))
@@ -3544,7 +3496,7 @@ private static void NativeCompletionProviderCommands(CompletionContext context,
RemoveLastNullCompletionResult(result);
var providerName = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref providerName);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref providerName);
if (!providerName.EndsWith('*'))
{
@@ -3562,17 +3514,7 @@ private static void NativeCompletionProviderCommands(CompletionContext context,
var completionText = providerInfo.Name;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -3588,7 +3530,7 @@ private static void NativeCompletionDriveCommands(CompletionContext context, str
RemoveLastNullCompletionResult(result);
var wordToComplete = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
if (!wordToComplete.EndsWith('*'))
{
@@ -3610,17 +3552,7 @@ private static void NativeCompletionDriveCommands(CompletionContext context, str
var completionText = driveInfo.Name;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -3635,7 +3567,7 @@ private static void NativeCompletionServiceCommands(CompletionContext context, s
return;
var wordToComplete = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
if (!wordToComplete.EndsWith('*'))
{
@@ -3661,17 +3593,7 @@ private static void NativeCompletionServiceCommands(CompletionContext context, s
var completionText = serviceInfo.DisplayName;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -3692,17 +3614,7 @@ private static void NativeCompletionServiceCommands(CompletionContext context, s
var completionText = serviceInfo.Name;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -3722,7 +3634,7 @@ private static void NativeCompletionVariableCommands(CompletionContext context,
RemoveLastNullCompletionResult(result);
var variableName = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref variableName);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref variableName);
if (!variableName.EndsWith('*'))
{
variableName += "*";
@@ -3748,7 +3660,7 @@ private static void NativeCompletionVariableCommands(CompletionContext context,
completionText = completionText.Replace("*", "`*");
}
- if (!completionText.Equals("$", StringComparison.Ordinal) && CompletionRequiresQuotes(completionText, false))
+ if (!completionText.Equals("$", StringComparison.Ordinal) && CompletionHelpers.CompletionRequiresQuotes(completionText))
{
var quoteInUse = effectiveQuote == string.Empty ? "'" : effectiveQuote;
if (quoteInUse == "'")
@@ -3781,7 +3693,7 @@ private static void NativeCompletionAliasCommands(CompletionContext context, str
if (paramName.Equals("Name", StringComparison.OrdinalIgnoreCase))
{
var commandName = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref commandName);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref commandName);
if (!commandName.EndsWith('*'))
{
@@ -3798,17 +3710,7 @@ private static void NativeCompletionAliasCommands(CompletionContext context, str
var completionText = aliasInfo.Name;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -3842,7 +3744,7 @@ private static void NativeCompletionTraceSourceCommands(CompletionContext contex
RemoveLastNullCompletionResult(result);
var traceSourceName = context.WordToComplete ?? string.Empty;
- var quote = HandleDoubleAndSingleQuote(ref traceSourceName);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref traceSourceName);
if (!traceSourceName.EndsWith('*'))
{
@@ -3861,17 +3763,7 @@ private static void NativeCompletionTraceSourceCommands(CompletionContext contex
var completionText = trace.Name;
var listItemText = completionText;
- if (CompletionRequiresQuotes(completionText, false))
- {
- var quoteInUse = quote == string.Empty ? "'" : quote;
- if (quoteInUse == "'")
- completionText = completionText.Replace("'", "''");
- completionText = quoteInUse + completionText + quoteInUse;
- }
- else
- {
- completionText = quote + completionText + quote;
- }
+ completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
}
@@ -4476,16 +4368,17 @@ internal static IEnumerable CompleteFilename(CompletionContext
internal static IEnumerable CompleteFilename(CompletionContext context, bool containerOnly, HashSet extension)
{
var wordToComplete = context.WordToComplete;
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
- // First, try to match \\server\share
- // support both / and \ when entering UNC paths for typing convenience (#17111)
- var shareMatch = Regex.Match(wordToComplete, @"^(?:\\\\|//)([^\\/]+)(?:\\|/)([^\\/]*)$");
+ // Matches file shares with and without the provider name and with either slash direction.
+ // Avoids matching Windows device paths like \\.\CDROM0 and \\?\Volume{b8f3fc1c-5cd6-4553-91e2-d6814c4cd375}\
+ var shareMatch = s_shareMatch.Match(wordToComplete);
if (shareMatch.Success)
{
// Only match share names, no filenames.
- var server = shareMatch.Groups[1].Value;
- var sharePattern = WildcardPattern.Get(shareMatch.Groups[2].Value + "*", WildcardOptions.IgnoreCase);
+ var provider = shareMatch.Groups[1].Value;
+ var server = shareMatch.Groups[2].Value;
+ var sharePattern = WildcardPattern.Get(shareMatch.Groups[3].Value + "*", WildcardOptions.IgnoreCase);
var ignoreHidden = context.GetOption("IgnoreHiddenShares", @default: false);
var shares = GetFileShares(server, ignoreHidden);
if (shares.Count == 0)
@@ -4498,13 +4391,20 @@ internal static IEnumerable CompleteFilename(CompletionContext
{
if (sharePattern.IsMatch(share))
{
- string shareFullPath = "\\\\" + server + "\\" + share;
- if (quote != string.Empty)
+ string sharePath = $"\\\\{server}\\{share}";
+ string completionText;
+ if (quote == string.Empty)
{
- shareFullPath = quote + shareFullPath + quote;
+ completionText = share.Contains(' ')
+ ? $"'{provider}{sharePath}'"
+ : $"{provider}{sharePath}";
+ }
+ else
+ {
+ completionText = $"{quote}{provider}{sharePath}{quote}";
}
- shareResults.Add(new CompletionResult(shareFullPath, shareFullPath, CompletionResultType.ProviderContainer, shareFullPath));
+ shareResults.Add(new CompletionResult(completionText, share, CompletionResultType.ProviderContainer, sharePath));
}
}
@@ -4585,20 +4485,41 @@ internal static IEnumerable CompleteFilename(CompletionContext
basePath = EscapePath(basePath, stringType, useLiteralPath, out _);
}
- _ = context.Helper
+ PowerShell currentPS = context.Helper
.AddCommandWithPreferenceSetting("Microsoft.PowerShell.Management\\Resolve-Path")
.AddParameter("Path", basePath);
- var resolvedPaths = context.Helper.ExecuteCurrentPowerShell(out _);
- if (resolvedPaths is null || resolvedPaths.Count == 0)
+ string relativeBasePath;
+ var useRelativePath = context.GetOption("RelativePaths", @default: defaultRelativePath);
+ if (useRelativePath)
{
- return CommandCompletion.EmptyCompletionResult;
+ if (providerSeparatorIndex != -1)
+ {
+ // User must have requested relative paths but that's not valid with provider paths.
+ return CommandCompletion.EmptyCompletionResult;
+ }
+
+ var lastAst = context.RelatedAsts[^1];
+ if (lastAst.Parent is UsingStatementAst usingStatement
+ && usingStatement.UsingStatementKind is UsingStatementKind.Module or UsingStatementKind.Assembly
+ && lastAst.Extent.File is not null)
+ {
+ relativeBasePath = Directory.GetParent(lastAst.Extent.File).FullName;
+ _ = currentPS.AddParameter("RelativeBasePath", relativeBasePath);
+ }
+ else
+ {
+ relativeBasePath = context.ExecutionContext.SessionState.Internal.CurrentLocation.ProviderPath;
+ }
+ }
+ else
+ {
+ relativeBasePath = string.Empty;
}
- var useRelativePath = context.GetOption("RelativePaths", @default: defaultRelativePath);
- if (useRelativePath && providerSeparatorIndex != -1)
+ var resolvedPaths = context.Helper.ExecuteCurrentPowerShell(out _);
+ if (resolvedPaths is null || resolvedPaths.Count == 0)
{
- // User must have requested relative paths but that's not valid with provider paths.
return CommandCompletion.EmptyCompletionResult;
}
@@ -4632,7 +4553,8 @@ internal static IEnumerable CompleteFilename(CompletionContext
useLiteralPath,
inputUsedHomeChar,
providerPrefix,
- stringType);
+ stringType,
+ relativeBasePath);
break;
default:
@@ -4667,6 +4589,7 @@ internal static IEnumerable CompleteFilename(CompletionContext
///
///
///
+ ///
///
private static List GetFileSystemProviderResults(
CompletionContext context,
@@ -4679,7 +4602,8 @@ private static List GetFileSystemProviderResults(
bool literalPaths,
bool inputUsedHome,
string providerPrefix,
- StringConstantType stringType)
+ StringConstantType stringType,
+ string relativeBasePath)
{
#if DEBUG
Diagnostics.Assert(provider.Name.Equals(FileSystemProvider.ProviderName), "Provider should be filesystem provider.");
@@ -4754,7 +4678,7 @@ private static List GetFileSystemProviderResults(
{
basePath = context.ExecutionContext.EngineSessionState.NormalizeRelativePath(
entry.FullName,
- context.ExecutionContext.SessionState.Internal.CurrentLocation.ProviderPath);
+ relativeBasePath);
if (!basePath.StartsWith($"..{provider.ItemSeparator}", StringComparison.Ordinal))
{
basePath = $".{provider.ItemSeparator}{basePath}";
@@ -4834,6 +4758,13 @@ private static List GetDefaultProviderResults(
bool hadErrors;
var childItemOutput = context.Helper.ExecuteCurrentPowerShell(out _, out hadErrors);
+ if (childItemOutput.Count == 1 &&
+ (pathInfo.Provider.FullName + "::" + pathInfo.ProviderPath).EqualsOrdinalIgnoreCase(childItemOutput[0].Properties["PSPath"].Value as string))
+ {
+ // Get-ChildItem returned the item itself instead of the children so there must be no child items to complete.
+ continue;
+ }
+
var childrenInfoTable = new Dictionary(childItemOutput.Count);
var childNameList = new List(childItemOutput.Count);
@@ -4869,7 +4800,7 @@ private static List GetDefaultProviderResults(
if (childNameList.Count == 0)
{
- return results;
+ continue;
}
string basePath = providerPrefix.Length > 0
@@ -5155,6 +5086,10 @@ private static string NewPathCompletionText(string parent, string leaf, StringCo
return result;
}
+ private static readonly Regex s_shareMatch = new(
+ @"(^Microsoft\.PowerShell\.Core\\FileSystem::|^FileSystem::|^)(?:\\\\|//)(?![.|?])([^\\/]+)(?:\\|/)([^\\/]*)$",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct SHARE_INFO_1
{
@@ -5244,7 +5179,7 @@ public static IEnumerable CompleteVariable(string variableName
return CompleteVariable(new CompletionContext { WordToComplete = variableName, Helper = helper, ExecutionContext = executionContext });
}
- private static readonly string[] s_variableScopes = new string[] { "Global:", "Local:", "Script:", "Private:" };
+ private static readonly string[] s_variableScopes = new string[] { "Global:", "Local:", "Script:", "Private:", "Using:" };
private static readonly SearchValues s_charactersRequiringQuotes = SearchValues.Create("-`&@'\"#{}()$,;|<> .\\/ \t^");
@@ -5258,7 +5193,13 @@ internal static List CompleteVariable(CompletionContext contex
List tempResults = new();
var wordToComplete = context.WordToComplete;
+ string scopePrefix = string.Empty;
var colon = wordToComplete.IndexOf(':');
+ if (colon >= 0)
+ {
+ scopePrefix = wordToComplete.Remove(colon + 1);
+ wordToComplete = wordToComplete.Substring(colon + 1);
+ }
var lastAst = context.RelatedAsts?[^1];
var variableAst = lastAst as VariableExpressionAst;
@@ -5301,15 +5242,23 @@ internal static List CompleteVariable(CompletionContext contex
continue;
}
- var varInfo = findVariablesVisitor.VariableInfoTable[varName];
- var varType = varInfo.LastDeclaredConstraint ?? varInfo.LastAssignedType;
- var toolTip = varType is null
- ? varName
- : StringUtil.Format("[{0}]${1}", ToStringCodeMethods.Type(varType, dropNamespaces: true), varName);
+ VariableInfo varInfo = findVariablesVisitor.VariableInfoTable[varName];
+ PSTypeName varType = varInfo.LastDeclaredConstraint ?? varInfo.LastAssignedType;
+ string toolTip;
+ if (varType is null)
+ {
+ toolTip = varName;
+ }
+ else
+ {
+ toolTip = varType.Type is not null
+ ? StringUtil.Format("[{0}]${1}", ToStringCodeMethods.Type(varType.Type, dropNamespaces: true), varName)
+ : varType.Name;
+ }
var completionText = !tokenAtCursorUsedBraces && !ContainsCharactersRequiringQuotes(varName)
- ? prefix + varName
- : prefix + "{" + varName + "}";
+ ? prefix + scopePrefix + varName
+ : prefix + "{" + scopePrefix + varName + "}";
AddUniqueVariable(hashedResults, results, completionText, varName, toolTip);
}
}
@@ -5327,10 +5276,15 @@ internal static List CompleteVariable(CompletionContext contex
var toolTip = value is null
? key
: StringUtil.Format("[{0}]${1}", ToStringCodeMethods.Type(value.GetType(), dropNamespaces: true), key);
+ if (!string.IsNullOrEmpty(variable.Description))
+ {
+ toolTip += $" - {variable.Description}";
+ }
+
var completionText = !tokenAtCursorUsedBraces && !ContainsCharactersRequiringQuotes(name)
? prefix + name
: prefix + "{" + name + "}";
- AddUniqueVariable(hashedResults, tempResults, completionText, key, key);
+ AddUniqueVariable(hashedResults, tempResults, completionText, key, toolTip);
}
}
@@ -5342,15 +5296,14 @@ internal static List CompleteVariable(CompletionContext contex
}
else
{
- string provider = wordToComplete.Substring(0, colon + 1);
string pattern;
- if (s_variableScopes.Contains(provider, StringComparer.OrdinalIgnoreCase))
+ if (s_variableScopes.Contains(scopePrefix, StringComparer.OrdinalIgnoreCase))
{
- pattern = string.Concat("variable:", wordToComplete.AsSpan(colon + 1), "*");
+ pattern = string.Concat("variable:", wordToComplete, "*");
}
else
{
- pattern = wordToComplete + "*";
+ pattern = scopePrefix + wordToComplete + "*";
}
var powerShellExecutionHelper = context.Helper;
@@ -5380,9 +5333,14 @@ internal static List CompleteVariable(CompletionContext contex
}
}
+ if (!string.IsNullOrEmpty(variable.Description))
+ {
+ tooltip += $" - {variable.Description}";
+ }
+
var completedName = !tokenAtCursorUsedBraces && !ContainsCharactersRequiringQuotes(name)
- ? prefix + provider + name
- : prefix + "{" + provider + name + "}";
+ ? prefix + scopePrefix + name
+ : prefix + "{" + scopePrefix + name + "}";
AddUniqueVariable(hashedResults, results, completedName, name, tooltip);
}
}
@@ -5405,22 +5363,22 @@ internal static List CompleteVariable(CompletionContext contex
tempResults.Clear();
}
- // Return variables already in session state first, because we can sometimes give better information,
- // like the variables type.
- foreach (var specialVariable in s_specialVariablesCache.Value)
+ if (colon == -1)
{
- if (wildcardPattern.IsMatch(specialVariable))
+ // Return variables already in session state first, because we can sometimes give better information,
+ // like the variables type.
+ foreach (var specialVariable in s_specialVariablesCache.Value)
{
- var completedName = !tokenAtCursorUsedBraces && !ContainsCharactersRequiringQuotes(specialVariable)
- ? prefix + specialVariable
- : prefix + "{" + specialVariable + "}";
+ if (wildcardPattern.IsMatch(specialVariable))
+ {
+ var completedName = !tokenAtCursorUsedBraces && !ContainsCharactersRequiringQuotes(specialVariable)
+ ? prefix + specialVariable
+ : prefix + "{" + specialVariable + "}";
- AddUniqueVariable(hashedResults, results, completedName, specialVariable, specialVariable);
+ AddUniqueVariable(hashedResults, results, completedName, specialVariable, specialVariable);
+ }
}
- }
- if (colon == -1)
- {
var allDrives = context.ExecutionContext.SessionState.Drive.GetAll();
foreach (var drive in allDrives)
{
@@ -5468,7 +5426,7 @@ private static void AddUniqueVariable(HashSet hashedResults, List s_varModificationCommands = new(StringComparer.OrdinalIgnoreCase)
+ internal static readonly HashSet s_varModificationCommands = new(StringComparer.OrdinalIgnoreCase)
{
"New-Variable",
"nv",
@@ -5477,13 +5435,13 @@ private static void AddUniqueVariable(HashSet hashedResults, List hashedResults, List s_localScopeCommandNames = new(StringComparer.OrdinalIgnoreCase)
+ internal static readonly HashSet s_localScopeCommandNames = new(StringComparer.OrdinalIgnoreCase)
{
"Microsoft.PowerShell.Core\\ForEach-Object",
"ForEach-Object",
@@ -5518,11 +5476,11 @@ private static void AddUniqueVariable(HashSet hashedResults, List StopSearchOffset)
{
- return AstVisitAction.StopVisit;
+ // When visiting do while/until statements, the condition will be visited before the statement block.
+ // The condition itself may not be interesting if it's after the cursor, but the statement block could be.
+ return ast is PipelineBaseAst && ast.Parent is DoUntilStatementAst or DoWhileStatementAst
+ ? AstVisitAction.SkipChildren
+ : AstVisitAction.StopVisit;
}
return AstVisitAction.Continue;
@@ -5607,7 +5568,9 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a
{
if (assignmentStatementAst.Extent.StartOffset > StopSearchOffset)
{
- return AstVisitAction.StopVisit;
+ return assignmentStatementAst.Parent is DoUntilStatementAst or DoWhileStatementAst ?
+ AstVisitAction.SkipChildren
+ : AstVisitAction.StopVisit;
}
if (assignmentStatementAst.Left is AttributedExpressionAst attributedExpression)
@@ -5635,14 +5598,14 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a
if (firstConvertExpression is not null)
{
- SaveVariableInfo(variableExpression.VariablePath.UserPath, firstConvertExpression.StaticType, isConstraint: true);
+ SaveVariableInfo(variableExpression.VariablePath.UnqualifiedPath, new PSTypeName(firstConvertExpression.Type.TypeName), isConstraint: true);
}
else
{
- Type lastAssignedType = assignmentStatementAst.Right is CommandExpressionAst commandExpression
+ PSTypeName lastAssignedType = assignmentStatementAst.Right is CommandExpressionAst commandExpression
? GetInferredVarTypeFromAst(commandExpression.Expression)
: null;
- SaveVariableInfo(variableExpression.VariablePath.UserPath, lastAssignedType, isConstraint: false);
+ SaveVariableInfo(variableExpression.VariablePath.UnqualifiedPath, lastAssignedType, isConstraint: false);
}
}
}
@@ -5653,7 +5616,7 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a
return AstVisitAction.Continue;
}
- Type lastAssignedType;
+ PSTypeName lastAssignedType;
if (assignmentStatementAst.Right is CommandExpressionAst commandExpression)
{
lastAssignedType = GetInferredVarTypeFromAst(commandExpression.Expression);
@@ -5663,7 +5626,7 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a
lastAssignedType = null;
}
- SaveVariableInfo(variableExpression.VariablePath.UserPath, lastAssignedType, isConstraint: false);
+ SaveVariableInfo(variableExpression.VariablePath.UnqualifiedPath, lastAssignedType, isConstraint: false);
}
return AstVisitAction.Continue;
@@ -5686,7 +5649,7 @@ public override AstVisitAction VisitCommand(CommandAst commandAst)
var nameValue = variableName.ConstantValue as string;
if (nameValue is not null)
{
- Type variableType;
+ PSTypeName variableType;
if (bindingResult.BoundParameters.TryGetValue("Value", out ParameterBindingResult variableValue))
{
variableType = GetInferredVarTypeFromAst(variableValue.Value);
@@ -5711,7 +5674,7 @@ public override AstVisitAction VisitCommand(CommandAst commandAst)
var varName = outVarBind.ConstantValue as string;
if (varName is not null)
{
- SaveVariableInfo(varName, typeof(ArrayList), isConstraint: false);
+ SaveVariableInfo(varName, new PSTypeName(typeof(ArrayList)), isConstraint: false);
}
}
}
@@ -5726,9 +5689,9 @@ public override AstVisitAction VisitCommand(CommandAst commandAst)
if (varName is not null)
{
var inferredTypes = AstTypeInference.InferTypeOf(commandAst, Context, TypeInferenceRuntimePermissions.AllowSafeEval);
- Type varType = inferredTypes.Count == 0
+ PSTypeName varType = inferredTypes.Count == 0
? null
- : inferredTypes[0].Type;
+ : inferredTypes[0];
SaveVariableInfo(varName, varType, isConstraint: false);
}
}
@@ -5736,6 +5699,46 @@ public override AstVisitAction VisitCommand(CommandAst commandAst)
}
}
+ foreach (RedirectionAst redirection in commandAst.Redirections)
+ {
+ if (redirection is FileRedirectionAst fileRedirection
+ && fileRedirection.Location is StringConstantExpressionAst redirectTarget
+ && redirectTarget.Value.StartsWith("variable:", StringComparison.OrdinalIgnoreCase)
+ && redirectTarget.Value.Length > "variable:".Length)
+ {
+ string varName = redirectTarget.Value.Substring("variable:".Length);
+ PSTypeName varType;
+ switch (fileRedirection.FromStream)
+ {
+ case RedirectionStream.Error:
+ varType = new PSTypeName(typeof(ErrorRecord));
+ break;
+
+ case RedirectionStream.Warning:
+ varType = new PSTypeName(typeof(WarningRecord));
+ break;
+
+ case RedirectionStream.Verbose:
+ varType = new PSTypeName(typeof(VerboseRecord));
+ break;
+
+ case RedirectionStream.Debug:
+ varType = new PSTypeName(typeof(DebugRecord));
+ break;
+
+ case RedirectionStream.Information:
+ varType = new PSTypeName(typeof(InformationRecord));
+ break;
+
+ default:
+ varType = null;
+ break;
+ }
+
+ SaveVariableInfo(varName, varType, isConstraint: false);
+ }
+ }
+
return AstVisitAction.Continue;
}
@@ -5752,7 +5755,7 @@ public override AstVisitAction VisitParameter(ParameterAst parameterAst)
return AstVisitAction.Continue;
}
- SaveVariableInfo(variableExpression.VariablePath.UserPath, parameterAst.StaticType, isConstraint: true);
+ SaveVariableInfo(variableExpression.VariablePath.UnqualifiedPath, new PSTypeName(parameterAst.StaticType), isConstraint: true);
return AstVisitAction.Continue;
}
@@ -5764,7 +5767,7 @@ public override AstVisitAction VisitForEachStatement(ForEachStatementAst forEach
return AstVisitAction.StopVisit;
}
- SaveVariableInfo(forEachStatementAst.Variable.VariablePath.UserPath, variableType: null, isConstraint: false);
+ SaveVariableInfo(forEachStatementAst.Variable.VariablePath.UnqualifiedPath, variableType: null, isConstraint: false);
return AstVisitAction.Continue;
}
@@ -5824,7 +5827,7 @@ public override AstVisitAction VisitDataStatement(DataStatementAst dataStatement
}
}
- private static readonly Lazy> s_specialVariablesCache = new Lazy>(BuildSpecialVariablesCache);
+ private static readonly Lazy> s_specialVariablesCache = new(BuildSpecialVariablesCache);
private static SortedSet BuildSpecialVariablesCache()
{
@@ -5840,6 +5843,35 @@ private static SortedSet BuildSpecialVariablesCache()
return result;
}
+ internal static PSTypeName GetLastDeclaredTypeConstraint(VariableExpressionAst variableAst, TypeInferenceContext typeInferenceContext)
+ {
+ Ast parent = variableAst.Parent;
+ var findVariablesVisitor = new FindVariablesVisitor()
+ {
+ CompletionVariableAst = variableAst,
+ StopSearchOffset = variableAst.Extent.StartOffset,
+ Context = typeInferenceContext
+ };
+ while (parent != null)
+ {
+ if (parent is IParameterMetadataProvider)
+ {
+ findVariablesVisitor.Top = parent;
+ parent.Visit(findVariablesVisitor);
+ }
+
+ if (findVariablesVisitor.VariableInfoTable.TryGetValue(variableAst.VariablePath.UserPath, out VariableInfo varInfo)
+ && varInfo.LastDeclaredConstraint is not null)
+ {
+ return varInfo.LastDeclaredConstraint;
+ }
+
+ parent = parent.Parent;
+ }
+
+ return null;
+ }
+
#endregion Variables
#region Comments
@@ -5957,12 +5989,13 @@ private static List CompleteRequires(CompletionContext context
// Produce completions for all parameters that begin with the prefix we've found,
// but which haven't already been specified in the line we need to complete
- foreach (KeyValuePair parameter in s_requiresParameters)
+ foreach (string parameter in s_requiresParameters)
{
- if (parameter.Key.StartsWith(currentParameterPrefix, StringComparison.OrdinalIgnoreCase)
- && !context.CursorPosition.Line.Contains($" -{parameter.Key}", StringComparison.OrdinalIgnoreCase))
+ if (parameter.StartsWith(currentParameterPrefix, StringComparison.OrdinalIgnoreCase)
+ && !context.CursorPosition.Line.Contains($" -{parameter}", StringComparison.OrdinalIgnoreCase))
{
- results.Add(new CompletionResult(parameter.Key, parameter.Key, CompletionResultType.ParameterName, parameter.Value));
+ string toolTip = GetRequiresParametersToolTip(parameter);
+ results.Add(new CompletionResult(parameter, parameter, CompletionResultType.ParameterName, toolTip));
}
}
@@ -5987,11 +6020,12 @@ private static List CompleteRequires(CompletionContext context
// Complete PSEdition parameter values
if (currentParameterMatch.Value.Equals("PSEdition", StringComparison.OrdinalIgnoreCase))
{
- foreach (KeyValuePair psEditionEntry in s_requiresPSEditions)
+ foreach (string psEditionEntry in s_requiresPSEditions)
{
- if (psEditionEntry.Key.StartsWith(currentValue, StringComparison.OrdinalIgnoreCase))
+ if (psEditionEntry.StartsWith(currentValue, StringComparison.OrdinalIgnoreCase))
{
- results.Add(new CompletionResult(psEditionEntry.Key, psEditionEntry.Key, CompletionResultType.ParameterValue, psEditionEntry.Value));
+ string toolTip = GetRequiresPsEditionsToolTip(psEditionEntry);
+ results.Add(new CompletionResult(psEditionEntry, psEditionEntry, CompletionResultType.ParameterValue, toolTip));
}
}
@@ -6019,7 +6053,7 @@ private static List CompleteRequires(CompletionContext context
hashtableKeyMatches = Regex.Matches(hashtableString, @"(@{|;)\s*(?:'|\""|\w*)\w*");
// Build the list of keys we might want to complete, based on what's already been provided
- var moduleSpecKeysToComplete = new HashSet(s_requiresModuleSpecKeys.Keys);
+ var moduleSpecKeysToComplete = new HashSet(s_requiresModuleSpecKeys);
bool sawModuleNameLast = false;
foreach (Match existingHashtableKeyMatch in hashtableKeyMatches)
{
@@ -6075,7 +6109,8 @@ private static List CompleteRequires(CompletionContext context
{
if (moduleSpecKey.StartsWith(currentValue, StringComparison.OrdinalIgnoreCase))
{
- results.Add(new CompletionResult(moduleSpecKey, moduleSpecKey, CompletionResultType.ParameterValue, s_requiresModuleSpecKeys[moduleSpecKey]));
+ string toolTip = GetRequiresModuleSpecKeysToolTip(moduleSpecKey);
+ results.Add(new CompletionResult(moduleSpecKey, moduleSpecKey, CompletionResultType.ParameterValue, toolTip));
}
}
}
@@ -6083,27 +6118,53 @@ private static List CompleteRequires(CompletionContext context
return results;
}
- private static readonly IReadOnlyDictionary s_requiresParameters = new SortedList(StringComparer.OrdinalIgnoreCase)
+ private static readonly string[] s_requiresParameters = new string[]
+ {
+ "Modules",
+ "PSEdition",
+ "RunAsAdministrator",
+ "Version"
+ };
+
+ private static string GetRequiresParametersToolTip(string name) => name switch
{
- { "Modules", "Specifies PowerShell modules that the script requires." },
- { "PSEdition", "Specifies a PowerShell edition that the script requires." },
- { "RunAsAdministrator", "Specifies that PowerShell must be running as administrator on Windows." },
- { "Version", "Specifies the minimum version of PowerShell that the script requires." },
+ "Modules" => TabCompletionStrings.RequiresModulesParameterDescription,
+ "PSEdition" => TabCompletionStrings.RequiresPSEditionParameterDescription,
+ "RunAsAdministrator" => TabCompletionStrings.RequiresRunAsAdministratorParameterDescription,
+ "Version" => TabCompletionStrings.RequiresVersionParameterDescription,
+ _ => string.Empty
};
- private static readonly IReadOnlyDictionary s_requiresPSEditions = new SortedList(StringComparer.OrdinalIgnoreCase)
+ private static readonly string[] s_requiresPSEditions = new string[]
{
- { "Core", "Specifies that the script requires PowerShell Core to run." },
- { "Desktop", "Specifies that the script requires Windows PowerShell to run." },
+ "Core",
+ "Desktop"
};
- private static readonly IReadOnlyDictionary s_requiresModuleSpecKeys = new SortedList(StringComparer.OrdinalIgnoreCase)
+ private static string GetRequiresPsEditionsToolTip(string name) => name switch
{
- { "ModuleName", "Required. Specifies the module name." },
- { "GUID", "Optional. Specifies the GUID of the module." },
- { "ModuleVersion", "Specifies a minimum acceptable version of the module." },
- { "RequiredVersion", "Specifies an exact, required version of the module." },
- { "MaximumVersion", "Specifies the maximum acceptable version of the module." },
+ "Core" => TabCompletionStrings.RequiresPsEditionCoreDescription,
+ "Desktop" => TabCompletionStrings.RequiresPsEditionDesktopDescription,
+ _ => string.Empty
+ };
+
+ private static readonly string[] s_requiresModuleSpecKeys = new string[]
+ {
+ "GUID",
+ "MaximumVersion",
+ "ModuleName",
+ "ModuleVersion",
+ "RequiredVersion"
+ };
+
+ private static string GetRequiresModuleSpecKeysToolTip(string name) => name switch
+ {
+ "GUID" => TabCompletionStrings.RequiresModuleSpecGUIDDescription,
+ "MaximumVersion" => TabCompletionStrings.RequiresModuleSpecMaximumVersionDescription,
+ "ModuleName" => TabCompletionStrings.RequiresModuleSpecModuleNameDescription,
+ "ModuleVersion" => TabCompletionStrings.RequiresModuleSpecModuleVersionDescription,
+ "RequiredVersion" => TabCompletionStrings.RequiresModuleSpecRequiredVersionDescription,
+ _ => string.Empty
};
private static readonly char[] s_hashtableKeyPrefixes = new[]
@@ -6148,7 +6209,7 @@ private static List CompleteCommentHelp(CompletionContext cont
replacementIndex = context.TokenAtCursor.Extent.StartOffset + lineKeyword.Index;
replacementLength = lineKeyword.Value.Length;
- var validKeywords = new HashSet(s_commentHelpKeywords.Keys, StringComparer.OrdinalIgnoreCase);
+ var validKeywords = new HashSet(s_commentHelpKeywords, StringComparer.OrdinalIgnoreCase);
foreach (Match keyword in usedKeywords)
{
if (keyword == lineKeyword || s_commentHelpAllowedDuplicateKeywords.Contains(keyword.Value))
@@ -6164,7 +6225,8 @@ private static List CompleteCommentHelp(CompletionContext cont
{
if (keyword.StartsWith(lineKeyword.Value, StringComparison.OrdinalIgnoreCase))
{
- result.Add(new CompletionResult(keyword, keyword, CompletionResultType.Keyword, s_commentHelpKeywords[keyword]));
+ string toolTip = GetCommentHelpKeywordsToolTip(keyword);
+ result.Add(new CompletionResult(keyword, keyword, CompletionResultType.Keyword, toolTip));
}
}
@@ -6224,46 +6286,66 @@ private static List CompleteCommentHelp(CompletionContext cont
return null;
}
- private static readonly IReadOnlyDictionary s_commentHelpKeywords = new SortedList(StringComparer.OrdinalIgnoreCase)
- {
- { "SYNOPSIS", "A brief description of the function or script. This keyword can be used only once in each topic." },
- { "DESCRIPTION", "A detailed description of the function or script. This keyword can be used only once in each topic." },
- { "PARAMETER", ".PARAMETER \nThe description of a parameter. Add a .PARAMETER keyword for each parameter in the function or script syntax." },
- { "EXAMPLE", "A sample command that uses the function or script, optionally followed by sample output and a description. Repeat this keyword for each example." },
- { "INPUTS", "The .NET types of objects that can be piped to the function or script. You can also include a description of the input objects." },
- { "OUTPUTS", "The .NET type of the objects that the cmdlet returns. You can also include a description of the returned objects." },
- { "NOTES", "Additional information about the function or script." },
- { "LINK", "The name of a related topic. Repeat the .LINK keyword for each related topic. The .Link keyword content can also include a URI to an online version of the same help topic." },
- { "COMPONENT", "The name of the technology or feature that the function or script uses, or to which it is related." },
- { "ROLE", "The name of the user role for the help topic." },
- { "FUNCTIONALITY", "The keywords that describe the intended use of the function." },
- { "FORWARDHELPTARGETNAME", ".FORWARDHELPTARGETNAME \nRedirects to the help topic for the specified command." },
- { "FORWARDHELPCATEGORY", ".FORWARDHELPCATEGORY \nSpecifies the help category of the item in .ForwardHelpTargetName" },
- { "REMOTEHELPRUNSPACE", ".REMOTEHELPRUNSPACE \nSpecifies a session that contains the help topic. Enter a variable that contains a PSSession object." },
- { "EXTERNALHELP", ".EXTERNALHELP \nThe .ExternalHelp keyword is required when a function or script is documented in XML files." }
+ private static readonly string[] s_commentHelpKeywords = new string[]
+ {
+ "COMPONENT",
+ "DESCRIPTION",
+ "EXAMPLE",
+ "EXTERNALHELP",
+ "FORWARDHELPCATEGORY",
+ "FORWARDHELPTARGETNAME",
+ "FUNCTIONALITY",
+ "INPUTS",
+ "LINK",
+ "NOTES",
+ "OUTPUTS",
+ "PARAMETER",
+ "REMOTEHELPRUNSPACE",
+ "ROLE",
+ "SYNOPSIS"
+ };
+
+ private static string GetCommentHelpKeywordsToolTip(string name) => name switch
+ {
+ "COMPONENT" => TabCompletionStrings.CommentHelpCOMPONENTKeywordDescription,
+ "DESCRIPTION" => TabCompletionStrings.CommentHelpDESCRIPTIONKeywordDescription,
+ "EXAMPLE" => TabCompletionStrings.CommentHelpEXAMPLEKeywordDescription,
+ "EXTERNALHELP" => TabCompletionStrings.CommentHelpEXTERNALHELPKeywordDescription,
+ "FORWARDHELPCATEGORY" => TabCompletionStrings.CommentHelpFORWARDHELPCATEGORYKeywordDescription,
+ "FORWARDHELPTARGETNAME" => TabCompletionStrings.CommentHelpFORWARDHELPTARGETNAMEKeywordDescription,
+ "FUNCTIONALITY" => TabCompletionStrings.CommentHelpFUNCTIONALITYKeywordDescription,
+ "INPUTS" => TabCompletionStrings.CommentHelpINPUTSKeywordDescription,
+ "LINK" => TabCompletionStrings.CommentHelpLINKKeywordDescription,
+ "NOTES" => TabCompletionStrings.CommentHelpNOTESKeywordDescription,
+ "OUTPUTS" => TabCompletionStrings.CommentHelpOUTPUTSKeywordDescription,
+ "PARAMETER" => TabCompletionStrings.CommentHelpPARAMETERKeywordDescription,
+ "REMOTEHELPRUNSPACE" => TabCompletionStrings.CommentHelpREMOTEHELPRUNSPACEKeywordDescription,
+ "ROLE" => TabCompletionStrings.CommentHelpROLEKeywordDescription,
+ "SYNOPSIS" => TabCompletionStrings.CommentHelpSYNOPSISKeywordDescription,
+ _ => string.Empty
};
private static readonly HashSet s_commentHelpAllowedDuplicateKeywords = new(StringComparer.OrdinalIgnoreCase)
{
- "PARAMETER",
"EXAMPLE",
- "LINK"
+ "LINK",
+ "PARAMETER"
};
private static readonly string[] s_commentHelpForwardCategories = new string[]
{
"Alias",
+ "All",
"Cmdlet",
- "HelpFile",
+ "ExternalScript",
+ "FAQ",
+ "Filter",
"Function",
- "Provider",
"General",
- "FAQ",
"Glossary",
- "ScriptCommand",
- "ExternalScript",
- "Filter",
- "All"
+ "HelpFile",
+ "Provider",
+ "ScriptCommand"
};
private static FunctionDefinitionAst GetCommentHelpFunctionTarget(CompletionContext context)
@@ -6779,7 +6861,7 @@ private static void CompleteFormatViewByInferredType(CompletionContext context,
Diagnostics.Assert(controlBodyType is not null, "This should never happen unless a new Format-* cmdlet is added");
var wordToComplete = context.WordToComplete;
- var quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
WildcardPattern viewPattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
var uniqueNames = new HashSet();
@@ -7698,44 +7780,34 @@ private static string GetNamespaceToRemove(CompletionContext context, TypeComple
internal static List CompleteHelpTopics(CompletionContext context)
{
- var results = new List();
- string userHelpDir = HelpUtils.GetUserHomeHelpSearchPath();
- string appHelpDir = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID);
- string currentCulture = CultureInfo.CurrentCulture.Name;
-
- //search for help files for the current culture + en-US as fallback
- var searchPaths = new string[]
+ ArrayList helpProviders = context.ExecutionContext.HelpSystem.HelpProviders;
+ HelpFileHelpProvider helpFileProvider = null;
+ for (int i = helpProviders.Count - 1; i >= 0; i--)
{
- Path.Combine(userHelpDir, currentCulture),
- Path.Combine(appHelpDir, currentCulture),
- Path.Combine(userHelpDir, "en-US"),
- Path.Combine(appHelpDir, "en-US")
- }.Distinct();
+ if (helpProviders[i] is HelpFileHelpProvider provider)
+ {
+ helpFileProvider = provider;
+ break;
+ }
+ }
- string wordToComplete = context.WordToComplete + "*";
- try
+ if (helpFileProvider is null)
{
- var wildcardPattern = WildcardPattern.Get(wordToComplete, WildcardOptions.IgnoreCase);
+ return null;
+ }
- foreach (var dir in searchPaths)
+ List results = new();
+ Collection filesMatched = MUIFileSearcher.SearchFiles($"{context.WordToComplete}*.help.txt", helpFileProvider.GetExtendedSearchPaths());
+ foreach (string path in filesMatched)
+ {
+ string fileName = Path.GetFileName(path);
+ if (fileName.StartsWith("about_", StringComparison.OrdinalIgnoreCase))
{
- var currentDir = new DirectoryInfo(dir);
- if (currentDir.Exists)
- {
- foreach (var file in currentDir.EnumerateFiles("about_*.help.txt"))
- {
- if (wildcardPattern.IsMatch(file.Name))
- {
- string topicName = file.Name.Substring(0, file.Name.LastIndexOf(".help.txt"));
- results.Add(new CompletionResult(topicName));
- }
- }
- }
+ string topicName = fileName.Substring(0, fileName.Length - ".help.txt".Length);
+ results.Add(new CompletionResult(topicName, topicName, CompletionResultType.ParameterValue, topicName));
}
}
- catch (Exception)
- {
- }
+
return results;
}
@@ -8044,7 +8116,7 @@ internal static List CompleteHashtableKey(CompletionContext co
}
var result = new List();
- foreach (var key in s_requiresModuleSpecKeys.Keys)
+ foreach (string key in s_requiresModuleSpecKeys)
{
if (excludedKeys.Contains(key)
|| (wordToComplete is not null && !key.StartsWith(wordToComplete, StringComparison.OrdinalIgnoreCase))
@@ -8053,7 +8125,10 @@ internal static List CompleteHashtableKey(CompletionContext co
{
continue;
}
- result.Add(new CompletionResult(key, key, CompletionResultType.Property, s_requiresModuleSpecKeys[key]));
+
+ string toolTip = GetRequiresModuleSpecKeysToolTip(key);
+
+ result.Add(new CompletionResult(key, key, CompletionResultType.Property, toolTip));
}
return result;
@@ -8305,7 +8380,9 @@ private static List GetSpecialHashTableKeyMembers(HashSet GetSpecialHashTableKeyMembers(HashSet name switch
+ {
+ "Alignment" => TabCompletionStrings.AlignmentHashtableKeyDescription,
+ "Ascending" => TabCompletionStrings.AscendingHashtableKeyDescription,
+ "Data" => TabCompletionStrings.DataHashtableKeyDescription,
+ "Depth" => TabCompletionStrings.DepthHashtableKeyDescription,
+ "Descending" => TabCompletionStrings.DescendingHashtableKeyDescription,
+ "EndTime" => TabCompletionStrings.EndTimeHashtableKeyDescription,
+ "Expression" => TabCompletionStrings.ExpressionHashtableKeyDescription,
+ "FormatString" => TabCompletionStrings.FormatStringHashtableKeyDescription,
+ "ID" => TabCompletionStrings.IDHashtableKeyDescription,
+ "Keywords" => TabCompletionStrings.KeywordsHashtableKeyDescription,
+ "Label" => TabCompletionStrings.LabelHashtableKeyDescription,
+ "Level" => TabCompletionStrings.LevelHashtableKeyDescription,
+ "LogName" => TabCompletionStrings.LogNameHashtableKeyDescription,
+ "Name" => TabCompletionStrings.NameHashtableKeyDescription,
+ "Path" => TabCompletionStrings.PathHashtableKeyDescription,
+ "ProviderName" => TabCompletionStrings.ProviderNameHashtableKeyDescription,
+ "StartTime" => TabCompletionStrings.StartTimeHashtableKeyDescription,
+ "SuppressHashFilter" => TabCompletionStrings.SuppressHashFilterHashtableKeyDescription,
+ "UserID" => TabCompletionStrings.UserIDHashtableKeyDescription,
+ "Width" => TabCompletionStrings.WidthHashtableKeyDescription,
+ _ => string.Empty
+ };
+
#endregion Hashtable Keys
#region Helpers
@@ -8397,77 +8499,6 @@ internal static string CombineVariableWithPartialPath(VariableExpressionAst vari
return null;
}
- internal static string HandleDoubleAndSingleQuote(ref string wordToComplete)
- {
- string quote = string.Empty;
-
- if (!string.IsNullOrEmpty(wordToComplete) && (wordToComplete[0].IsSingleQuote() || wordToComplete[0].IsDoubleQuote()))
- {
- char frontQuote = wordToComplete[0];
- int length = wordToComplete.Length;
-
- if (length == 1)
- {
- wordToComplete = string.Empty;
- quote = frontQuote.IsSingleQuote() ? "'" : "\"";
- }
- else if (length > 1)
- {
- if ((wordToComplete[length - 1].IsDoubleQuote() && frontQuote.IsDoubleQuote()) || (wordToComplete[length - 1].IsSingleQuote() && frontQuote.IsSingleQuote()))
- {
- wordToComplete = wordToComplete.Substring(1, length - 2);
- quote = frontQuote.IsSingleQuote() ? "'" : "\"";
- }
- else if (!wordToComplete[length - 1].IsDoubleQuote() && !wordToComplete[length - 1].IsSingleQuote())
- {
- wordToComplete = wordToComplete.Substring(1);
- quote = frontQuote.IsSingleQuote() ? "'" : "\"";
- }
- }
- }
-
- return quote;
- }
-
- ///
- /// Get matching completions from word to complete.
- /// This makes it easier to handle different variations of completions with consideration of quotes.
- ///
- /// The word to complete.
- /// The possible completion values to iterate.
- /// The optional tool tip mapping delegate.
- /// The optional completion result type. Default is Text.
- ///
- internal static IEnumerable GetMatchingResults(
- string wordToComplete,
- IEnumerable possibleCompletionValues,
- Func toolTipMapping = null,
- CompletionResultType resultType = CompletionResultType.Text)
- {
- string quote = HandleDoubleAndSingleQuote(ref wordToComplete);
- var pattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
-
- foreach (string value in possibleCompletionValues)
- {
- if (pattern.IsMatch(value))
- {
- string completionText = quote == string.Empty
- ? value
- : quote + value + quote;
-
- string listItemText = value;
-
- yield return new CompletionResult(
- completionText,
- listItemText,
- resultType,
- toolTip: toolTipMapping is null
- ? listItemText
- : toolTipMapping(value));
- }
- }
- }
-
///
/// Calls Get-Command to get command info objects.
///
@@ -8665,33 +8696,6 @@ private static bool IsStaticTypeEnumerable(Type type)
return false;
}
- private static readonly SearchValues s_defaultCharsToCheck = SearchValues.Create("$`");
- private static readonly SearchValues s_escapeCharsToCheck = SearchValues.Create("$[]`");
-
- private static bool ContainsCharsToCheck(ReadOnlySpan text, bool escape)
- => text.ContainsAny(escape ? s_escapeCharsToCheck : s_defaultCharsToCheck);
-
- private static bool CompletionRequiresQuotes(string completion, bool escape)
- {
- // If the tokenizer sees the completion as more than two tokens, or if there is some error, then
- // some form of quoting is necessary (if it's a variable, we'd need ${}, filenames would need [], etc.)
-
- Language.Token[] tokens;
- ParseError[] errors;
- Language.Parser.ParseInput(completion, out tokens, out errors);
-
- // Expect no errors and 2 tokens (1 is for our completion, the other is eof)
- // Or if the completion is a keyword, we ignore the errors
- bool requireQuote = !(errors.Length == 0 && tokens.Length == 2);
- if ((!requireQuote && tokens[0] is StringToken) ||
- (tokens.Length == 2 && (tokens[0].TokenFlags & TokenFlags.Keyword) != 0))
- {
- requireQuote = ContainsCharsToCheck(tokens[0].Text, escape);
- }
-
- return requireQuote;
- }
-
private static bool ProviderSpecified(string path)
{
var index = path.IndexOf(':');
diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionHelpers.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionHelpers.cs
new file mode 100644
index 00000000000..bd44185b460
--- /dev/null
+++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionHelpers.cs
@@ -0,0 +1,183 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Buffers;
+using System.Collections.Generic;
+using System.Management.Automation.Language;
+
+namespace System.Management.Automation
+{
+ ///
+ /// Shared helper class for common completion helper methods.
+ ///
+ internal static class CompletionHelpers
+ {
+ private static readonly SearchValues s_defaultCharsToCheck = SearchValues.Create("$`");
+
+ ///
+ /// Get matching completions from word to complete.
+ /// This makes it easier to handle different variations of completions with consideration of quotes.
+ ///
+ /// The word to complete.
+ /// The possible completion values to iterate.
+ /// The optional tool tip mapping delegate.
+ /// The optional completion result type. Default is Text.
+ ///
+ internal static IEnumerable GetMatchingResults(
+ string wordToComplete,
+ IEnumerable possibleCompletionValues,
+ Func toolTipMapping = null,
+ CompletionResultType resultType = CompletionResultType.Text)
+ {
+ string quote = HandleDoubleAndSingleQuote(ref wordToComplete);
+ var pattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
+
+ foreach (string value in possibleCompletionValues)
+ {
+ if (pattern.IsMatch(value))
+ {
+ string completionText = QuoteCompletionText(value, quote);
+
+ string listItemText = value;
+
+ yield return new CompletionResult(
+ completionText,
+ listItemText,
+ resultType,
+ toolTip: toolTipMapping is null
+ ? listItemText
+ : toolTipMapping(value));
+ }
+ }
+ }
+
+ ///
+ /// Removes wrapping quotes from a string and returns the quote used, if present.
+ ///
+ ///
+ /// The string to process, potentially surrounded by single or double quotes.
+ /// This parameter is updated in-place to exclude the removed quotes.
+ ///
+ ///
+ /// The type of quote detected (single or double), or an empty string if no quote is found.
+ ///
+ ///
+ /// This method checks for single or double quotes at the start and end of the string.
+ /// If wrapping quotes are detected and match, both are removed; otherwise, only the front quote is removed.
+ /// The string is updated in-place, and only matching front-and-back quotes are stripped.
+ /// If no quotes are detected or the input is empty, the original string remains unchanged.
+ ///
+ internal static string HandleDoubleAndSingleQuote(ref string wordToComplete)
+ {
+ if (string.IsNullOrEmpty(wordToComplete))
+ {
+ return string.Empty;
+ }
+
+ char frontQuote = wordToComplete[0];
+ bool hasFrontSingleQuote = frontQuote.IsSingleQuote();
+ bool hasFrontDoubleQuote = frontQuote.IsDoubleQuote();
+
+ if (!hasFrontSingleQuote && !hasFrontDoubleQuote)
+ {
+ return string.Empty;
+ }
+
+ string quoteInUse = hasFrontSingleQuote ? "'" : "\"";
+
+ int length = wordToComplete.Length;
+ if (length == 1)
+ {
+ wordToComplete = string.Empty;
+ return quoteInUse;
+ }
+
+ char backQuote = wordToComplete[length - 1];
+ bool hasBackSingleQuote = backQuote.IsSingleQuote();
+ bool hasBackDoubleQuote = backQuote.IsDoubleQuote();
+
+ bool hasBothFrontAndBackQuotes =
+ (hasFrontSingleQuote && hasBackSingleQuote) || (hasFrontDoubleQuote && hasBackDoubleQuote);
+
+ if (hasBothFrontAndBackQuotes)
+ {
+ wordToComplete = wordToComplete.Substring(1, length - 2);
+ return quoteInUse;
+ }
+
+ bool hasFrontQuoteAndNoBackQuote =
+ (hasFrontSingleQuote || hasFrontDoubleQuote) && !hasBackSingleQuote && !hasBackDoubleQuote;
+
+ if (hasFrontQuoteAndNoBackQuote)
+ {
+ wordToComplete = wordToComplete.Substring(1);
+ return quoteInUse;
+ }
+
+ return string.Empty;
+ }
+
+ ///
+ /// Determines whether the specified completion string requires quotes.
+ /// Quoting is required if:
+ ///
+ /// There are parsing errors in the input string.
+ /// The parsed token count is not exactly two (the input token + EOF).
+ /// The first token is a string or a PowerShell keyword containing special characters.
+ ///
+ ///
+ /// The input string to analyze for quoting requirements.
+ /// true if the string requires quotes, false otherwise.
+ internal static bool CompletionRequiresQuotes(string completion)
+ {
+ Parser.ParseInput(completion, out Token[] tokens, out ParseError[] errors);
+
+ bool isExpectedTokenCount = tokens.Length == 2;
+
+ bool requireQuote = errors.Length > 0 || !isExpectedTokenCount;
+
+ Token firstToken = tokens[0];
+ bool isStringToken = firstToken is StringToken;
+ bool isKeywordToken = (firstToken.TokenFlags & TokenFlags.Keyword) != 0;
+
+ if ((!requireQuote && isStringToken) || (isExpectedTokenCount && isKeywordToken))
+ {
+ requireQuote = ContainsCharsToCheck(firstToken.Text);
+ }
+
+ return requireQuote;
+ }
+
+ private static bool ContainsCharsToCheck(ReadOnlySpan text)
+ => text.ContainsAny(s_defaultCharsToCheck);
+
+ ///
+ /// Quotes a given completion text.
+ ///
+ ///
+ /// The text to be quoted.
+ ///
+ ///
+ /// The quote character to use for enclosing the text. Defaults to a single quote if not provided.
+ ///
+ ///
+ /// The quoted .
+ ///
+ internal static string QuoteCompletionText(string completionText, string quote)
+ {
+ if (!CompletionRequiresQuotes(completionText))
+ {
+ return quote + completionText + quote;
+ }
+
+ string quoteInUse = string.IsNullOrEmpty(quote) ? "'" : quote;
+
+ if (quoteInUse == "'")
+ {
+ completionText = CodeGeneration.EscapeSingleQuotedStringContent(completionText);
+ }
+
+ return quoteInUse + completionText + quoteInUse;
+ }
+ }
+}
diff --git a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs
index 4201be16f93..2e7457cd812 100644
--- a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs
+++ b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs
@@ -1198,7 +1198,7 @@ private bool PrepareCommandElements(ExecutionContext context, CommandParameterAs
string commandName = null;
try
{
- processor = PrepareFromAst(context, out commandName) ?? context.CreateCommand(commandName, dotSource);
+ processor = PrepareFromAst(context, out commandName) ?? context.CreateCommand(commandName, dotSource, forCompletion:true);
}
catch (RuntimeException)
{
@@ -1406,7 +1406,6 @@ private CommandProcessorBase PrepareFromAst(ExecutionContext context, out string
}
ast.Visit(exportVisitor);
-
CommandProcessorBase commandProcessor = null;
resolvedCommandName = _commandAst.GetCommandName();
diff --git a/src/System.Management.Automation/engine/CommandCompletion/ScopeArgumentCompleter.cs b/src/System.Management.Automation/engine/CommandCompletion/ScopeArgumentCompleter.cs
index 8e233bc31ca..444ccf79adb 100644
--- a/src/System.Management.Automation/engine/CommandCompletion/ScopeArgumentCompleter.cs
+++ b/src/System.Management.Automation/engine/CommandCompletion/ScopeArgumentCompleter.cs
@@ -29,7 +29,7 @@ public IEnumerable CompleteArgument(
string wordToComplete,
CommandAst commandAst,
IDictionary fakeBoundParameters)
- => CompletionCompleters.GetMatchingResults(
+ => CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: s_Scopes);
}
diff --git a/src/System.Management.Automation/engine/CommandDiscovery.cs b/src/System.Management.Automation/engine/CommandDiscovery.cs
index 561a33ccba8..cf4f561c983 100644
--- a/src/System.Management.Automation/engine/CommandDiscovery.cs
+++ b/src/System.Management.Automation/engine/CommandDiscovery.cs
@@ -262,6 +262,9 @@ internal void AddSessionStateCmdletEntryToCache(SessionStateCmdletEntry entry, b
/// False if not. Null if command discovery should default to something reasonable
/// for the command discovered.
///
+ ///
+ /// True if this for parameter completion and script requirements should be ignored.
+ ///
///
///
///
@@ -271,14 +274,15 @@ internal void AddSessionStateCmdletEntryToCache(SessionStateCmdletEntry entry, b
/// If the security manager is preventing the command from running.
///
internal CommandProcessorBase LookupCommandProcessor(string commandName,
- CommandOrigin commandOrigin, bool? useLocalScope)
+ CommandOrigin commandOrigin, bool? useLocalScope, bool forCompletion = false)
{
CommandProcessorBase processor = null;
CommandInfo commandInfo = LookupCommandInfo(commandName, commandOrigin);
if (commandInfo != null)
{
- processor = LookupCommandProcessor(commandInfo, commandOrigin, useLocalScope, null);
+ processor = LookupCommandProcessor(commandInfo, commandOrigin, useLocalScope, null, forCompletion);
+
// commandInfo.Name might be different than commandName - restore the original invocation name
processor.Command.MyInvocation.InvocationName = commandName;
}
@@ -286,7 +290,7 @@ internal CommandProcessorBase LookupCommandProcessor(string commandName,
return processor;
}
- internal static void VerifyRequiredModules(ExternalScriptInfo scriptInfo, ExecutionContext context)
+ internal static void VerifyRequiredModules(ExternalScriptInfo scriptInfo, ExecutionContext context, bool forCompletion = false)
{
// Check Required Modules
if (scriptInfo.RequiresModules != null)
@@ -301,7 +305,7 @@ internal static void VerifyRequiredModules(ExternalScriptInfo scriptInfo, Execut
moduleManifestPath: null,
manifestProcessingFlags: ModuleCmdletBase.ManifestProcessingFlags.LoadElements | ModuleCmdletBase.ManifestProcessingFlags.WriteErrors,
error: out error);
- if (error != null)
+ if (!forCompletion && error is not null)
{
ScriptRequiresException scriptRequiresException =
new ScriptRequiresException(
@@ -316,9 +320,9 @@ internal static void VerifyRequiredModules(ExternalScriptInfo scriptInfo, Execut
}
}
- private CommandProcessorBase CreateScriptProcessorForSingleShell(ExternalScriptInfo scriptInfo, ExecutionContext context, bool useLocalScope, SessionStateInternal sessionState)
+ private CommandProcessorBase CreateScriptProcessorForSingleShell(ExternalScriptInfo scriptInfo, ExecutionContext context, bool useLocalScope, SessionStateInternal sessionState, bool forCompletion = false)
{
- VerifyScriptRequirements(scriptInfo, Context);
+ VerifyScriptRequirements(scriptInfo, Context, forCompletion);
if (!string.IsNullOrEmpty(scriptInfo.RequiresApplicationID))
{
@@ -340,12 +344,18 @@ private CommandProcessorBase CreateScriptProcessorForSingleShell(ExternalScriptI
// #Requires -PSVersion
// #Requires -PSEdition
// #Requires -Module
- internal static void VerifyScriptRequirements(ExternalScriptInfo scriptInfo, ExecutionContext context)
+ internal static void VerifyScriptRequirements(ExternalScriptInfo scriptInfo, ExecutionContext context, bool forCompletion = false)
{
- VerifyElevatedPrivileges(scriptInfo);
- VerifyPSVersion(scriptInfo);
- VerifyPSEdition(scriptInfo);
- VerifyRequiredModules(scriptInfo, context);
+ // When completing script parameters we don't care if these requirements are met.
+ // VerifyRequiredModules will attempt to load the required modules which is useful for completion (so the correct types are loaded).
+ if (!forCompletion)
+ {
+ VerifyElevatedPrivileges(scriptInfo);
+ VerifyPSVersion(scriptInfo);
+ VerifyPSEdition(scriptInfo);
+ }
+
+ VerifyRequiredModules(scriptInfo, context, forCompletion);
}
internal static void VerifyPSVersion(ExternalScriptInfo scriptInfo)
@@ -426,6 +436,9 @@ internal static void VerifyElevatedPrivileges(ExternalScriptInfo scriptInfo)
/// False if not. Null if command discovery should default to something reasonable
/// for the command discovered.
///
+ ///
+ /// True if this for parameter completion and script requirements should be ignored.
+ ///
/// The session state the commandInfo should be run in.
///
///
@@ -436,7 +449,7 @@ internal static void VerifyElevatedPrivileges(ExternalScriptInfo scriptInfo)
/// If the security manager is preventing the command from running.
///
internal CommandProcessorBase LookupCommandProcessor(CommandInfo commandInfo,
- CommandOrigin commandOrigin, bool? useLocalScope, SessionStateInternal sessionState)
+ CommandOrigin commandOrigin, bool? useLocalScope, SessionStateInternal sessionState, bool forCompletion = false)
{
CommandProcessorBase processor = null;
@@ -482,7 +495,7 @@ internal CommandProcessorBase LookupCommandProcessor(CommandInfo commandInfo,
scriptInfo.SignatureChecked = true;
try
{
- processor = CreateScriptProcessorForSingleShell(scriptInfo, Context, useLocalScope ?? true, sessionState);
+ processor = CreateScriptProcessorForSingleShell(scriptInfo, Context, useLocalScope ?? true, sessionState, forCompletion);
}
catch (ScriptRequiresSyntaxException reqSyntaxException)
{
diff --git a/src/System.Management.Automation/engine/ExecutionContext.cs b/src/System.Management.Automation/engine/ExecutionContext.cs
index 56f64c1a5c2..16f2dbcc218 100644
--- a/src/System.Management.Automation/engine/ExecutionContext.cs
+++ b/src/System.Management.Automation/engine/ExecutionContext.cs
@@ -477,7 +477,6 @@ internal LocationGlobber LocationGlobber
/// The assemblies that have been loaded for this runspace.
///
internal Dictionary AssemblyCache { get; private set; }
-
#endregion Properties
#region Engine State
@@ -634,12 +633,13 @@ internal HelpSystem HelpSystem
///
/// The name of the command to lookup.
///
+ ///
/// The command processor object.
- internal CommandProcessorBase CreateCommand(string command, bool dotSource)
+ internal CommandProcessorBase CreateCommand(string command, bool dotSource, bool forCompletion = false)
{
CommandOrigin commandOrigin = this.EngineSessionState.CurrentScope.ScopeOrigin;
CommandProcessorBase commandProcessor =
- CommandDiscovery.LookupCommandProcessor(command, commandOrigin, !dotSource);
+ CommandDiscovery.LookupCommandProcessor(command, commandOrigin, !dotSource, forCompletion);
// Reset the command origin for script commands... // BUGBUG - dotting can get around command origin checks???
if (commandProcessor != null && commandProcessor is ScriptCommandProcessorBase)
{
diff --git a/src/System.Management.Automation/engine/ExperimentalFeature/EnableDisableExperimentalFeatureCommand.cs b/src/System.Management.Automation/engine/ExperimentalFeature/EnableDisableExperimentalFeatureCommand.cs
index 6e6a2cb81ff..af09f427253 100644
--- a/src/System.Management.Automation/engine/ExperimentalFeature/EnableDisableExperimentalFeatureCommand.cs
+++ b/src/System.Management.Automation/engine/ExperimentalFeature/EnableDisableExperimentalFeatureCommand.cs
@@ -127,7 +127,7 @@ public IEnumerable CompleteArgument(
expirmentalFeatures.Add(feature.Name);
}
- return CompletionCompleters.GetMatchingResults(wordToComplete, expirmentalFeatures);
+ return CompletionHelpers.GetMatchingResults(wordToComplete, expirmentalFeatures);
}
private static Collection GetExperimentalFeatures()
diff --git a/src/System.Management.Automation/engine/GetCommandCommand.cs b/src/System.Management.Automation/engine/GetCommandCommand.cs
index 9f96c0196e1..2ecf19ccaa9 100644
--- a/src/System.Management.Automation/engine/GetCommandCommand.cs
+++ b/src/System.Management.Automation/engine/GetCommandCommand.cs
@@ -1712,7 +1712,7 @@ public IEnumerable CompleteArgument(
string parameterName,
string wordToComplete,
CommandAst commandAst,
- IDictionary fakeBoundParameters) => CompletionCompleters.GetMatchingResults(
+ IDictionary fakeBoundParameters) => CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: GetCommandNouns(fakeBoundParameters));
diff --git a/src/System.Management.Automation/engine/InternalCommands.cs b/src/System.Management.Automation/engine/InternalCommands.cs
index 49bcabddafb..39556db9cca 100644
--- a/src/System.Management.Automation/engine/InternalCommands.cs
+++ b/src/System.Management.Automation/engine/InternalCommands.cs
@@ -2741,7 +2741,7 @@ public IEnumerable CompleteArgument(
string wordToComplete,
CommandAst commandAst,
IDictionary fakeBoundParameters)
- => CompletionCompleters.GetMatchingResults(
+ => CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: s_strictModeVersions);
}
diff --git a/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs b/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs
index 1055a45130f..ca48c5c698c 100644
--- a/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs
+++ b/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs
@@ -605,6 +605,6 @@ public IEnumerable CompleteArgument(
string wordToComplete,
CommandAst commandAst,
IDictionary fakeBoundParameters)
- => CompletionCompleters.GetMatchingResults(wordToComplete, possibleCompletionValues: Utils.AllowedEditionValues);
+ => CompletionHelpers.GetMatchingResults(wordToComplete, possibleCompletionValues: Utils.AllowedEditionValues);
}
}
diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs
index f47f9b45e48..105704fb256 100644
--- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs
+++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs
@@ -1620,17 +1620,7 @@ internal PSModuleInfo LoadModuleManifest(
if (bailOnFirstError) return null;
}
- string resolvedCommandPrefix = string.Empty;
-
- if (!string.IsNullOrEmpty(defaultCommandPrefix))
- {
- resolvedCommandPrefix = defaultCommandPrefix;
- }
-
- if (!string.IsNullOrEmpty(this.BasePrefix))
- {
- resolvedCommandPrefix = this.BasePrefix;
- }
+ string resolvedCommandPrefix = BasePrefix ?? defaultCommandPrefix ?? string.Empty;
if (!string.IsNullOrEmpty(actualRootModule))
{
diff --git a/src/System.Management.Automation/engine/Modules/ScriptAnalysis.cs b/src/System.Management.Automation/engine/Modules/ScriptAnalysis.cs
index 9644829a02a..7207a7292c0 100644
--- a/src/System.Management.Automation/engine/Modules/ScriptAnalysis.cs
+++ b/src/System.Management.Automation/engine/Modules/ScriptAnalysis.cs
@@ -277,10 +277,22 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a
// - Exporting module members
public override AstVisitAction VisitCommand(CommandAst commandAst)
{
- string commandName =
- commandAst.GetCommandName() ??
- GetSafeValueVisitor.GetSafeValue(commandAst.CommandElements[0], null, GetSafeValueVisitor.SafeValueContext.ModuleAnalysis) as string;
+ string commandName = commandAst.GetCommandName();
+ if (commandName is null)
+ {
+ // GetCommandName only works if the name is a string constant. GetSafeValueVistor can evaluate some safe dynamic expressions
+ try
+ {
+ commandName = GetSafeValueVisitor.GetSafeValue(commandAst.CommandElements[0], null, GetSafeValueVisitor.SafeValueContext.ModuleAnalysis) as string;
+ }
+ catch (ParseException)
+ {
+ // The script is invalid so we can't use GetSafeValue to get the name either.
+ }
+ }
+ // We couldn't get the name of the command. Either it's an anonymous scriptblock: & {"Some script"}
+ // Or it's a dynamic expression we couldn't safely resolve.
if (commandName == null)
return AstVisitAction.SkipChildren;
diff --git a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs
index 328eb4eee87..0af184f4e99 100644
--- a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs
+++ b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs
@@ -243,7 +243,7 @@ internal GeneralCommandErrorFeedback()
public Guid Id => _guid;
- public string Name => "general";
+ public string Name => "General Feedback";
public string Description => "The built-in general feedback source for command errors.";
diff --git a/src/System.Management.Automation/engine/cmdlet.cs b/src/System.Management.Automation/engine/cmdlet.cs
index 742224c21d5..ffe13b7304f 100644
--- a/src/System.Management.Automation/engine/cmdlet.cs
+++ b/src/System.Management.Automation/engine/cmdlet.cs
@@ -10,7 +10,7 @@
using System.Reflection;
using System.Resources;
using System.Management.Automation.Internal;
-using Dbg = System.Management.Automation.Diagnostics;
+using System.Threading;
namespace System.Management.Automation
{
@@ -100,6 +100,11 @@ public bool Stopping
}
}
+ ///
+ /// Gets the CancellationToken that is signaled when the pipeline is stopping.
+ ///
+ public CancellationToken PipelineStopToken => StopToken;
+
///
/// The name of the parameter set in effect.
///
diff --git a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
index 9e5612189fa..003625791b1 100644
--- a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
+++ b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
@@ -8,7 +8,6 @@
using System.Globalization;
using System.Management.Automation.Host;
using System.Management.Automation.Internal;
-using System.Management.Automation.Language;
using System.Management.Automation.Runspaces;
using System.Management.Automation.Subsystem.Feedback;
using System.Runtime.InteropServices;
@@ -67,13 +66,6 @@ public static class HostUtilities
$formatString -f $lastError.TargetObject,"".\$($lastError.TargetObject)""
";
- private static readonly string s_getFuzzyMatchedCommands = @"
- [System.Diagnostics.DebuggerHidden()]
- param([string] $formatString)
-
- $formatString -f [string]::Join(', ', (Get-Command $lastError.TargetObject -UseFuzzyMatching -FuzzyMinimumDistance 1 | Select-Object -First 5 -Unique -ExpandProperty Name))
- ";
-
private static readonly List s_suggestions = InitializeSuggestions();
private static bool HostSupportUnicode()
@@ -97,28 +89,17 @@ private static bool HostSupportUnicode()
private static List InitializeSuggestions()
{
- var suggestions = new List(
- new Hashtable[]
- {
- NewSuggestion(
- id: 3,
- category: "General",
- matchType: SuggestionMatchType.Dynamic,
- rule: ScriptBlock.CreateDelayParsedScriptBlock(s_checkForCommandInCurrentDirectoryScript, isProductCode: true),
- suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_createCommandExistsInCurrentDirectoryScript, isProductCode: true),
- suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandExistsInCurrentDirectory) },
- enabled: true)
- });
-
- suggestions.Add(
+ var suggestions = new List()
+ {
NewSuggestion(
- id: 4,
+ id: 3,
category: "General",
- matchType: SuggestionMatchType.ErrorId,
- rule: "CommandNotFoundException",
- suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_getFuzzyMatchedCommands, isProductCode: true),
- suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandNotFound) },
- enabled: true));
+ matchType: SuggestionMatchType.Dynamic,
+ rule: ScriptBlock.CreateDelayParsedScriptBlock(s_checkForCommandInCurrentDirectoryScript, isProductCode: true),
+ suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_createCommandExistsInCurrentDirectoryScript, isProductCode: true),
+ suggestionArgs: new object[] { SuggestionStrings.Suggestion_CommandExistsInCurrentDirectory_Legacy },
+ enabled: true)
+ };
return suggestions;
}
diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs
index 464231c0402..1592d2e7e7d 100644
--- a/src/System.Management.Automation/engine/parser/Parser.cs
+++ b/src/System.Management.Automation/engine/parser/Parser.cs
@@ -1487,7 +1487,7 @@ private ITypeName GenericTypeNameRule(Token genericTypeName, Token firstToken, b
rBracketToken = null;
}
- var openGenericType = new TypeName(genericTypeName.Extent, genericTypeName.Text);
+ var openGenericType = new TypeName(genericTypeName.Extent, genericTypeName.Text, genericArguments.Count);
var result = new GenericTypeName(
ExtentOf(genericTypeName.Extent, ExtentFromFirstOf(rBracketToken, genericArguments.LastOrDefault(), firstToken)),
openGenericType,
@@ -3004,8 +3004,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom
dropIntoDebugger: true);
}
- // Configuration is not supported on ARM64
- if (PsUtils.IsRunningOnProcessorArchitectureARM())
+ // Configuration is not supported for ARM or ARM64 process architecture.
+ if (PsUtils.IsRunningOnProcessArchitectureARM())
{
ReportError(
configurationToken.Extent,
@@ -7154,7 +7154,7 @@ private ExpressionAst UnaryExpressionRule(bool endNumberOnTernaryOpChars = false
ParserStrings.UnexpectedAttribute,
lastAttribute.TypeName.FullName);
- return new ErrorExpressionAst(ExtentOf(token, lastAttribute));
+ return new ErrorExpressionAst(ExtentOf(token, lastAttribute), attributes);
}
expr = new AttributedExpressionAst(ExtentOf(lastAttribute, child), lastAttribute, child);
diff --git a/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs b/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs
index 0e0355761ac..a7744ac6411 100644
--- a/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs
+++ b/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs
@@ -150,6 +150,8 @@ public TypeInferenceContext(PowerShell powerShell)
public TypeDefinitionAst CurrentTypeDefinitionAst { get; set; }
+ public HashSet AnalyzedCommands { get; } = new HashSet();
+
public TypeInferenceRuntimePermissions RuntimePermissions { get; set; }
internal PowerShellExecutionHelper Helper { get; }
@@ -1239,7 +1241,18 @@ object ICustomAstVisitor.VisitDoUntilStatement(DoUntilStatementAst doUntilStatem
object ICustomAstVisitor.VisitAssignmentStatement(AssignmentStatementAst assignmentStatementAst)
{
- return assignmentStatementAst.Left.Accept(this);
+ ExpressionAst child = assignmentStatementAst.Left;
+ while (child is AttributedExpressionAst attributeChild)
+ {
+ if (attributeChild is ConvertExpressionAst convert)
+ {
+ return new List() { new(convert.Type.TypeName) };
+ }
+
+ child = attributeChild.Child;
+ }
+
+ return assignmentStatementAst.Right.Accept(this);
}
object ICustomAstVisitor.VisitPipeline(PipelineAst pipelineAst)
@@ -1270,8 +1283,82 @@ object ICustomAstVisitor.VisitFileRedirection(FileRedirectionAst fileRedirection
return TypeInferenceContext.EmptyPSTypeNameArray;
}
- private void InferTypesFrom(CommandAst commandAst, List inferredTypes)
+ private void InferTypesFrom(CommandAst commandAst, List inferredTypes, bool forRedirection = false)
{
+ if (commandAst.Redirections.Count > 0)
+ {
+ var mergedStreams = new HashSet();
+ bool allStreamsMerged = false;
+ foreach (RedirectionAst streamRedirection in commandAst.Redirections)
+ {
+ if (streamRedirection is FileRedirectionAst fileRedirection)
+ {
+ if (!forRedirection && fileRedirection.FromStream is RedirectionStream.All or RedirectionStream.Output)
+ {
+ // command output is redirected so it returns nothing.
+ return;
+ }
+ }
+ else if (streamRedirection is MergingRedirectionAst mergeRedirection && mergeRedirection.ToStream == RedirectionStream.Output)
+ {
+ if (mergeRedirection.FromStream == RedirectionStream.All)
+ {
+ allStreamsMerged = true;
+ continue;
+ }
+
+ _ = mergedStreams.Add(mergeRedirection.FromStream);
+ }
+ }
+
+ if (allStreamsMerged)
+ {
+ inferredTypes.Add(new PSTypeName(typeof(ErrorRecord)));
+ inferredTypes.Add(new PSTypeName(typeof(WarningRecord)));
+ inferredTypes.Add(new PSTypeName(typeof(VerboseRecord)));
+ inferredTypes.Add(new PSTypeName(typeof(DebugRecord)));
+ inferredTypes.Add(new PSTypeName(typeof(InformationRecord)));
+ }
+ else
+ {
+ foreach (RedirectionStream value in mergedStreams)
+ {
+ switch (value)
+ {
+ case RedirectionStream.Error:
+ inferredTypes.Add(new PSTypeName(typeof(ErrorRecord)));
+ break;
+
+ case RedirectionStream.Warning:
+ inferredTypes.Add(new PSTypeName(typeof(WarningRecord)));
+ break;
+
+ case RedirectionStream.Verbose:
+ inferredTypes.Add(new PSTypeName(typeof(VerboseRecord)));
+ break;
+
+ case RedirectionStream.Debug:
+ inferredTypes.Add(new PSTypeName(typeof(DebugRecord)));
+ break;
+
+ case RedirectionStream.Information:
+ inferredTypes.Add(new PSTypeName(typeof(InformationRecord)));
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ if (commandAst.CommandElements[0] is ScriptBlockExpressionAst scriptBlock)
+ {
+ // An anonymous function like: & {"Do Something"}
+ inferredTypes.AddRange(InferTypes(scriptBlock.ScriptBlock));
+ return;
+ }
+
PseudoBindingInfo pseudoBinding = new PseudoParameterBinder()
.DoPseudoParameterBinding(commandAst, null, null, PseudoParameterBinder.BindingType.ParameterCompletion);
@@ -1354,6 +1441,21 @@ private void InferTypesFrom(CommandAst commandAst, List inferredType
}
}
+ if ((commandInfo.OutputType.Count == 0
+ || (commandInfo.OutputType.Count == 1
+ && (commandInfo.OutputType[0].Name.EqualsOrdinalIgnoreCase(typeof(PSObject).FullName)
+ || commandInfo.OutputType[0].Name.EqualsOrdinalIgnoreCase(typeof(object).FullName))))
+ && commandInfo is IScriptCommandInfo scriptCommandInfo
+ && scriptCommandInfo.ScriptBlock.Ast is IParameterMetadataProvider scriptBlockWithParams
+ && _context.AnalyzedCommands.Add(scriptBlockWithParams))
+ {
+ // This is a function without an output type defined (or it's too generic to be useful)
+ // We can analyze the code inside the function to find out what it actually outputs
+ // The purpose of the hashset is to avoid infinite loops with functions that call themselves.
+ inferredTypes.AddRange(InferTypes(scriptBlockWithParams.Body));
+ return;
+ }
+
// The OutputType property ignores the parameter set specified in the OutputTypeAttribute.
// With pseudo-binding, we actually know the candidate parameter sets, so we could take
// advantage of it here, but I opted for the simpler code because so few cmdlets use
@@ -1861,6 +1963,36 @@ private IEnumerable InferTypesFrom(MemberExpressionAst memberExpress
return res;
}
+ private static IEnumerable InferTypeFromRef(InvokeMemberExpressionAst invokeMember, ExpressionAst refArgument)
+ {
+ Type expressionClrType = (invokeMember.Expression as TypeExpressionAst)?.TypeName.GetReflectionType();
+ string memberName = (invokeMember.Member as StringConstantExpressionAst)?.Value;
+ int argumentIndex = invokeMember.Arguments.IndexOf(refArgument);
+ if (expressionClrType is null || string.IsNullOrEmpty(memberName) || argumentIndex == -1)
+ {
+ yield break;
+ }
+
+ foreach (MemberInfo memberInfo in expressionClrType.GetMember(memberName))
+ {
+ if (memberInfo.MemberType == MemberTypes.Method)
+ {
+ var methodInfo = memberInfo as MethodInfo;
+ ParameterInfo[] methodParams = methodInfo.GetParameters();
+ if (methodParams.Length < argumentIndex)
+ {
+ continue;
+ }
+
+ ParameterInfo paramCandidate = methodParams[argumentIndex];
+ if (paramCandidate.IsOut)
+ {
+ yield return new PSTypeName(paramCandidate.ParameterType.GetElementType());
+ }
+ }
+ }
+ }
+
private void GetTypesOfMembers(
PSTypeName thisType,
string memberName,
@@ -2157,7 +2289,7 @@ private void InferTypeFrom(VariableExpressionAst variableExpressionAst, List 0)
{
if (switchErrorStatement.Conditions[0].Extent.EndOffset < variableExpressionAst.Extent.StartOffset)
{
- parent = switchErrorStatement.Conditions[0];
+ currentAst = switchErrorStatement.Conditions[0];
break;
}
else
{
// $_ is inside the condition that is being declared, eg: Get-Process | Sort-Object -Property {switch ($_.Proc
- parent = switchErrorStatement.Parent;
+ currentAst = switchErrorStatement.Parent;
continue;
}
}
break;
}
- else if (parent is ScriptBlockExpressionAst)
+ else if (currentAst is ScriptBlockExpressionAst)
{
hasSeenScriptBlock = true;
}
else if (hasSeenScriptBlock)
{
- if (parent is InvokeMemberExpressionAst invokeMember)
+ if (currentAst is InvokeMemberExpressionAst invokeMember)
{
- parent = invokeMember.Expression;
+ currentAst = invokeMember.Expression;
break;
}
- else if (parent is CommandAst cmdAst && cmdAst.Parent is PipelineAst pipeline && pipeline.PipelineElements.Count > 1)
+ else if (currentAst is CommandAst cmdAst && cmdAst.Parent is PipelineAst pipeline && pipeline.PipelineElements.Count > 1)
{
// We've found a pipeline with multiple commands, now we need to determine what command came before the command with the scriptblock:
// eg Get-Partition in this example: Get-Disk | Get-Partition | Where {$_}
var indexOfPreviousCommand = pipeline.PipelineElements.IndexOf(cmdAst) - 1;
if (indexOfPreviousCommand >= 0)
{
- parent = pipeline.PipelineElements[indexOfPreviousCommand];
+ currentAst = pipeline.PipelineElements[indexOfPreviousCommand];
break;
}
}
}
- parent = parent.Parent;
+ currentAst = currentAst.Parent;
}
- if (parent is CatchClauseAst catchBlock)
+ if (currentAst is CatchClauseAst catchBlock)
{
if (catchBlock.CatchTypes.Count > 0)
{
@@ -2248,7 +2380,7 @@ private void InferTypeFrom(VariableExpressionAst variableExpressionAst, List)AstSearcher.FindAll(
- parent,
- ast =>
+ ScopeIsLocal = true,
+ LocalScopeOnly = variableExpressionAst.VariablePath.IsLocal || variableExpressionAst.VariablePath.IsPrivate,
+ StopSearchOffset = variableExpressionAst.Extent.StartOffset,
+ VariableTarget = variableExpressionAst
+ };
+ while (currentAst is not null)
+ {
+ if (currentAst is IParameterMetadataProvider)
{
- if (ast is ParameterAst || ast is AssignmentStatementAst || ast is CommandAst)
+ if (currentAst is ScriptBlockAst && currentAst.Parent is FunctionDefinitionAst)
{
- return variableExpressionAst.AstAssignsToSameVariable(ast)
- && ast.Extent.EndOffset < startOffset;
+ // If this scriptblock belongs to a function we want to visit that instead so we can get the parameters
+ // function X ($Param1){}
+ currentAst = currentAst.Parent;
}
- if (ast is ForEachStatementAst)
- {
- return variableExpressionAst.AstAssignsToSameVariable(ast)
- && ast.Extent.StartOffset < startOffset;
- }
-
- return false;
- },
- searchNestedScriptBlocks: true);
-
- foreach (var ast in targetAsts)
- {
- if (ast is ParameterAst parameterAst)
- {
- var currentCount = inferredTypes.Count;
- inferredTypes.AddRange(InferTypes(parameterAst));
+ assignmentVisitor.ScopeDefinitionAst = currentAst;
+ currentAst.Visit(assignmentVisitor);
- if (inferredTypes.Count != currentCount)
+ if (assignmentVisitor.LocalScopeOnly
+ || assignmentVisitor.LastConstraint is not null
+ || ((assignmentVisitor.LastAssignment is not null || assignmentVisitor.LastAssignmentType is not null)
+ && (currentAst.Parent is not ScriptBlockExpressionAst scriptBlock || !scriptBlock.IsDotsourced())))
{
- return;
+ // We only care about the parent scopes if no assignment has been made in the current scope
+ // or if it's a dot sourced scriptblock where an earlier defined type constraint could influence the final type
+ break;
}
- }
- }
-
- var assignAsts = targetAsts.OfType().ToArray();
- // If any of the assignments lhs use a type constraint, then we use that.
- // Otherwise, we use the rhs of the "nearest" assignment
- for (int i = assignAsts.Length - 1; i >= 0; i--)
- {
- if (assignAsts[i].Left is ConvertExpressionAst lhsConvert)
- {
- inferredTypes.Add(new PSTypeName(lhsConvert.Type.TypeName));
- return;
+ assignmentVisitor.ScopeIsLocal = false;
+ assignmentVisitor.StopSearchOffset = currentAst.Extent.StartOffset;
}
- }
- var foreachAst = targetAsts.OfType().FirstOrDefault();
- if (foreachAst != null)
- {
- inferredTypes.AddRange(
- GetInferredEnumeratedTypes(InferTypes(foreachAst.Condition)));
- return;
+ currentAst = currentAst.Parent;
}
- var commandCompletionAst = targetAsts.OfType().FirstOrDefault();
- if (commandCompletionAst != null)
+ // The visitor is done finding the last assignment, now we need to infer the type of that assignment.
+ if (assignmentVisitor.LastConstraint is not null)
{
- inferredTypes.AddRange(InferTypes(commandCompletionAst));
- return;
+ inferredTypes.Add(new PSTypeName(assignmentVisitor.LastConstraint));
}
-
- int smallestDiff = int.MaxValue;
- AssignmentStatementAst closestAssignment = null;
- foreach (var assignAst in assignAsts)
+ else if (assignmentVisitor.LastAssignment is not null)
{
- var endOffset = assignAst.Extent.EndOffset;
- if ((startOffset - endOffset) < smallestDiff)
+ if (assignmentVisitor.EnumerateAssignment)
{
- smallestDiff = startOffset - endOffset;
- closestAssignment = assignAst;
+ inferredTypes.AddRange(GetInferredEnumeratedTypes(InferTypes(assignmentVisitor.LastAssignment)));
+ }
+ else
+ {
+ if (assignmentVisitor.LastAssignment is ConvertExpressionAst convertExpression
+ && convertExpression.IsRef())
+ {
+ if (convertExpression.Parent is InvokeMemberExpressionAst memberInvoke)
+ {
+ inferredTypes.AddRange(InferTypeFromRef(memberInvoke, convertExpression));
+ }
+ }
+ else if (assignmentVisitor.RedirectionAssignment && assignmentVisitor.LastAssignment is CommandAst cmdAst)
+ {
+ InferTypesFrom(cmdAst, inferredTypes, forRedirection: true);
+ }
+ else
+ {
+ inferredTypes.AddRange(InferTypes(assignmentVisitor.LastAssignment));
+ }
}
}
-
- if (closestAssignment != null)
+ else if (assignmentVisitor.LastAssignmentType is not null)
{
- inferredTypes.AddRange(InferTypes(closestAssignment.Right));
+ inferredTypes.Add(assignmentVisitor.LastAssignmentType);
}
if (_context.TryGetRepresentativeTypeNameFromExpressionSafeEval(variableExpressionAst, out var evalTypeName))
@@ -2767,95 +2877,459 @@ private static CommandBaseAst GetPreviousPipelineCommand(CommandAst commandAst)
var i = pipe.PipelineElements.IndexOf(commandAst);
return i != 0 ? pipe.PipelineElements[i - 1] : null;
}
- }
- internal static class TypeInferenceExtension
- {
- public static bool EqualsOrdinalIgnoreCase(this string s, string t)
- {
- return string.Equals(s, t, StringComparison.OrdinalIgnoreCase);
- }
+ private sealed class VariableAssignmentVisitor : AstVisitor2
+ {
+ ///
+ /// If set, we only look for local/private assignments in the scope of the variable we are inferring.
+ ///
+ internal bool LocalScopeOnly;
+
+ ///
+ /// The current scope is local to the variable that is being inferred.
+ ///
+ internal bool ScopeIsLocal;
+
+ ///
+ /// The variable that we are trying to determine the type of.
+ ///
+ internal VariableExpressionAst VariableTarget;
+
+ ///
+ /// The last type constraint applied to the variable. This takes priority when determining the type of the variable.
+ ///
+ internal ITypeName LastConstraint;
+
+ ///
+ /// The last ast that assigned a value to the variable. This determines the value of the variable unless a type constraint has been applied.
+ ///
+ internal Ast LastAssignment;
+
+ ///
+ /// The inferred type from the most recent assignment. This is only used for stream redirections to variables, or the special OutVariable common parameters.
+ ///
+ internal PSTypeName LastAssignmentType;
+
+ ///
+ /// Whether or not the types from the last assignment should be enumerated.
+ /// For assignments made by the PipelineVariable parameter or the foreach statement.
+ ///
+ internal bool EnumerateAssignment;
+
+ ///
+ /// Whether or not the last assignment was via command redirection.
+ ///
+ internal bool RedirectionAssignment;
+
+ ///
+ /// The Ast of the scope we are currently analyzing.
+ ///
+ internal Ast ScopeDefinitionAst;
+ internal int StopSearchOffset;
+ private int LastAssignmentOffset = -1;
+
+ private void SetLastAssignment(Ast ast, bool enumerate = false, bool redirectionAssignment = false)
+ {
+ if (LastAssignmentOffset < ast.Extent.StartOffset && !VariableTarget.Extent.IsWithin(ast.Extent))
+ {
+ // If the variable we are inferring the value of is inside this assignment then the assignment is invalid
+ // For example: $x = Get-Random; $x = $x.Where{$_.} here the value should be inferred based on Get-Random and not $x = $x...
+ ClearAssignmentData();
+ LastAssignment = ast;
+ EnumerateAssignment = enumerate;
+ RedirectionAssignment = redirectionAssignment;
+ LastAssignmentOffset = ast.Extent.StartOffset;
+ }
+ }
+
+ private void SetLastAssignmentType(PSTypeName typeName, IScriptExtent assignmentExtent)
+ {
+ if (LastAssignmentOffset < assignmentExtent.StartOffset && !VariableTarget.Extent.IsWithin(assignmentExtent))
+ {
+ // If the variable we are inferring the value of is inside this assignment then the assignment is invalid
+ // For example: $x = 1..10; Get-Random 2>variable:x -InputObject ($x.) here the variable should be inferred based on the initial 1..10 assignment
+ // and not the error redirected variable.
+ ClearAssignmentData();
+ LastAssignmentType = typeName;
+ LastAssignmentOffset = assignmentExtent.StartOffset;
+ }
+ }
+
+ private void ClearAssignmentData()
+ {
+ LastAssignment = null;
+ LastAssignmentType = null;
+ EnumerateAssignment = false;
+ RedirectionAssignment = false;
+ }
+
+ private bool AssignsToTargetVar(VariableExpressionAst foundVar)
+ {
+ if (!foundVar.VariablePath.UnqualifiedPath.EqualsOrdinalIgnoreCase(VariableTarget.VariablePath.UnqualifiedPath))
+ {
+ return false;
+ }
- public static IEnumerable GetGetterProperty(this Type type, string propertyName)
- {
- var res = new List();
- foreach (var m in type.GetMethods(BindingFlags.Public | BindingFlags.Instance))
+ int scopeIndex = foundVar.VariablePath.UserPath.IndexOf(':');
+ string scopeName = scopeIndex == -1 ? string.Empty : foundVar.VariablePath.UserPath.Remove(scopeIndex);
+ return AssignsToTargetScope(scopeName);
+ }
+
+ private bool AssignsToTargetVar(string userPath)
{
- var name = m.Name;
- // Equals without string allocation
- if (name.Length == propertyName.Length + 4
- && name.StartsWith("get_")
- && name.IndexOf(propertyName, 4, StringComparison.Ordinal) == 4)
+ if (string.IsNullOrEmpty(userPath))
{
- res.Add(m);
+ return false;
+ }
+
+ string scopeName;
+ string varName;
+ int scopeIndex = userPath.IndexOf(':');
+ if (scopeIndex == -1)
+ {
+ scopeName = string.Empty;
+ varName = userPath;
+ }
+ else
+ {
+ scopeName = userPath.Remove(scopeIndex);
+ varName = userPath.Substring(scopeIndex + 1);
+ }
+
+ if (!varName.EqualsOrdinalIgnoreCase(VariableTarget.VariablePath.UnqualifiedPath))
+ {
+ return false;
}
+
+ return AssignsToTargetScope(scopeName);
}
- return res;
- }
+ private bool AssignsToTargetScope(string scopeName)
+ => LocalScopeOnly
+ ? string.IsNullOrEmpty(scopeName) || scopeName.EqualsOrdinalIgnoreCase("Local") || scopeName.EqualsOrdinalIgnoreCase("Private")
+ : ScopeIsLocal || !(scopeName.EqualsOrdinalIgnoreCase("Local") || scopeName.EqualsOrdinalIgnoreCase("Private"));
- public static bool AstAssignsToSameVariable(this VariableExpressionAst variableAst, Ast ast)
- {
- var parameterAst = ast as ParameterAst;
- var variableAstVariablePath = variableAst.VariablePath;
- if (parameterAst != null)
+ public override AstVisitAction DefaultVisit(Ast ast)
{
- return variableAstVariablePath.IsUnscopedVariable &&
- parameterAst.Name.VariablePath.UnqualifiedPath.Equals(variableAstVariablePath.UnqualifiedPath, StringComparison.OrdinalIgnoreCase) &&
- parameterAst.Parent.Parent.Extent.EndOffset > variableAst.Extent.StartOffset;
+ if (ast.Extent.StartOffset >= StopSearchOffset)
+ {
+ // When visiting do while/until statements, the condition will be visited before the statement block
+ // The condition itself may not be interesting if it's after the cursor, but the statement block could be
+ // Example:
+ // do
+ // {
+ // $Var = gci
+ // $Var.
+ // }
+ // until($false)
+ return ast is PipelineBaseAst && ast.Parent is DoUntilStatementAst or DoWhileStatementAst
+ ? AstVisitAction.SkipChildren
+ : AstVisitAction.StopVisit;
+ }
+
+ return AstVisitAction.Continue;
}
- if (ast is ForEachStatementAst foreachAst)
+ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst assignmentStatementAst)
{
- return variableAstVariablePath.IsUnscopedVariable &&
- foreachAst.Variable.VariablePath.UnqualifiedPath.Equals(variableAstVariablePath.UnqualifiedPath, StringComparison.OrdinalIgnoreCase);
+ if (assignmentStatementAst.Extent.StartOffset >= StopSearchOffset)
+ {
+ return assignmentStatementAst.Parent is DoUntilStatementAst or DoWhileStatementAst
+ ? AstVisitAction.SkipChildren
+ : AstVisitAction.StopVisit;
+ }
+
+ if (assignmentStatementAst.Left is AttributedExpressionAst attributedExpression)
+ {
+ var firstConvertExpression = attributedExpression as ConvertExpressionAst;
+ ExpressionAst child = attributedExpression.Child;
+ while (child is AttributedExpressionAst attributeChild)
+ {
+ if (firstConvertExpression is null && attributeChild is ConvertExpressionAst convertExpression)
+ {
+ // Multiple type constraint can be set on a variable like this: [int] [string] $Var1 = 1
+ // But it's the left most type constraint that determines the final type.
+ firstConvertExpression = convertExpression;
+ }
+
+ child = attributeChild.Child;
+ }
+
+ if (child is VariableExpressionAst variableExpression && AssignsToTargetVar(variableExpression))
+ {
+ if (firstConvertExpression is not null)
+ {
+ LastConstraint = firstConvertExpression.Type.TypeName;
+ }
+ else
+ {
+ SetLastAssignment(assignmentStatementAst.Right);
+ }
+ }
+ }
+ else if (assignmentStatementAst.Left is VariableExpressionAst variableExpression && AssignsToTargetVar(variableExpression))
+ {
+ SetLastAssignment(assignmentStatementAst.Right);
+ }
+
+ return AstVisitAction.Continue;
}
- if (ast is CommandAst commandAst)
+ public override AstVisitAction VisitCommand(CommandAst commandAst)
{
- string[] variableParameters = { "PV", "PipelineVariable", "OV", "OutVariable" };
- StaticBindingResult bindingResult = StaticParameterBinder.BindCommand(commandAst, false, variableParameters);
+ if (commandAst.Extent.StartOffset >= StopSearchOffset)
+ {
+ return AstVisitAction.StopVisit;
+ }
- if (bindingResult != null)
+ string commandName = commandAst.GetCommandName();
+ if (commandName is not null && CompletionCompleters.s_varModificationCommands.Contains(commandName))
{
- foreach (string commandVariableParameter in variableParameters)
+ StaticBindingResult bindingResult = StaticParameterBinder.BindCommand(commandAst, resolve: false, CompletionCompleters.s_varModificationParameters);
+ if (bindingResult is not null
+ && bindingResult.BoundParameters.TryGetValue("Name", out ParameterBindingResult variableName)
+ && variableName.ConstantValue is string nameValue
+ && AssignsToTargetVar(nameValue)
+ && bindingResult.BoundParameters.TryGetValue("Value", out ParameterBindingResult variableValue))
{
- if (bindingResult.BoundParameters.TryGetValue(commandVariableParameter, out ParameterBindingResult parameterBindingResult))
+ SetLastAssignment(variableValue.Value);
+ return AstVisitAction.Continue;
+ }
+ }
+
+ StaticBindingResult bindResult = StaticParameterBinder.BindCommand(commandAst, resolve: false);
+ if (bindResult is not null)
+ {
+ foreach (string parameterName in CompletionCompleters.s_outVarParameters)
+ {
+ if (bindResult.BoundParameters.TryGetValue(parameterName, out ParameterBindingResult outVarBind)
+ && outVarBind.ConstantValue is string varName
+ && AssignsToTargetVar(varName))
{
- if (string.Equals(variableAstVariablePath.UnqualifiedPath, (string)parameterBindingResult.ConstantValue, StringComparison.OrdinalIgnoreCase))
+ // The *Variable parameters actually always results in an ArrayList
+ // But to make type inference of individual elements better, we say it's a generic list.
+ switch (parameterName)
{
- return true;
+ case "ErrorVariable":
+ case "ev":
+ SetLastAssignmentType(new PSTypeName(typeof(List)), commandAst.Extent);
+ break;
+
+ case "WarningVariable":
+ case "wv":
+ SetLastAssignmentType(new PSTypeName(typeof(List)), commandAst.Extent);
+ break;
+
+ case "InformationVariable":
+ case "iv":
+ SetLastAssignmentType(new PSTypeName(typeof(List)), commandAst.Extent);
+ break;
+
+ case "OutVariable":
+ case "ov":
+ SetLastAssignment(commandAst);
+ break;
+
+ default:
+ break;
+ }
+
+ return AstVisitAction.Continue;
+ }
+ }
+
+ if (commandAst.Parent is PipelineAst pipeline && pipeline.Extent.EndOffset > VariableTarget.Extent.StartOffset)
+ {
+ foreach (string parameterName in CompletionCompleters.s_pipelineVariableParameters)
+ {
+ if (bindResult.BoundParameters.TryGetValue(parameterName, out ParameterBindingResult pipeVarBind)
+ && pipeVarBind.ConstantValue is string varName
+ && AssignsToTargetVar(varName))
+ {
+ SetLastAssignment(commandAst, enumerate: true);
+ return AstVisitAction.Continue;
}
}
}
}
- return false;
+ foreach (RedirectionAst redirection in commandAst.Redirections)
+ {
+ if (redirection is FileRedirectionAst fileRedirection
+ && fileRedirection.Location is StringConstantExpressionAst redirectTarget
+ && redirectTarget.Value.StartsWith("variable:", StringComparison.OrdinalIgnoreCase)
+ && redirectTarget.Value.Length > "variable:".Length)
+ {
+ string varName = redirectTarget.Value.Substring("variable:".Length);
+ if (!AssignsToTargetVar(varName))
+ {
+ continue;
+ }
+
+ switch (fileRedirection.FromStream)
+ {
+ case RedirectionStream.Error:
+ SetLastAssignmentType(new PSTypeName(typeof(ErrorRecord)), commandAst.Extent);
+ break;
+
+ case RedirectionStream.Warning:
+ SetLastAssignmentType(new PSTypeName(typeof(WarningRecord)), commandAst.Extent);
+ break;
+
+ case RedirectionStream.Verbose:
+ SetLastAssignmentType(new PSTypeName(typeof(VerboseRecord)), commandAst.Extent);
+ break;
+
+ case RedirectionStream.Debug:
+ SetLastAssignmentType(new PSTypeName(typeof(DebugRecord)), commandAst.Extent);
+ break;
+
+ case RedirectionStream.Information:
+ SetLastAssignmentType(new PSTypeName(typeof(InformationRecord)), commandAst.Extent);
+ break;
+
+ default:
+ SetLastAssignment(commandAst, redirectionAssignment: true);
+ break;
+ }
+ }
+ }
+
+ return AstVisitAction.Continue;
}
- var assignmentAst = (AssignmentStatementAst)ast;
- var lhs = assignmentAst.Left;
- if (lhs is ConvertExpressionAst convertExpr)
+ public override AstVisitAction VisitParameter(ParameterAst parameterAst)
{
- lhs = convertExpr.Child;
+ if (parameterAst.Extent.StartOffset >= StopSearchOffset)
+ {
+ return AstVisitAction.StopVisit;
+ }
+
+ if (AssignsToTargetVar(parameterAst.Name))
+ {
+ foreach (AttributeBaseAst attribute in parameterAst.Attributes)
+ {
+ if (attribute is TypeConstraintAst typeConstraint)
+ {
+ LastConstraint = typeConstraint.TypeName;
+ return AstVisitAction.Continue;
+ }
+ }
+ }
+
+ return AstVisitAction.Continue;
}
- if (lhs is not VariableExpressionAst varExpr)
+ public override AstVisitAction VisitForEachStatement(ForEachStatementAst forEachStatementAst)
{
- return false;
+ if (forEachStatementAst.Extent.StartOffset >= StopSearchOffset)
+ {
+ return AstVisitAction.StopVisit;
+ }
+
+ if (AssignsToTargetVar(forEachStatementAst.Variable) && forEachStatementAst.Condition.Extent.EndOffset < VariableTarget.Extent.StartOffset)
+ {
+ SetLastAssignment(forEachStatementAst.Condition, enumerate: true);
+ }
+
+ return AstVisitAction.Continue;
+ }
+
+ public override AstVisitAction VisitConvertExpression(ConvertExpressionAst convertExpressionAst)
+ {
+ if (convertExpressionAst.IsRef()
+ && convertExpressionAst.Child is VariableExpressionAst varAst
+ && AssignsToTargetVar(varAst))
+ {
+ SetLastAssignment(convertExpressionAst);
+ }
+
+ return AstVisitAction.Continue;
+ }
+
+ public override AstVisitAction VisitAttribute(AttributeAst attributeAst)
+ {
+ // Attributes can't assign values to variables so they aren't interesting.
+ return AstVisitAction.SkipChildren;
}
- var candidateVarPath = varExpr.VariablePath;
- if (candidateVarPath.UserPath.Equals(variableAstVariablePath.UserPath, StringComparison.OrdinalIgnoreCase))
+ public override AstVisitAction VisitScriptBlockExpression(ScriptBlockExpressionAst scriptBlockExpressionAst)
{
- return true;
+ return scriptBlockExpressionAst.IsDotsourced()
+ ? AstVisitAction.Continue
+ : AstVisitAction.SkipChildren;
+ }
+
+ public override AstVisitAction VisitDataStatement(DataStatementAst dataStatementAst)
+ {
+ if (dataStatementAst.Extent.StartOffset >= StopSearchOffset)
+ {
+ return AstVisitAction.StopVisit;
+ }
+
+ if (AssignsToTargetVar(dataStatementAst.Variable) && dataStatementAst.Extent.EndOffset < VariableTarget.Extent.StartOffset)
+ {
+ SetLastAssignment(dataStatementAst.Body);
+ }
+
+ return AstVisitAction.SkipChildren;
}
- // The following condition is making an assumption that at script scope, we didn't use $script:, but in the local scope, we did
- // If we are searching anything other than script scope, this is wrong.
- if (variableAstVariablePath.IsScript && variableAstVariablePath.UnqualifiedPath.Equals(candidateVarPath.UnqualifiedPath, StringComparison.OrdinalIgnoreCase))
+ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst)
{
- return true;
+ return functionDefinitionAst == ScopeDefinitionAst
+ ? AstVisitAction.Continue
+ : AstVisitAction.SkipChildren;
+ }
+ }
+ }
+
+ internal static class TypeInferenceExtension
+ {
+ public static bool EqualsOrdinalIgnoreCase(this string s, string t)
+ {
+ return string.Equals(s, t, StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static IEnumerable GetGetterProperty(this Type type, string propertyName)
+ {
+ var res = new List();
+ foreach (var m in type.GetMethods(BindingFlags.Public | BindingFlags.Instance))
+ {
+ var name = m.Name;
+ // Equals without string allocation
+ if (name.Length == propertyName.Length + 4
+ && name.StartsWith("get_")
+ && name.IndexOf(propertyName, 4, StringComparison.Ordinal) == 4)
+ {
+ res.Add(m);
+ }
+ }
+
+ return res;
+ }
+
+ public static bool IsDotsourced(this ScriptBlockExpressionAst scriptBlockExpressionAst)
+ {
+ Ast parent = scriptBlockExpressionAst.Parent;
+
+ // This loop checks if the scriptblock is used as a dot sourced command
+ // or an argument for a command that uses the local scope eg: ForEach-Object -Process {$Var1 = "Hello"}, {Var2 = $true}
+ while (parent is not null)
+ {
+ if (parent is CommandAst cmdAst)
+ {
+ string cmdName = cmdAst.GetCommandName();
+ return CompletionCompleters.s_localScopeCommandNames.Contains(cmdName)
+ || (cmdAst.CommandElements[0] is ScriptBlockExpressionAst && cmdAst.InvocationOperator == TokenKind.Dot);
+ }
+
+ if (parent is not CommandExpressionAst and not PipelineAst and not StatementBlockAst and not ArrayExpressionAst and not ArrayLiteralAst)
+ {
+ break;
+ }
+
+ parent = parent.Parent;
}
return false;
diff --git a/src/System.Management.Automation/engine/parser/ast.cs b/src/System.Management.Automation/engine/parser/ast.cs
index c9c54bcd4b4..0325cf94aeb 100644
--- a/src/System.Management.Automation/engine/parser/ast.cs
+++ b/src/System.Management.Automation/engine/parser/ast.cs
@@ -7263,7 +7263,7 @@ internal PipelineAst GenerateCommandCallPipelineAst()
FunctionName.Extent,
new TypeName(
FunctionName.Extent,
- typeof(System.Management.Automation.Language.DynamicKeyword).FullName)),
+ typeof(DynamicKeyword).FullName)),
new StringConstantExpressionAst(
FunctionName.Extent,
"GetKeyword",
@@ -8424,9 +8424,11 @@ internal interface ISupportsTypeCaching
///
public sealed class TypeName : ITypeName, ISupportsTypeCaching
{
- internal readonly string _name;
- internal Type _type;
- internal readonly IScriptExtent _extent;
+ private readonly string _name;
+ private readonly IScriptExtent _extent;
+ private readonly int _genericArgumentCount;
+ private Type _type;
+
internal TypeDefinitionAst _typeDefinitionAst;
///
@@ -8485,6 +8487,23 @@ public TypeName(IScriptExtent extent, string name, string assembly)
AssemblyName = assembly;
}
+ ///
+ /// Construct a typename that represents a generic type definition.
+ ///
+ /// The extent of the typename.
+ /// The name of the type.
+ /// The number of generic arguments.
+ internal TypeName(IScriptExtent extent, string name, int genericArgumentCount)
+ : this(extent, name)
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan(genericArgumentCount, 0);
+
+ if (genericArgumentCount > 0 && !_name.Contains('`'))
+ {
+ _genericArgumentCount = genericArgumentCount;
+ }
+ }
+
///
/// Returns the full name of the type.
///
@@ -8561,8 +8580,25 @@ public Type GetReflectionType()
{
if (_type == null)
{
- Exception e;
- Type type = _typeDefinitionAst != null ? _typeDefinitionAst.Type : TypeResolver.ResolveTypeName(this, out e);
+ Type type = _typeDefinitionAst != null ? _typeDefinitionAst.Type : TypeResolver.ResolveTypeName(this, out _);
+
+ if (type is null && _genericArgumentCount > 0)
+ {
+ // We try an alternate name only if it failed to resolve with the original name.
+ // This is because for a generic type like `System.Tuple`, the original name `System.Tuple`
+ // can be resolved and hence `genericTypeName.TypeName.GetReflectionType()` in that case has always been
+ // returning the type `System.Tuple`. If we change to directly use the alternate name for resolution, the
+ // return value will become 'System.Tuple`1' in that case, and that's a breaking change.
+ TypeName newTypeName = new(
+ _extent,
+ string.Create(CultureInfo.InvariantCulture, $"{_name}`{_genericArgumentCount}"))
+ {
+ AssemblyName = AssemblyName
+ };
+
+ type = TypeResolver.ResolveTypeName(newTypeName, out _);
+ }
+
if (type != null)
{
try
@@ -8597,7 +8633,11 @@ public Type GetReflectionAttributeType()
var result = GetReflectionType();
if (result == null || !typeof(Attribute).IsAssignableFrom(result))
{
- var attrTypeName = new TypeName(_extent, FullName + "Attribute");
+ TypeName attrTypeName = new(_extent, $"{_name}Attribute", _genericArgumentCount)
+ {
+ AssemblyName = AssemblyName
+ };
+
result = attrTypeName.GetReflectionType();
if (result != null && !typeof(Attribute).IsAssignableFrom(result))
{
@@ -8890,8 +8930,13 @@ internal Type GetGenericType(Type generic)
{
if (!TypeName.FullName.Contains('`'))
{
- var newTypeName = new TypeName(Extent,
- string.Create(CultureInfo.InvariantCulture, $"{TypeName.FullName}`{GenericArguments.Count}"));
+ TypeName newTypeName = new(
+ Extent,
+ string.Create(CultureInfo.InvariantCulture, $"{TypeName.Name}`{GenericArguments.Count}"))
+ {
+ AssemblyName = TypeName.AssemblyName
+ };
+
generic = newTypeName.GetReflectionType();
}
}
@@ -8917,8 +8962,13 @@ public Type GetReflectionAttributeType()
{
if (!TypeName.FullName.Contains('`'))
{
- var newTypeName = new TypeName(Extent,
- string.Create(CultureInfo.InvariantCulture, $"{TypeName.FullName}Attribute`{GenericArguments.Count}"));
+ TypeName newTypeName = new(
+ Extent,
+ string.Create(CultureInfo.InvariantCulture, $"{TypeName.Name}Attribute`{GenericArguments.Count}"))
+ {
+ AssemblyName = TypeName.AssemblyName
+ };
+
generic = newTypeName.GetReflectionType();
}
}
diff --git a/src/System.Management.Automation/engine/pipeline.cs b/src/System.Management.Automation/engine/pipeline.cs
index 91bf4359189..191f80e1d89 100644
--- a/src/System.Management.Automation/engine/pipeline.cs
+++ b/src/System.Management.Automation/engine/pipeline.cs
@@ -7,6 +7,7 @@
using System.Management.Automation.Tracing;
using System.Reflection;
using System.Runtime.ExceptionServices;
+using System.Threading;
using Microsoft.PowerShell.Telemetry;
using Dbg = System.Management.Automation.Diagnostics;
@@ -29,6 +30,7 @@ internal class PipelineProcessor : IDisposable
{
#region private_members
+ private readonly CancellationTokenSource _pipelineStopTokenSource = new CancellationTokenSource();
private List _commands = new List();
private List _redirectionPipes;
private PipelineReader _externalInputPipe;
@@ -85,6 +87,7 @@ private void Dispose(bool disposing)
_externalErrorOutput = null;
_executionScope = null;
_eventLogBuffer = null;
+ _pipelineStopTokenSource.Dispose();
#if !CORECLR // Impersonation Not Supported On CSS
SecurityContext.Dispose();
SecurityContext = null;
@@ -118,6 +121,11 @@ internal bool ExecutionFailed
}
}
+ ///
+ /// Gets the CancellationToken that is signaled when the pipeline is stopping.
+ ///
+ internal CancellationToken PipelineStopToken => _pipelineStopTokenSource.Token;
+
internal void LogExecutionInfo(InvocationInfo invocationInfo, string text)
{
string message = StringUtil.Format(PipelineStrings.PipelineExecutionInformation, GetCommand(invocationInfo), text);
@@ -896,6 +904,8 @@ internal void Stop()
return;
}
+ _pipelineStopTokenSource.Cancel();
+
// Call StopProcessing() for all the commands.
foreach (CommandProcessorBase commandProcessor in commands)
{
diff --git a/src/System.Management.Automation/engine/regex.cs b/src/System.Management.Automation/engine/regex.cs
index 4ca21bd1310..cead035f057 100644
--- a/src/System.Management.Automation/engine/regex.cs
+++ b/src/System.Management.Automation/engine/regex.cs
@@ -238,9 +238,9 @@ internal static string Escape(string pattern, char[] charsNotToEscape)
char ch = pattern[i];
//
- // if it is a wildcard char, escape it
+ // if it is a special char, escape it
//
- if (IsWildcardChar(ch) && !charsNotToEscape.Contains(ch))
+ if (SpecialChars.Contains(ch) && !charsNotToEscape.Contains(ch))
{
temp[tempIndex++] = escapeChar;
}
diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs
index 78d459933fa..f4020547432 100644
--- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs
+++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs
@@ -6943,12 +6943,6 @@ internal static DynamicMetaObject InvokeDotNetMethod(
expr = Expression.Block(expr, ExpressionCache.AutomationNullConstant);
}
- // Expression block runs two expressions in order:
- // - Log method invocation to AMSI Notifications (can throw PSSecurityException)
- // - Invoke method
- string targetName = methodInfo.ReflectedType?.FullName ?? string.Empty;
- expr = MaybeAddMemberInvocationLogging(expr, targetName, name, args);
-
// If we're calling SteppablePipeline.{Begin|Process|End}, we don't want
// to wrap exceptions - this is very much a special case to help error
// propagation and ensure errors are attributed to the correct code (the
@@ -7111,6 +7105,7 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target,
invocationType != MethodInvocationType.NonVirtual;
var parameters = mi.GetParameters();
var argExprs = new Expression[parameters.Length];
+ var argsToLog = new List(Math.Max(parameters.Length, args.Length));
for (int i = 0; i < parameters.Length; ++i)
{
@@ -7135,16 +7130,21 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target,
if (expandParameters)
{
- argExprs[i] = Expression.NewArrayInit(
- paramElementType,
- args.Skip(i).Select(
- a => a.CastOrConvertMethodArgument(
+ IEnumerable elements = args
+ .Skip(i)
+ .Select(a =>
+ a.CastOrConvertMethodArgument(
paramElementType,
paramName,
mi.Name,
allowCastingToByRefLikeType: false,
temps,
- initTemps)));
+ initTemps))
+ .ToList();
+
+ argExprs[i] = Expression.NewArrayInit(paramElementType, elements);
+ // User specified the element arguments, so we log them instead of the compiler-created array.
+ argsToLog.AddRange(elements);
}
else
{
@@ -7155,13 +7155,18 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target,
allowCastingToByRefLikeType: false,
temps,
initTemps);
+
argExprs[i] = arg;
+ argsToLog.Add(arg);
}
}
else if (i >= args.Length)
{
- Diagnostics.Assert(parameters[i].IsOptional,
+ // We don't log the default value for an optional parameter, as it's not specified by the user.
+ Diagnostics.Assert(
+ parameters[i].IsOptional,
"if there are too few arguments, FindBestMethod should only succeed if parameters are optional");
+
var argValue = parameters[i].DefaultValue;
if (argValue == null)
{
@@ -7199,17 +7204,25 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target,
var psRefValue = Expression.Property(args[i].Expression.Cast(typeof(PSReference)), CachedReflectionInfo.PSReference_Value);
initTemps.Add(Expression.Assign(temp, psRefValue.Convert(temp.Type)));
copyOutTemps.Add(Expression.Assign(psRefValue, temp.Cast(typeof(object))));
+
argExprs[i] = temp;
+ argsToLog.Add(temp);
}
else
{
- argExprs[i] = args[i].CastOrConvertMethodArgument(
+ var convertedArg = args[i].CastOrConvertMethodArgument(
parameterType,
paramName,
mi.Name,
allowCastingToByRefLikeType,
temps,
initTemps);
+
+ argExprs[i] = convertedArg;
+ // If the converted arg is a byref-like type, then we log the original arg.
+ argsToLog.Add(convertedArg.Type.IsByRefLike
+ ? args[i].Expression
+ : convertedArg);
}
}
}
@@ -7255,6 +7268,12 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target,
}
}
+ // We need to add one expression to log the .NET invocation before actually invoking:
+ // - Log method invocation to AMSI Notifications (can throw PSSecurityException)
+ // - Invoke method
+ string targetName = mi.ReflectedType?.FullName ?? string.Empty;
+ string methodName = mi.Name is ".ctor" ? "new" : mi.Name;
+
if (temps.Count > 0)
{
if (call.Type != typeof(void) && copyOutTemps.Count > 0)
@@ -7265,8 +7284,13 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target,
copyOutTemps.Add(retValue);
}
+ AddMemberInvocationLogging(initTemps, targetName, methodName, argsToLog);
call = Expression.Block(call.Type, temps, initTemps.Append(call).Concat(copyOutTemps));
}
+ else
+ {
+ call = AddMemberInvocationLogging(call, targetName, methodName, argsToLog);
+ }
return call;
}
@@ -7559,21 +7583,22 @@ internal static void InvalidateCache()
}
#nullable enable
- private static Expression MaybeAddMemberInvocationLogging(
+ private static Expression AddMemberInvocationLogging(
Expression expr,
string targetName,
string name,
- DynamicMetaObject[] args)
+ List args)
{
-#if UNIX && !DEBUG
- // For efficiency this is a no-op on non-Windows platforms in release builds.
+#if UNIX
+ // For efficiency this is a no-op on non-Windows platforms.
return expr;
#else
- Expression[] invocationArgs = new Expression[args.Length];
- for (int i = 0; i < args.Length; i++)
+ Expression[] invocationArgs = new Expression[args.Count];
+ for (int i = 0; i < args.Count; i++)
{
- invocationArgs[i] = args[i].Expression.Cast(typeof(object));
+ invocationArgs[i] = args[i].Cast(typeof(object));
}
+
return Expression.Block(
Expression.Call(
CachedReflectionInfo.MemberInvocationLoggingOps_LogMemberInvocation,
@@ -7581,6 +7606,27 @@ private static Expression MaybeAddMemberInvocationLogging(
Expression.Constant(name),
Expression.NewArrayInit(typeof(object), invocationArgs)),
expr);
+#endif
+ }
+
+ private static void AddMemberInvocationLogging(
+ List exprs,
+ string targetName,
+ string name,
+ List args)
+ {
+#if !UNIX
+ Expression[] invocationArgs = new Expression[args.Count];
+ for (int i = 0; i < args.Count; i++)
+ {
+ invocationArgs[i] = args[i].Cast(typeof(object));
+ }
+
+ exprs.Add(Expression.Call(
+ CachedReflectionInfo.MemberInvocationLoggingOps_LogMemberInvocation,
+ Expression.Constant(targetName),
+ Expression.Constant(name),
+ Expression.NewArrayInit(typeof(object), invocationArgs)));
#endif
}
#nullable disable
diff --git a/src/System.Management.Automation/resources/SuggestionStrings.resx b/src/System.Management.Automation/resources/SuggestionStrings.resx
index ea249db55e7..9e325b2616c 100644
--- a/src/System.Management.Automation/resources/SuggestionStrings.resx
+++ b/src/System.Management.Automation/resources/SuggestionStrings.resx
@@ -123,6 +123,9 @@ PowerShell does not load commands from the current location by default (see 'Get
If you trust this command, run the following command instead:
+
+ The command "{0}" was not found, but does exist in the current location. PowerShell does not load commands from the current location by default. If you trust this command, instead type: "{1}". See "get-help about_Command_Precedence" for more details.
+
The most similar commands are:
diff --git a/src/System.Management.Automation/resources/TabCompletionStrings.resx b/src/System.Management.Automation/resources/TabCompletionStrings.resx
index 73399a6d6e8..c201facc3e2 100644
--- a/src/System.Management.Automation/resources/TabCompletionStrings.resx
+++ b/src/System.Management.Automation/resources/TabCompletionStrings.resx
@@ -329,6 +329,218 @@
Shift Right bit operator. Inserts zero in the left-most bit position. For signed values, sign bit is preserved.
+
+ [string]
+Specifies the name of the property being created.
+
+
+ [string]
+Specifies the name of the property being created.
+
+
+ [scriptblock]
+A script block used to calculate the value of the new property.
+
+
+ [string]
+Define how the values are displayed in a column.
+Valid values are 'left', 'center', or 'right'.
+
+
+ [string]
+Specifies a format string that defines how the value is formatted for output.
+
+
+ [int]
+Specifies the maximum column width in a table when the value is displayed.
+The value must be greater than 0.
+
+
+ [int]
+The depth key specifies the depth of expansion per property.
+
+
+ [bool]
+Specifies the order of sorting for one or more properties.
+
+
+ [bool]
+Specifies the order of sorting for one or more properties.
+
+
+ [String[]]
+Specifies the log names to get events from.
+Supports wildcards.
+
+
+ [String[]]
+Specifies the event log providers to get events from.
+Supports wildcards.
+
+
+ [String[]]
+Specifies file paths to log files to get events from.
+Valid file formats are: .etl, .evt, and .evtx
+
+
+ [Long[]]
+Selects events with the specified keyword bitmasks.
+The following are standard keywords:
+4503599627370496: AuditFailure
+9007199254740992: AuditSuccess
+4503599627370496: CorrelationHint
+18014398509481984: CorrelationHint2
+36028797018963968: EventLogClassic
+281474976710656: ResponseTime
+2251799813685248: Sqm
+562949953421312: WdiContext
+1125899906842624: WdiDiagnostic
+
+
+ [int[]]
+Selects events with the specified event IDs.
+
+
+ [int[]]
+Selects events with the specified log levels.
+The following log levels are valid:
+1: Critical
+2: Error
+3: Warning
+4: Informational
+5: Verbose
+
+
+ [datetime]
+Selects events created after the specified date and time.
+
+
+ [datetime]
+Selects events created before the specified date and time.
+
+
+ [string]
+Selects events generated by the specified user.
+This can either be a string representation of a SID or a domain and username in the format DOMAIN\USERNAME or USERNAME@DOMAIN
+
+
+ [string[]]
+Selects events with any of the specified values in the EventData section.
+
+
+ [hashtable]
+Excludes events that match the values specified in the hashtable.
+
+
+ [string] or [hashtable]
+Specifies an array of PowerShell modules that the script requires.
+Each element can either be a string with the module name as value or a hashtable with the following keys:
+Name: Name of the module
+GUID: GUID of the module
+One of the following:
+ModuleVersion: Specifies a minimum acceptable version of the module.
+RequiredVersion: Specifies an exact, required version of the module.
+MaximumVersion: Specifies the maximum acceptable version of the module.
+
+
+ [string]
+Specifies a PowerShell edition that the script requires.
+Valid values are "Core" and "Desktop"
+
+
+ [switch]
+Specifies that PowerShell must be running as administrator on Windows.
+This must be the last parameter on the #requires statement line.
+
+
+ [version]
+Specifies the minimum version of PowerShell that the script requires.
+
+
+ Specifies that the script requires PowerShell Core to run.
+
+
+ Specifies that the script requires Windows PowerShell to run.
+
+
+ [string]
+Required. Specifies the module name.
+
+
+ [string]
+Optional. Specifies the GUID of the module.
+
+
+ [string]
+Specifies a minimum acceptable version of the module.
+
+
+ [string]
+Specifies an exact, required version of the module.
+
+
+ [string]
+Specifies the maximum acceptable version of the module.
+
+
+ A brief description of the function or script.
+This keyword can be used only once in each topic.
+
+
+ A detailed description of the function or script.
+This keyword can be used only once in each topic.
+
+
+ .PARAMETER <Parameter-Name>
+The description of a parameter.
+Add a .PARAMETER keyword for each parameter in the function or script syntax.
+
+
+ A sample command that uses the function or script, optionally followed by sample output and a description.
+Repeat this keyword for each example.
+
+
+ The .NET types of objects that can be piped to the function or script.
+You can also include a description of the input objects.
+
+
+ The .NET type of the objects that the cmdlet returns.
+You can also include a description of the returned objects.
+
+
+ Additional information about the function or script.
+
+
+ The name of a related topic.
+Repeat the .LINK keyword for each related topic.
+The .Link keyword content can also include a URI to an online version of the same help topic.
+
+
+ The name of the technology or feature that the function or script uses, or to which it is related.
+
+
+ The name of the user role for the help topic.
+
+
+ The keywords that describe the intended use of the function.
+
+
+ .FORWARDHELPTARGETNAME <Command-Name>
+Redirects to the help topic for the specified command.
+
+
+ .FORWARDHELPCATEGORY <Category>
+Specifies the help category of the item in .ForwardHelpTargetName
+
+
+ .REMOTEHELPRUNSPACE <PSSession-variable>
+Specifies a session that contains the help topic.
+Enter a variable that contains a PSSession object.
+
+
+ .EXTERNALHELP <XML Help File>
+The .ExternalHelp keyword is required when a function or script is documented in XML files.
+
Specifies the path to a .NET assembly to load.
diff --git a/src/System.Management.Automation/security/wldpNativeMethods.cs b/src/System.Management.Automation/security/wldpNativeMethods.cs
index a59f37c0a8f..ab49f927614 100644
--- a/src/System.Management.Automation/security/wldpNativeMethods.cs
+++ b/src/System.Management.Automation/security/wldpNativeMethods.cs
@@ -6,6 +6,7 @@
//
#if !UNIX
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation.Internal;
using System.Management.Automation.Runspaces;
@@ -148,7 +149,7 @@ public static SystemEnforcementMode GetSystemLockdownPolicy()
{
lock (s_systemLockdownPolicyLock)
{
- s_systemLockdownPolicy = GetDebugLockdownPolicy(path: null);
+ s_systemLockdownPolicy = GetDebugLockdownPolicy(path: null, out _);
}
}
@@ -172,93 +173,89 @@ public static SystemScriptFileEnforcement GetFilePolicyEnforcement(
System.IO.FileStream fileStream)
{
SafeHandle fileHandle = fileStream.SafeFileHandle;
- var systemLockdownPolicy = SystemPolicy.GetSystemLockdownPolicy();
+ SystemEnforcementMode systemLockdownPolicy = GetSystemLockdownPolicy();
// First check latest WDAC APIs if available.
- // Revert to legacy APIs if system policy is in AUDIT mode or debug hook is in effect.
- Exception errorException = null;
- if (s_wldpCanExecuteAvailable && systemLockdownPolicy == SystemEnforcementMode.Enforce)
+ if (systemLockdownPolicy is SystemEnforcementMode.Enforce
+ && s_wldpCanExecuteAvailable
+ && TryGetWldpCanExecuteFileResult(filePath, fileHandle, out SystemScriptFileEnforcement wldpFilePolicy))
{
- try
- {
- string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
- string auditMsg = $"PowerShell ExternalScriptInfo reading file: {fileName}";
+ return GetLockdownPolicy(filePath, fileHandle, wldpFilePolicy);
+ }
- int hr = WldpNativeMethods.WldpCanExecuteFile(
- host: PowerShellHost,
- options: WLDP_EXECUTION_EVALUATION_OPTIONS.WLDP_EXECUTION_EVALUATION_OPTION_NONE,
- fileHandle: fileHandle.DangerousGetHandle(),
- auditInfo: auditMsg,
- result: out WLDP_EXECUTION_POLICY canExecuteResult);
+ // Failed to invoke WldpCanExecuteFile, revert to legacy APIs.
+ if (systemLockdownPolicy is SystemEnforcementMode.None)
+ {
+ return SystemScriptFileEnforcement.None;
+ }
- PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile", filePath, hr, (int)canExecuteResult);
+ // WldpCanExecuteFile was invoked successfully so we can skip running
+ // legacy WDAC APIs. AppLocker must still be checked in case it is more
+ // strict than the current WDAC policy.
+ return GetLockdownPolicy(filePath, fileHandle, canExecuteResult: null);
+ }
- if (hr >= 0)
- {
- switch (canExecuteResult)
- {
- case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_ALLOWED:
- return SystemScriptFileEnforcement.Allow;
+ private static SystemScriptFileEnforcement ConvertToModernFileEnforcement(SystemEnforcementMode legacyMode)
+ {
+ return legacyMode switch
+ {
+ SystemEnforcementMode.None => SystemScriptFileEnforcement.Allow,
+ SystemEnforcementMode.Audit => SystemScriptFileEnforcement.AllowConstrainedAudit,
+ SystemEnforcementMode.Enforce => SystemScriptFileEnforcement.AllowConstrained,
+ _ => SystemScriptFileEnforcement.Block,
+ };
+ }
- case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_BLOCKED:
- return SystemScriptFileEnforcement.Block;
+ private static bool TryGetWldpCanExecuteFileResult(string filePath, SafeHandle fileHandle, out SystemScriptFileEnforcement result)
+ {
+ try
+ {
+ string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
+ string auditMsg = $"PowerShell ExternalScriptInfo reading file: {fileName}";
- case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_REQUIRE_SANDBOX:
- return SystemScriptFileEnforcement.AllowConstrained;
+ int hr = WldpNativeMethods.WldpCanExecuteFile(
+ host: PowerShellHost,
+ options: WLDP_EXECUTION_EVALUATION_OPTIONS.WLDP_EXECUTION_EVALUATION_OPTION_NONE,
+ fileHandle: fileHandle.DangerousGetHandle(),
+ auditInfo: auditMsg,
+ result: out WLDP_EXECUTION_POLICY canExecuteResult);
- default:
- // Fall through to legacy system policy checks.
- System.Diagnostics.Debug.Assert(false, $"Unknown execution policy returned from WldCanExecute: {canExecuteResult}");
- break;
- }
- }
+ PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile", filePath, hr, (int)canExecuteResult);
- // If HResult is unsuccessful (such as E_NOTIMPL (0x80004001)), fall through to legacy system checks.
- }
- catch (DllNotFoundException ex)
- {
- // Fall back to legacy system policy checks.
- s_wldpCanExecuteAvailable = false;
- errorException = ex;
- }
- catch (EntryPointNotFoundException ex)
+ if (hr >= 0)
{
- // Fall back to legacy system policy checks.
- s_wldpCanExecuteAvailable = false;
- errorException = ex;
+ switch (canExecuteResult)
+ {
+ case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_ALLOWED:
+ result = SystemScriptFileEnforcement.Allow;
+ return true;
+
+ case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_BLOCKED:
+ result = SystemScriptFileEnforcement.Block;
+ return true;
+
+ case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_REQUIRE_SANDBOX:
+ result = SystemScriptFileEnforcement.AllowConstrained;
+ return true;
+
+ default:
+ // Fall through to legacy system policy checks.
+ Debug.Assert(false, $"Unknown policy result returned from WldCanExecute: {canExecuteResult}");
+ break;
+ }
}
- if (errorException != null)
- {
- PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile_Failed", filePath, errorException.HResult, 0);
- }
+ // If HResult is unsuccessful (such as E_NOTIMPL (0x80004001)), fall through to legacy system checks.
}
-
- // Original (legacy) WDAC and AppLocker system checks.
- if (systemLockdownPolicy == SystemEnforcementMode.None)
+ catch (Exception ex) when (ex is DllNotFoundException or EntryPointNotFoundException)
{
- return SystemScriptFileEnforcement.None;
+ // Fall back to legacy system policy checks.
+ s_wldpCanExecuteAvailable = false;
+ PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile_Failed", filePath, ex.HResult, 0);
}
- // Check policy for file.
- switch (SystemPolicy.GetLockdownPolicy(filePath, fileHandle))
- {
- case SystemEnforcementMode.Enforce:
- // File is not allowed by policy enforcement and must run in CL mode.
- return SystemScriptFileEnforcement.AllowConstrained;
-
- case SystemEnforcementMode.Audit:
- // File is allowed but would be run in CL mode if policy was enforced and not audit.
- return SystemScriptFileEnforcement.AllowConstrainedAudit;
-
- case SystemEnforcementMode.None:
- // No restrictions, file will run in FL mode.
- return SystemScriptFileEnforcement.Allow;
-
- default:
- System.Diagnostics.Debug.Assert(false, "GetFilePolicyEnforcement: Unknown SystemEnforcementMode.");
- return SystemScriptFileEnforcement.Block;
- }
+ result = default;
+ return false;
}
///
@@ -267,9 +264,32 @@ public static SystemScriptFileEnforcement GetFilePolicyEnforcement(
/// An EnforcementMode that describes policy.
public static SystemEnforcementMode GetLockdownPolicy(string path, SafeHandle handle)
{
+ SystemScriptFileEnforcement modernMode = GetLockdownPolicy(path, handle, canExecuteResult: null);
+ Debug.Assert(
+ modernMode is not SystemScriptFileEnforcement.Block,
+ "Block should never be converted to legacy file enforcement.");
+
+ return modernMode switch
+ {
+ SystemScriptFileEnforcement.Block => SystemEnforcementMode.Enforce,
+ SystemScriptFileEnforcement.AllowConstrained => SystemEnforcementMode.Enforce,
+ SystemScriptFileEnforcement.AllowConstrainedAudit => SystemEnforcementMode.Audit,
+ SystemScriptFileEnforcement.Allow => SystemEnforcementMode.None,
+ SystemScriptFileEnforcement.None => SystemEnforcementMode.None,
+ _ => throw new ArgumentOutOfRangeException(nameof(modernMode)),
+ };
+ }
+
+ private static SystemScriptFileEnforcement GetLockdownPolicy(
+ string path,
+ SafeHandle handle,
+ SystemScriptFileEnforcement? canExecuteResult)
+ {
+ SystemScriptFileEnforcement wldpFilePolicy = canExecuteResult
+ ?? ConvertToModernFileEnforcement(GetWldpPolicy(path, handle));
+
// Check the WLDP File policy via API
- var wldpFilePolicy = GetWldpPolicy(path, handle);
- if (wldpFilePolicy == SystemEnforcementMode.Enforce)
+ if (wldpFilePolicy is SystemScriptFileEnforcement.Block or SystemScriptFileEnforcement.AllowConstrained)
{
return wldpFilePolicy;
}
@@ -281,29 +301,28 @@ public static SystemEnforcementMode GetLockdownPolicy(string path, SafeHandle ha
var appLockerFilePolicy = GetAppLockerPolicy(path, handle);
if (appLockerFilePolicy == SystemEnforcementMode.Enforce)
{
- return appLockerFilePolicy;
+ return ConvertToModernFileEnforcement(appLockerFilePolicy);
}
// At this point, LockdownPolicy = Audit or Allowed.
// If there was a WLDP policy, but WLDP didn't block it,
// then it was explicitly allowed. Therefore, return the result for the file.
- SystemEnforcementMode systemWldpPolicy = s_cachedWldpSystemPolicy.GetValueOrDefault(SystemEnforcementMode.None);
- if ((systemWldpPolicy == SystemEnforcementMode.Audit) ||
- (systemWldpPolicy == SystemEnforcementMode.Enforce))
+ if (s_cachedWldpSystemPolicy is SystemEnforcementMode.Audit or SystemEnforcementMode.Enforce
+ || wldpFilePolicy is SystemScriptFileEnforcement.AllowConstrainedAudit)
{
return wldpFilePolicy;
}
// If there was a system-wide AppLocker policy, but AppLocker didn't block it,
// then return AppLocker's status.
- if (s_cachedSaferSystemPolicy.GetValueOrDefault(SaferPolicy.Allowed) ==
- SaferPolicy.Disallowed)
+ if (s_cachedSaferSystemPolicy is SaferPolicy.Disallowed)
{
- return appLockerFilePolicy;
+ return ConvertToModernFileEnforcement(appLockerFilePolicy);
}
// If it's not set to 'Enforce' by the platform, allow debug overrides
- return GetDebugLockdownPolicy(path);
+ GetDebugLockdownPolicy(path, out SystemScriptFileEnforcement debugPolicy);
+ return debugPolicy;
}
[SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods",
@@ -558,7 +577,7 @@ private static SaferPolicy TestSaferPolicy(string testPathScript, string testPat
return result;
}
- private static SystemEnforcementMode GetDebugLockdownPolicy(string path)
+ private static SystemEnforcementMode GetDebugLockdownPolicy(string path, out SystemScriptFileEnforcement modernEnforcement)
{
s_allowDebugOverridePolicy = true;
@@ -569,10 +588,19 @@ private static SystemEnforcementMode GetDebugLockdownPolicy(string path)
// check so that we can actually put it in the filename during testing.
if (path.Contains("System32", StringComparison.OrdinalIgnoreCase))
{
+ modernEnforcement = SystemScriptFileEnforcement.Allow;
return SystemEnforcementMode.None;
}
// No explicit debug allowance for the file, so return the system policy if there is one.
+ modernEnforcement = s_systemLockdownPolicy switch
+ {
+ SystemEnforcementMode.Enforce => SystemScriptFileEnforcement.AllowConstrained,
+ SystemEnforcementMode.Audit => SystemScriptFileEnforcement.AllowConstrainedAudit,
+ SystemEnforcementMode.None => SystemScriptFileEnforcement.None,
+ _ => SystemScriptFileEnforcement.None,
+ };
+
return s_systemLockdownPolicy.GetValueOrDefault(SystemEnforcementMode.None);
}
@@ -582,10 +610,13 @@ private static SystemEnforcementMode GetDebugLockdownPolicy(string path)
if (result != null)
{
pdwLockdownState = LanguagePrimitives.ConvertTo(result);
- return GetLockdownPolicyForResult(pdwLockdownState);
+ SystemEnforcementMode policy = GetLockdownPolicyForResult(pdwLockdownState);
+ modernEnforcement = ConvertToModernFileEnforcement(policy);
+ return policy;
}
// If the system-wide debug policy had no preference, then there is no enforcement.
+ modernEnforcement = SystemScriptFileEnforcement.None;
return SystemEnforcementMode.None;
}
diff --git a/src/System.Management.Automation/utils/PsUtils.cs b/src/System.Management.Automation/utils/PsUtils.cs
index 53809e586a0..d404581bf1f 100644
--- a/src/System.Management.Automation/utils/PsUtils.cs
+++ b/src/System.Management.Automation/utils/PsUtils.cs
@@ -74,12 +74,12 @@ internal static Process GetParentProcess(Process current)
}
///
- /// Return true/false to indicate whether the processor architecture is ARM.
+ /// Return true/false to indicate whether the process architecture is ARM.
///
///
- internal static bool IsRunningOnProcessorArchitectureARM()
+ internal static bool IsRunningOnProcessArchitectureARM()
{
- Architecture arch = RuntimeInformation.OSArchitecture;
+ Architecture arch = RuntimeInformation.ProcessArchitecture;
return arch == Architecture.Arm || arch == Architecture.Arm64;
}
diff --git a/src/System.Management.Automation/utils/Telemetry.cs b/src/System.Management.Automation/utils/Telemetry.cs
index f611c36bf23..13a8d7d5ec5 100644
--- a/src/System.Management.Automation/utils/Telemetry.cs
+++ b/src/System.Management.Automation/utils/Telemetry.cs
@@ -636,7 +636,7 @@ static ApplicationInsightsTelemetry()
s_knownSubsystemNames = new HashSet(StringComparer.OrdinalIgnoreCase)
{
"Completion",
- "general",
+ "General Feedback",
"Windows Package Manager - WinGet",
"Az Predictor"
};
diff --git a/src/System.Management.Automation/utils/Verbs.cs b/src/System.Management.Automation/utils/Verbs.cs
index 14a43dca6d0..72299ab3d84 100644
--- a/src/System.Management.Automation/utils/Verbs.cs
+++ b/src/System.Management.Automation/utils/Verbs.cs
@@ -1550,7 +1550,7 @@ private static IEnumerable CompleteVerbWithGroups(string wordT
{
if (GroupsContainVerbType(groups, verbType))
{
- foreach (CompletionResult result in CompletionCompleters.GetMatchingResults(
+ foreach (CompletionResult result in CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: EnumerateFieldNamesFromVerbType(verbType)))
{
@@ -1567,7 +1567,7 @@ private static IEnumerable CompleteVerbWithGroups(string wordT
/// The list of commands.
/// List of completions for verb.
private static IEnumerable CompleteVerbWithCommands(string wordToComplete, Collection commands)
- => CompletionCompleters.GetMatchingResults(
+ => CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: EnumerateCommandVerbNames(commands));
@@ -1577,7 +1577,7 @@ private static IEnumerable CompleteVerbWithCommands(string wor
/// The word to complete.
/// List of completions for verb.
private static IEnumerable CompleteVerbForAllTypes(string wordToComplete)
- => CompletionCompleters.GetMatchingResults(
+ => CompletionHelpers.GetMatchingResults(
wordToComplete,
possibleCompletionValues: EnumerateFieldNamesFromAllVerbTypes());
}
diff --git a/src/TypeCatalogGen/TypeCatalogGen.csproj b/src/TypeCatalogGen/TypeCatalogGen.csproj
index 56db232548a..ffc3ff99986 100644
--- a/src/TypeCatalogGen/TypeCatalogGen.csproj
+++ b/src/TypeCatalogGen/TypeCatalogGen.csproj
@@ -2,7 +2,7 @@
Generates CorePsTypeCatalog.cs given powershell.inc
- net9.0
+ net10.0
true
TypeCatalogGen
Exe
diff --git a/test/Test.Common.props b/test/Test.Common.props
index e28b916f738..3fafbbf8f85 100644
--- a/test/Test.Common.props
+++ b/test/Test.Common.props
@@ -6,7 +6,7 @@
Microsoft Corporation
(c) Microsoft Corporation.
- net9.0
+ net10.0
13.0
true
diff --git a/test/hosting/hosting.tests.csproj b/test/hosting/hosting.tests.csproj
index cb72e0a90ef..1c40094c7ff 100644
--- a/test/hosting/hosting.tests.csproj
+++ b/test/hosting/hosting.tests.csproj
@@ -21,6 +21,12 @@
+
+
+
+
+
+
diff --git a/test/powershell/Host/TabCompletion/BugFix.Tests.ps1 b/test/powershell/Host/TabCompletion/BugFix.Tests.ps1
index e0ec96aa87b..32fd73f8c09 100644
--- a/test/powershell/Host/TabCompletion/BugFix.Tests.ps1
+++ b/test/powershell/Host/TabCompletion/BugFix.Tests.ps1
@@ -43,6 +43,28 @@ Describe "Tab completion bug fix" -Tags "CI" {
$result[0].CompletionText | Should -BeExactly '$ErrorActionPreference'
}
+ It "Issue#24756 - Wildcard completions should not return early due to missing results in one container" -Skip:(!$IsWindows) {
+ try
+ {
+ $keys = New-Item -Path @(
+ 'HKCU:\AB1'
+ 'HKCU:\AB2'
+ 'HKCU:\AB2\Test'
+ )
+
+ $res = TabExpansion2 -inputScript 'Get-ChildItem -Path HKCU:\AB?\'
+ $res.CompletionMatches.Count | Should -Be 1
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly "HKCU:\AB2\Test"
+ }
+ finally
+ {
+ if ($keys)
+ {
+ Remove-Item -Path HKCU:\AB? -Recurse -ErrorAction SilentlyContinue
+ }
+ }
+ }
+
Context "Issue#3416 - 'Select-Object'" {
BeforeAll {
$DatetimeProperties = @((Get-Date).psobject.baseobject.psobject.properties) | Sort-Object -Property Name
diff --git a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1
index b7e8669b765..c7d6ee744e0 100644
--- a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1
+++ b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1
@@ -33,6 +33,37 @@ Describe "TabCompletion" -Tags CI {
$res.CompletionMatches[0].CompletionText | Should -BeExactly 'notepad.exe'
}
+ It 'Should not include duplicate command results' {
+ $OldModulePath = $env:PSModulePath
+ $tempDir = Join-Path -Path $TestDrive -ChildPath "TempPsModuleDir"
+ try
+ {
+ $ModuleDirs = @(
+ Join-Path $tempDir "TestModule1\1.0"
+ Join-Path $tempDir "TestModule1\1.1"
+ Join-Path $tempDir "TestModule2\1.0"
+ )
+ foreach ($Dir in $ModuleDirs)
+ {
+ $NewDir = New-Item -Path $Dir -ItemType Directory -Force
+ $ModuleName = $NewDir.Parent.Name
+ Set-Content -Value 'MyTestFunction{}' -LiteralPath "$($NewDir.FullName)\$ModuleName.psm1"
+ New-ModuleManifest -Path "$($NewDir.FullName)\$ModuleName.psd1" -RootModule "$ModuleName.psm1" -FunctionsToExport "MyTestFunction" -ModuleVersion $NewDir.Name
+ }
+
+ $env:PSModulePath += [System.IO.Path]::PathSeparator + $tempDir
+ $Res = TabExpansion2 -inputScript MyTestFunction
+ $Res.CompletionMatches.Count | Should -Be 2
+ $SortedMatches = $Res.CompletionMatches.CompletionText | Sort-Object
+ $SortedMatches[0] | Should -Be "TestModule1\MyTestFunction"
+ $SortedMatches[1] | Should -Be "TestModule2\MyTestFunction"
+ }
+ finally
+ {
+ $env:PSModulePath = $OldModulePath
+ }
+ }
+
It 'Should complete dotnet method' {
$res = TabExpansion2 -inputScript '(1).ToSt' -cursorColumn '(1).ToSt'.Length
$res.CompletionMatches[0].CompletionText | Should -BeExactly 'ToString('
@@ -104,6 +135,34 @@ Describe "TabCompletion" -Tags CI {
$res = TabExpansion2 -inputScript 'param($PS = $P'
$res.CompletionMatches.Count | Should -BeGreaterThan 0
}
+
+ It 'Should complete variable with description and value ' -TestCases @(
+ @{ Value = 1; Expected = '[int]$VariableWithDescription - Variable description' }
+ @{ Value = 'string'; Expected = '[string]$VariableWithDescription - Variable description' }
+ @{ Value = $null; Expected = 'VariableWithDescription - Variable description' }
+ ) {
+ param ($Value, $Expected)
+
+ New-Variable -Name VariableWithDescription -Value $Value -Description 'Variable description' -Force
+ $res = TabExpansion2 -inputScript '$VariableWithDescription'
+ $res.CompletionMatches.Count | Should -Be 1
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '$VariableWithDescription'
+ $res.CompletionMatches[0].ToolTip | Should -BeExactly $Expected
+ }
+
+ It 'Should complete scoped variable with description and value ' -TestCases @(
+ @{ Value = 1; Expected = '[int]$VariableWithDescription - Variable description' }
+ @{ Value = 'string'; Expected = '[string]$VariableWithDescription - Variable description' }
+ @{ Value = $null; Expected = 'VariableWithDescription - Variable description' }
+ ) {
+ param ($Value, $Expected)
+
+ New-Variable -Name VariableWithDescription -Value $Value -Description 'Variable description' -Force
+ $res = TabExpansion2 -inputScript '$local:VariableWithDescription'
+ $res.CompletionMatches.Count | Should -Be 1
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '$local:VariableWithDescription'
+ $res.CompletionMatches[0].ToolTip | Should -BeExactly $Expected
+ }
It 'Should not complete property name in class definition' {
$res = TabExpansion2 -inputScript 'class X {$P'
@@ -118,6 +177,122 @@ Describe "TabCompletion" -Tags CI {
}
}
+ context CustomProviderTests {
+ BeforeAll {
+ $testModulePath = Join-Path $TestDrive "ReproModule"
+ New-Item -Path $testModulePath -ItemType Directory > $null
+
+ New-ModuleManifest -Path "$testModulePath/ReproModule.psd1" -RootModule 'testmodule.dll'
+
+ $testBinaryModulePath = Join-Path $testModulePath "testmodule.dll"
+ $binaryModule = @'
+using System;
+using System.Linq;
+using System.Management.Automation;
+using System.Management.Automation.Provider;
+
+namespace BugRepro
+{
+ public class IntItemInfo
+ {
+ public string Name;
+ public IntItemInfo(string name) => Name = name;
+ }
+
+ [CmdletProvider("Int", ProviderCapabilities.None)]
+ public class IntProvider : NavigationCmdletProvider
+ {
+ public static string[] ToChunks(string path) => path.Split("/", StringSplitOptions.RemoveEmptyEntries);
+
+ protected string _ChildName(string path)
+ {
+ var name = ToChunks(path).LastOrDefault();
+ return name ?? string.Empty;
+ }
+
+ protected string Normalize(string path) => string.Join("/", ToChunks(path));
+
+ protected override string GetChildName(string path)
+ {
+ var name = _ChildName(path);
+ // if (!IsItemContainer(path)) { return string.Empty; }
+ return name;
+ }
+
+ protected override bool IsValidPath(string path) => int.TryParse(GetChildName(path), out int _);
+
+ protected override bool IsItemContainer(string path)
+ {
+ var name = _ChildName(path);
+ if (!int.TryParse(name, out int value))
+ {
+ return false;
+ }
+ if (ToChunks(path).Count() > 3)
+ {
+ return false;
+ }
+ return value % 2 == 0;
+ }
+
+ protected override bool ItemExists(string path)
+ {
+ foreach (var chunk in ToChunks(path))
+ {
+ if (!int.TryParse(chunk, out int value))
+ {
+ return false;
+ }
+ if (value < 0 || value > 9)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected override void GetItem(string path)
+ {
+ var name = GetChildName(path);
+ if (!int.TryParse(name, out int _))
+ {
+ return;
+ }
+ WriteItemObject(new IntItemInfo(name), path, IsItemContainer(path));
+ }
+ protected override bool HasChildItems(string path) => IsItemContainer(path);
+
+ protected override void GetChildItems(string path, bool recurse)
+ {
+ if (!IsItemContainer(path)) { GetItem(path); return; }
+
+ for (var i = 0; i <= 9; i++)
+ {
+ var _path = $"{Normalize(path)}/{i}";
+ if (recurse)
+ {
+ GetChildItems(_path, recurse);
+ }
+ else
+ {
+ GetItem(_path);
+ }
+ }
+ }
+ }
+}
+'@
+ Add-Type -OutputAssembly $testBinaryModulePath -TypeDefinition $binaryModule
+
+ $pwsh = "$PSHOME\pwsh"
+ }
+
+ It "Should not complete invalid items when a provider path returns itself instead of its children" {
+ $result = & $pwsh -NoProfile -Command "Import-Module -Name $testModulePath; (TabExpansion2 'Get-ChildItem Int::/2/3/').CompletionMatches.Count"
+ $result | Should -BeExactly "0"
+ }
+ }
+
It 'should complete index expression for ' -TestCases @(
@{
Intent = 'Hashtable with no user input'
@@ -320,6 +495,21 @@ switch ($x)
$res.CompletionMatches.Count | Should -Be 0
}
+ It 'Should complete variable assigned in command redirection to variable' {
+ $res = TabExpansion2 -inputScript 'New-Guid 1>variable:Redir1 2>variable:Redir2 3>variable:Redir3 4>variable:Redir4 5>variable:Redir5 6>variable:Redir6; $Redir'
+ $res.CompletionMatches[0].CompletionText | Should -Be '$Redir1'
+ $res.CompletionMatches[1].CompletionText | Should -Be '$Redir2'
+ $res.CompletionMatches[1].ToolTip | Should -Be '[ErrorRecord]$Redir2'
+ $res.CompletionMatches[2].CompletionText | Should -Be '$Redir3'
+ $res.CompletionMatches[2].ToolTip | Should -Be '[WarningRecord]$Redir3'
+ $res.CompletionMatches[3].CompletionText | Should -Be '$Redir4'
+ $res.CompletionMatches[3].ToolTip | Should -Be '[VerboseRecord]$Redir4'
+ $res.CompletionMatches[4].CompletionText | Should -Be '$Redir5'
+ $res.CompletionMatches[4].ToolTip | Should -Be '[DebugRecord]$Redir5'
+ $res.CompletionMatches[5].CompletionText | Should -Be '$Redir6'
+ $res.CompletionMatches[5].ToolTip | Should -Be '[InformationRecord]$Redir6'
+ }
+
context TypeConstructionWithHashtable {
BeforeAll {
class RandomTestType {
@@ -489,6 +679,21 @@ using `
$res.CompletionMatches[0].CompletionText | Should -Be '"Classic"'
}
+ It 'Should work for variable assignment of enum type with type inference' {
+ $res = TabExpansion2 -inputScript '[System.Management.Automation.ProgressView]$MyUnassignedVar = $psstyle.Progress.View; $MyUnassignedVar = "Class'
+ $res.CompletionMatches[0].CompletionText | Should -Be '"Classic"'
+ }
+
+ It 'Should work for property assignment of enum type with type inference with PowerShell class' {
+ $res = TabExpansion2 -inputScript 'enum Animals{Cat= 0;Dog= 1};class AnimalTestClass{[Animals] $Prop1};$Test1 = [AnimalTestClass]::new();$Test1.Prop1 = "C'
+ $res.CompletionMatches[0].CompletionText | Should -Be '"Cat"'
+ }
+
+ It 'Should work for variable assignment with type inference of PowerShell Enum' {
+ $res = TabExpansion2 -inputScript 'enum Animals{Cat= 0;Dog= 1}; [Animals]$TestVar1 = "D'
+ $res.CompletionMatches[0].CompletionText | Should -Be '"Dog"'
+ }
+
It 'Should work for variable assignment of enum type: ' -TestCases @(
@{ inputStr = '$ErrorActionPreference = '; filter = ''; doubleQuotes = $false }
@{ inputStr = '$ErrorActionPreference='; filter = ''; doubleQuotes = $false }
@@ -632,6 +837,11 @@ using `
$res.CompletionMatches.CompletionText | Should -Contain "GetType"
}
+ It 'Should complete variable member inferred from command inside scriptblock' {
+ $res = TabExpansion2 -inputScript '& {(New-Guid).'
+ $res.CompletionMatches.Count | Should -BeGreaterThan 0
+ }
+
It 'Should not complete void instance members' {
$res = TabExpansion2 -inputScript '([void]("")).'
$res.CompletionMatches | Should -BeNullOrEmpty
@@ -644,6 +854,20 @@ using `
$completionText -join ' ' | Should -BeExactly 'Equals( new( ReferenceEquals('
}
+ It 'Should complete variables assigned inside do while loop' {
+ $TestString = 'do{$Var1 = 1; $Var^ }while ($true)'
+ $CursorIndex = $TestString.IndexOf('^')
+ $res = TabExpansion2 -cursorColumn $CursorIndex -inputScript $TestString.Remove($CursorIndex, 1)
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '$Var1'
+ }
+
+ It 'Should complete variables assigned inside do until loop' {
+ $TestString = 'do{$Var1 = 1; $Var^ }until ($null = Get-ChildItem)'
+ $CursorIndex = $TestString.IndexOf('^')
+ $res = TabExpansion2 -cursorColumn $CursorIndex -inputScript $TestString.Remove($CursorIndex, 1)
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '$Var1'
+ }
+
It 'Should show multiple constructors in the tooltip' {
$res = TabExpansion2 -inputScript 'class ConstructorTestClass{ConstructorTestClass ([string] $s){}ConstructorTestClass ([int] $i){}ConstructorTestClass ([int] $i, [bool]$b){}};[ConstructorTestClass]::new'
$res.CompletionMatches | Should -HaveCount 1
@@ -677,6 +901,36 @@ ConstructorTestClass(int i, bool b)
$diffs | Should -BeNullOrEmpty
}
+ It 'Should complete attribute argument in incomplete param block' {
+ $res = TabExpansion2 -inputScript 'param([ValidatePattern('
+ $Expected = ([ValidatePattern].GetProperties() | Where-Object {$_.CanWrite}).Name -join ','
+ $res.CompletionMatches.CompletionText -join ',' | Should -BeExactly $Expected
+ }
+
+ It 'Should complete attribute argument in incomplete param block on new line' {
+ $TestString = @'
+param([ValidatePattern(
+^)])
+'@
+ $CursorIndex = $TestString.IndexOf('^')
+ $res = TabExpansion2 -cursorColumn $CursorIndex -inputScript $TestString.Remove($CursorIndex, 1)
+ $Expected = ([ValidatePattern].GetProperties() | Where-Object {$_.CanWrite}).Name -join ','
+ $res.CompletionMatches.CompletionText -join ',' | Should -BeExactly $Expected
+ }
+
+ It 'Should complete attribute argument with partially written name in incomplete param block' {
+ $TestString = 'param([ValidatePattern(op^)]'
+ $CursorIndex = $TestString.IndexOf('^')
+ $res = TabExpansion2 -cursorColumn $CursorIndex -inputScript $TestString.Remove($CursorIndex, 1)
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly 'Options'
+ }
+
+ It 'Should complete attribute argument for incomplete standalone attribute' {
+ $res = TabExpansion2 -inputScript '[ValidatePattern('
+ $Expected = ([ValidatePattern].GetProperties() | Where-Object {$_.CanWrite}).Name -join ','
+ $res.CompletionMatches.CompletionText -join ',' | Should -BeExactly $Expected
+ }
+
It 'Should complete argument for second parameter' {
$res = TabExpansion2 -inputScript 'Get-ChildItem -Path $HOME -ErrorAction '
$res.CompletionMatches[0].CompletionText | Should -BeExactly Break
@@ -699,6 +953,16 @@ ConstructorTestClass(int i, bool b)
$res.CompletionMatches[0].CompletionText | Should -BeExactly '$MyDataVar'
}
+ It 'Should complete global variable without scope' {
+ $res = TabExpansion2 -inputScript '$Global:MyTestVar = "Hello";$MyTestV'
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '$MyTestVar'
+ }
+
+ It 'Should complete previously assigned variable in using: scope' {
+ $res = TabExpansion2 -inputScript '$MyTestVar = "Hello";$Using:MyTestv'
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '$Using:MyTestVar'
+ }
+
it 'Should complete "Value" parameter value in "Where-Object" for Enum property with no input' {
$res = TabExpansion2 -inputScript 'Get-Command | where-Object CommandType -eq '
$res.CompletionMatches[0].CompletionText | Should -BeExactly Alias
@@ -1519,6 +1783,36 @@ class InheritedClassTest : System.Attribute
}
}
+ Context "Script parameter completion" {
+ BeforeAll {
+ Setup -File -Path 'ModuleReqTest.ps1' -Content @'
+#requires -Modules ThisModuleDoesNotExist
+param ($Param1)
+'@
+ Setup -File -Path 'AdminReqTest.ps1' -Content @'
+#requires -RunAsAdministrator
+param ($Param1)
+'@
+ Push-Location ${TestDrive}\
+ }
+
+ AfterAll {
+ Pop-Location
+ }
+
+ It "Input should successfully complete script parameter for script with failed script requirements" {
+ $res = TabExpansion2 -inputScript '.\ModuleReqTest.ps1 -'
+ $res.CompletionMatches.Count | Should -BeGreaterThan 0
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '-Param1'
+ }
+
+ It "Input should successfully complete script parameter for admin script while not elevated" {
+ $res = TabExpansion2 -inputScript '.\AdminReqTest.ps1 -'
+ $res.CompletionMatches.Count | Should -BeGreaterThan 0
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly '-Param1'
+ }
+ }
+
Context "File name completion" {
BeforeAll {
$tempDir = Join-Path -Path $TestDrive -ChildPath "baseDir"
@@ -1690,6 +1984,34 @@ class InheritedClassTest : System.Attribute
$res.CompletionMatches[0].CompletionText | Should -Be "`"$expectedPath`""
}
+ It "Relative path completion for using statement when AST extent has file identity" -TestCases @(
+ @{UsingKind = "module"; ExpectedFileName = 'UsingFileCompletionModuleTest.psm1'}
+ @{UsingKind = "assembly";ExpectedFileName = 'UsingFileCompletionAssemblyTest.dll'}
+ ) -test {
+ param($UsingKind, $ExpectedFileName)
+ $scriptText = "using $UsingKind .\UsingFileCompletion"
+ $tokens = $null
+ $scriptAst = [System.Management.Automation.Language.Parser]::ParseInput(
+ $scriptText,
+ (Join-Path -Path $tempDir -ChildPath ScriptInEditor.ps1),
+ [ref] $tokens,
+ [ref] $null)
+
+ $cursorPosition = $scriptAst.Extent.StartScriptPosition.
+ GetType().
+ GetMethod('CloneWithNewOffset', [System.Reflection.BindingFlags]'NonPublic, Instance').
+ Invoke($scriptAst.Extent.StartScriptPosition, @($scriptText.Length - 1))
+
+ Push-Location -LiteralPath $PSHOME
+ $TestFile = Join-Path -Path $tempDir -ChildPath $ExpectedFileName
+ $null = New-Item -Path $TestFile
+ $res = TabExpansion2 -ast $scriptAst -tokens $tokens -positionOfCursor $cursorPosition
+ Pop-Location
+
+ $ExpectedPath = Join-Path -Path '.\' -ChildPath $ExpectedFileName
+ $res.CompletionMatches.CompletionText | Where-Object {$_ -Like "*$ExpectedFileName"} | Should -Be $ExpectedPath
+ }
+
It "Should handle '~' in completiontext when it's used to refer to home in input" {
$res = TabExpansion2 -inputScript "~$separator"
# select the first answer which does not have a space in the completion (those completions look like & '3D Objects')
@@ -1931,6 +2253,10 @@ class InheritedClassTest : System.Attribute
$res.CompletionMatches[0].CompletionText | Should -BeExactly $afterTab
}
+ It "Tab completion UNC path with filesystem provider" -Skip:(!$IsWindows) {
+ $res = TabExpansion2 -inputScript 'Filesystem::\\localhost\admin'
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly 'Filesystem::\\localhost\ADMIN$'
+ }
It "Tab completion for registry" -Skip:(!$IsWindows) {
$beforeTab = 'registry::HKEY_l'
@@ -2231,7 +2557,7 @@ class InheritedClassTest : System.Attribute
}
It "Test hashtable key completion in #requires statement for modules" {
- $res = TabExpansion2 -inputScript "#requires -Modules @{" -cursorColumn 21
+ $res = TabExpansion2 -inputScript "#requires -Modules @{"
$res.CompletionMatches.Count | Should -BeGreaterThan 0
$res.CompletionMatches[0].CompletionText | Should -BeExactly "GUID"
}
@@ -2900,23 +3226,23 @@ dir -Recurse `
}
It '' -TestCases @(
@{
- Intent = 'Complete help keywords with minimum input'
+ Intent = 'Complete help keywords with minimal input'
Expected = @(
- 'COMPONENT'
- 'DESCRIPTION'
- 'EXAMPLE'
- 'EXTERNALHELP'
- 'FORWARDHELPCATEGORY'
- 'FORWARDHELPTARGETNAME'
- 'FUNCTIONALITY'
- 'INPUTS'
- 'LINK'
- 'NOTES'
- 'OUTPUTS'
- 'PARAMETER'
- 'REMOTEHELPRUNSPACE'
- 'ROLE'
- 'SYNOPSIS'
+ "COMPONENT",
+ "DESCRIPTION",
+ "EXAMPLE",
+ "EXTERNALHELP",
+ "FORWARDHELPCATEGORY",
+ "FORWARDHELPTARGETNAME",
+ "FUNCTIONALITY",
+ "INPUTS",
+ "LINK",
+ "NOTES",
+ "OUTPUTS",
+ "PARAMETER",
+ "REMOTEHELPRUNSPACE",
+ "ROLE",
+ "SYNOPSIS"
)
TestString = @'
<#
@@ -3106,6 +3432,7 @@ function MyFunction ($param1, $param2)
It 'Should complete module specification keys in using module statement' {
$res = TabExpansion2 -inputScript 'using module @{'
$res.CompletionMatches.CompletionText -join ' ' | Should -BeExactly "GUID MaximumVersion ModuleName ModuleVersion RequiredVersion"
+ $res.CompletionMatches[0].ToolTip | Should -Not -Be $res.CompletionMatches[0].CompletionText
}
It 'Should not fallback to file completion when completing typenames' {
@@ -3115,6 +3442,18 @@ function MyFunction ($param1, $param2)
}
}
+Describe "TabCompletion elevated tests" -Tags CI, RequireAdminOnWindows {
+ It "Tab completion UNC path with spaces" -Skip:(!$IsWindows) {
+ $Share = New-SmbShare -Temporary -ReadAccess (whoami.exe) -Path C:\ -Name "Test Share"
+ $res = TabExpansion2 -inputScript '\\localhost\test'
+ $res.CompletionMatches[0].CompletionText | Should -BeExactly "& '\\localhost\Test Share'"
+ if ($null -ne $Share)
+ {
+ Remove-SmbShare -InputObject $Share -Force -Confirm:$false
+ }
+ }
+}
+
Describe "Tab completion tests with remote Runspace" -Tags Feature,RequireAdminOnWindows {
BeforeAll {
$skipTest = -not $IsWindows
diff --git a/test/powershell/Language/Operators/ComparisonOperator.Tests.ps1 b/test/powershell/Language/Operators/ComparisonOperator.Tests.ps1
index 76069143327..ddc6498eb6d 100644
--- a/test/powershell/Language/Operators/ComparisonOperator.Tests.ps1
+++ b/test/powershell/Language/Operators/ComparisonOperator.Tests.ps1
@@ -82,6 +82,21 @@ Describe "ComparisonOperator" -Tag "CI" {
param($lhs, $operator, $rhs)
Invoke-Expression "$lhs $operator $rhs" | Should -BeFalse
}
+
+ It "Should be for backtick comparison " -TestCases @(
+ @{ lhs = 'abc`def'; operator = '-like'; rhs = 'abc`def'; result = $false }
+ @{ lhs = 'abc`def'; operator = '-like'; rhs = 'abc``def'; result = $true }
+ @{ lhs = 'abc`def'; operator = '-like'; rhs = 'abc````def'; result = $false }
+ @{ lhs = 'abc``def'; operator = '-like'; rhs = 'abc````def'; result = $true }
+ @{ lhs = 'abc`def'; operator = '-like'; rhs = [WildcardPattern]::Escape('abc`def'); result = $true }
+ @{ lhs = 'abc`def'; operator = '-like'; rhs = [WildcardPattern]::Escape('abc``def'); result = $false }
+ @{ lhs = 'abc``def'; operator = '-like'; rhs = [WildcardPattern]::Escape('abc``def'); result = $true }
+ @{ lhs = 'abc``def'; operator = '-like'; rhs = [WildcardPattern]::Escape('abc````def'); result = $false }
+ ) {
+ param($lhs, $operator, $rhs, $result)
+ $expression = "'$lhs' $operator '$rhs'"
+ Invoke-Expression $expression | Should -Be $result
+ }
}
Describe "Bytewise Operator" -Tag "CI" {
diff --git a/test/powershell/Language/Parser/Parsing.Tests.ps1 b/test/powershell/Language/Parser/Parsing.Tests.ps1
index d7bc39b0778..b85ef72c43e 100644
--- a/test/powershell/Language/Parser/Parsing.Tests.ps1
+++ b/test/powershell/Language/Parser/Parsing.Tests.ps1
@@ -683,6 +683,53 @@ Describe "Additional tests" -Tag CI {
$result.EndBlock.Statements[0].PipelineElements[0].Expression.TypeName.FullName | Should -Be 'System.Tuple[System.String[],System.Int32[]]'
}
+ It "Should correctly set the cached type for 'GenericTypeName.TypeName' as needed when the generic type is found in cache" {
+ $tks = $null
+ $ers = $null
+ $Script = '[System.Collections.Generic.List[string]]'
+
+ ## See https://github.com/PowerShell/PowerShell/issues/24982 for details about the issue.
+ $result = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref]$tks, [ref]$ers)
+ $typeExpr = $result.EndBlock.Statements[0].PipelineElements[0].Expression
+ $typeExpr.TypeName.FullName | Should -Be 'System.Collections.Generic.List[string]'
+ $typeExpr.TypeName.TypeName.FullName | Should -Be 'System.Collections.Generic.List'
+ $typeExpr.TypeName.TypeName.GetReflectionType() | Should -Not -BeNullOrEmpty
+ $typeExpr.TypeName.TypeName.GetReflectionType().FullName | Should -Be 'System.Collections.Generic.List`1'
+
+ $result2 = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref]$tks, [ref]$ers)
+ $typeExpr2 = $result2.EndBlock.Statements[0].PipelineElements[0].Expression
+ $typeExpr2.TypeName.FullName | Should -Be 'System.Collections.Generic.List[string]'
+ $typeExpr2.TypeName.TypeName.FullName | Should -Be 'System.Collections.Generic.List'
+ $typeExpr2.TypeName.TypeName.GetReflectionType() | Should -Not -BeNullOrEmpty
+ $typeExpr2.TypeName.TypeName.GetReflectionType().FullName | Should -Be 'System.Collections.Generic.List`1'
+
+ $Script = '[System.Tuple[System.String[],System.Int32[]]]'
+ $result3 = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref]$tks, [ref]$ers)
+ $result3.EndBlock.Statements[0].PipelineElements[0].Expression.TypeName.TypeName.GetReflectionType().FullName | Should -Be 'System.Tuple'
+
+ ## Generic type with assembly name can be resolved.
+ [System.Collections.Generic.List[string], System.Private.CoreLib].FullName | Should -BeLike 'System.Collections.Generic.List``1`[`[System.String, *`]`]'
+
+ $Script = '[System.Collections.Generic.List[string], System.Private.CoreLib]'
+ $result4 = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref]$tks, [ref]$ers)
+ $typeExpr4 = $result4.EndBlock.Statements[0].PipelineElements[0].Expression
+ $typeExpr4.TypeName.FullName | Should -Be 'System.Collections.Generic.List[string],System.Private.CoreLib'
+ $typeExpr4.TypeName.TypeName.FullName | Should -Be 'System.Collections.Generic.List,System.Private.CoreLib'
+ $typeExpr4.TypeName.TypeName.GetReflectionType() | Should -Not -BeNullOrEmpty
+ $typeExpr4.TypeName.TypeName.GetReflectionType().FullName | Should -Be 'System.Collections.Generic.List`1'
+
+ ## Generic type with '`' in name can be resolved.
+ [System.Collections.Generic.List`1[string]].FullName | Should -BeLike 'System.Collections.Generic.List``1`[`[System.String, *`]`]'
+
+ $Script = '[System.Collections.Generic.List`1[string]]'
+ $result5 = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref]$tks, [ref]$ers)
+ $typeExpr5 = $result5.EndBlock.Statements[0].PipelineElements[0].Expression
+ $typeExpr5.TypeName.FullName | Should -Be 'System.Collections.Generic.List`1[string]'
+ $typeExpr5.TypeName.TypeName.FullName | Should -Be 'System.Collections.Generic.List`1'
+ $typeExpr5.TypeName.TypeName.GetReflectionType() | Should -Not -BeNullOrEmpty
+ $typeExpr5.TypeName.TypeName.GetReflectionType().FullName | Should -Be 'System.Collections.Generic.List`1'
+ }
+
It "Should get correct offsets for number constant parsing error" {
$tks = $null
$ers = $null
diff --git a/test/powershell/Language/Scripting/PipelineStoppedToken.Tests.ps1 b/test/powershell/Language/Scripting/PipelineStoppedToken.Tests.ps1
new file mode 100644
index 00000000000..54d1510a20d
--- /dev/null
+++ b/test/powershell/Language/Scripting/PipelineStoppedToken.Tests.ps1
@@ -0,0 +1,97 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+Describe 'PipelineStopToken tests' -Tags 'CI' {
+
+ BeforeAll {
+ Function Invoke-WithStop {
+ [CmdletBinding()]
+ param (
+ [Parameter(Mandatory)]
+ [ScriptBlock]
+ $ScriptBlock,
+
+ [Parameter(ValueFromRemainingArguments)]
+ [object[]]
+ $ArgumentList
+ )
+
+ $ps = [PowerShell]::Create()
+ $null = $ps.AddScript("'start'`n" + $ScriptBlock.ToString())
+ foreach ($arg in $ArgumentList) {
+ $null = $ps.AddArgument($arg)
+ }
+
+ $inPipe = [System.Management.Automation.PSDataCollection[object]]::new()
+ $inPipe.Complete()
+ $outPipe = [System.Management.Automation.PSDataCollection[object]]::new()
+
+ # Use an event to make sure Stop is called once the pipeline has started
+ # and not before.
+ $eventId = [Guid]::NewGuid().ToString()
+ Register-ObjectEvent -InputObject $outPipe -EventName DataAdded -SourceIdentifier $eventId
+ try {
+ $task = $ps.BeginInvoke($inPipe, $outPipe)
+ Wait-Event -SourceIdentifier $eventId | Remove-Event
+ }
+ finally {
+ Remove-Event -SourceIdentifier $eventId -ErrorAction SilentlyContinue
+ Unregister-Event -SourceIdentifier $eventId
+ }
+
+ $ps.Stop()
+ $ps.Streams.Error | Write-Error
+ { $ps.EndInvoke($task) } | Should -Throw -ErrorId PipelineStoppedException
+ }
+ }
+
+ It 'Signal advanced function to stop' {
+ $start = Get-Date
+
+ Invoke-WithStop -ScriptBlock {
+ Function Test-FunctionWithStop {
+ [CmdletBinding()]
+ param ([Parameter()][int]$Timeout)
+
+ [System.Threading.Tasks.Task]::Delay($Timeout * 1000, $PSCmdlet.PipelineStopToken).GetAwaiter().GetResult()
+ }
+
+ Test-FunctionWithStop -Timeout 10
+ }
+
+ $end = (Get-Date) - $start
+ $end.TotalSeconds | Should -BeLessThan 10
+ }
+
+ It 'Signals compiled cmdlet to stop' {
+ $binaryAssembly = Add-Type @'
+using System;
+using System.Management.Automation;
+using System.Threading.Tasks;
+
+namespace PipelineStoppedToken.Tests;
+
+[Cmdlet(VerbsDiagnostic.Test, "CmdletWithStop")]
+public sealed class TestCmdletWithStop : Cmdlet
+{
+ [Parameter]
+ public int Timeout { get; set; }
+
+ protected override void EndProcessing()
+ {
+ Task.Delay(Timeout * 1000, PipelineStopToken).GetAwaiter().GetResult();
+ }
+}
+'@ -PassThru | ForEach-Object Assembly | Select-Object -First 1
+
+ $start = Get-Date
+ Invoke-WithStop -ScriptBlock {
+ Import-Module -Assembly $args[0]
+
+ Test-CmdletWithStop -Timeout 10
+ } -ArgumentList $binaryAssembly
+
+ $end = (Get-Date) - $start
+ $end.TotalSeconds | Should -BeLessThan 10
+ }
+}
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1
index 6885abe847d..2cc21dc03f3 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1
@@ -57,6 +57,18 @@ Describe "Import-Module" -Tags "CI" {
(Get-Module TestModule).Version | Should -BeIn "1.1"
}
+
+ It 'Should override default command prefix if an empty string is provided' {
+ $ModuleName = "PrefixTestModule"
+ $ModulePath = Join-Path -Path $testdrive -ChildPath $ModuleName
+ $null = New-Item -Path $ModulePath -ItemType Directory -Force
+ 'function Use-Something{}' | Set-Content -Path "$ModulePath\$ModuleName.psm1" -Force
+ New-ModuleManifest -Path "$ModulePath\$ModuleName.psd1" -DefaultCommandPrefix MyPrefix -FunctionsToExport Use-Something -RootModule "$ModuleName.psm1"
+ $ImportedModule = Import-Module -Name "$ModulePath\$ModuleName.psd1" -Prefix "" -PassThru
+ $ImportedModule.ExportedCommands.ContainsKey('Use-Something') | Should -Be $true
+ Remove-Module -ModuleInfo $ImportedModule
+ }
+
It 'ProcessorArchitecture should work' {
$currentProcessorArchitecture = switch ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture) {
'X86' { 'x86' }
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Join-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Join-Path.Tests.ps1
index 8cb6391cd7b..a66bddd5e4f 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/Join-Path.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Join-Path.Tests.ps1
@@ -50,4 +50,38 @@ Describe "Join-Path cmdlet tests" -Tags "CI" {
$result.Count | Should -Be 1
$result | Should -BeExactly "one${sepChar}two${sepChar}three${sepChar}four${sepChar}five"
}
+ It "Join-Path -Path -ChildPath should return ''" -TestCases @(
+ @{
+ Path = 'one'
+ ChildPath = 'two', 'three'
+ ExpectedResult = "one${sepChar}two${sepChar}three"
+ }
+ @{
+ Path = 'one', 'two'
+ ChildPath = 'three', 'four'
+ ExpectedResult = @(
+ "one${sepChar}three${sepChar}four"
+ "two${sepChar}three${sepChar}four"
+ )
+ }
+ @{
+ Path = 'one'
+ ChildPath = @()
+ ExpectedResult = "one${sepChar}"
+ }
+ @{
+ Path = 'one'
+ ChildPath = $null
+ ExpectedResult = "one${sepChar}"
+ }
+ @{
+ Path = 'one'
+ ChildPath = [string]::Empty
+ ExpectedResult = "one${sepChar}"
+ }
+ ) {
+ param($Path, $ChildPath, $ExpectedResult)
+ $result = Join-Path -Path $Path -ChildPath $ChildPath
+ $result | Should -BeExactly $ExpectedResult
+ }
}
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1
index 50cde0bae6e..65dd74e1b94 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1
@@ -241,3 +241,17 @@ Describe "Environment Tests" -Tags "Feature" {
}
}
}
+
+Describe "Bug fixes" -Tags "CI" {
+
+ ## https://github.com/PowerShell/PowerShell/issues/24986
+ It "Error redirection along with '-NoNewWindow' should work for Start-Process" -Skip:(!$IsWindows) {
+ $errorFile = Join-Path -Path $TestDrive -ChildPath error.txt
+ $out = pwsh -noprofile -c "Start-Process -Wait -NoNewWindow -RedirectStandardError $errorFile -FilePath cmd -ArgumentList '/C echo Hello'"
+
+ ## 'Hello' should be sent to standard output; 'error.txt' file should be created but empty.
+ $out | Should -BeExactly "Hello"
+ Test-Path -Path $errorFile | Should -BeTrue
+ (Get-Item $errorFile).Length | Should -Be 0
+ }
+}
diff --git a/test/powershell/engine/Api/TypeInference.Tests.ps1 b/test/powershell/engine/Api/TypeInference.Tests.ps1
index 83bab06d196..fc6bdae74b8 100644
--- a/test/powershell/engine/Api/TypeInference.Tests.ps1
+++ b/test/powershell/engine/Api/TypeInference.Tests.ps1
@@ -268,6 +268,16 @@ Describe "Type inference Tests" -tags "CI" {
$res.Name | Should -Be 'System.Management.ManagementObject#root\cimv2\Win32_Process'
}
+ It "Infers type from parameter in classic function definition" {
+ $res = [AstTypeInference]::InferTypeOf(({
+ function MyFunction ([int]$param1)
+ {
+ $param1
+ }
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Int32'
+ }
+
It "Infers type from binary expression with a bool operator as bool" {
$res = [AstTypeInference]::InferTypeOf( {
(1..10) -contains 5
@@ -650,8 +660,10 @@ Describe "Type inference Tests" -tags "CI" {
}
It "Infers type from variable with AllowSafeEval" {
- function Hide-GetProcess { Get-Process }
- $p = Hide-GetProcess
+ # Invoke-Expression is used to "hide" Get-Process from the type inference.
+ # If the typeinference code is updated to handle Invoke-Expression, this test will need to find some other way to set $p
+ # so that the type inference can't figure it out without evaluating the variable value
+ $p = Invoke-Expression -Command 'Get-Process'
$res = [AstTypeInference]::InferTypeOf( { $p }.Ast, [TypeInferenceRuntimePermissions]::AllowSafeEval)
$res.Name | Should -Be 'System.Diagnostics.Process'
}
@@ -1185,6 +1197,18 @@ Describe "Type inference Tests" -tags "CI" {
$res.Name | Should -Be System.String
}
+ It 'Ignores assignment when a variable is declared and used within the same commandAst' {
+ $variableAst = { Get-Random 2>variable:RandomError1 -InputObject ($RandomError1) }.Ast.FindAll({ param($a) $a -is [Language.VariableExpressionAst] }, $true) | select -Last 1
+ $res = [AstTypeInference]::InferTypeOf($variableAst)
+ $res.Count | Should -Be 0
+ }
+
+ It 'Ignores the last assignment when a variable is reused' {
+ $variableAst = { $x = New-Guid; $x = $x.Where{$_} }.Ast.FindAll({ param($a) $a -is [Language.VariableExpressionAst] }, $true) | select -Last 1
+ $res = [AstTypeInference]::InferTypeOf($variableAst)
+ $res.Name | Should -Be System.Guid
+ }
+
$catchClauseTypes = @(
@{ Type = 'System.ArgumentException' }
@{ Type = 'System.ArgumentNullException' }
@@ -1467,6 +1491,26 @@ Describe "Type inference Tests" -tags "CI" {
$res.Count | Should -Be 0
}
+ It 'Infers right side of assignment expression' {
+ $res = [AstTypeInference]::InferTypeOf( { $Test1 = "Hello" }.Ast.Find({param($ast) $ast -is [Language.AssignmentStatementAst]}, $true))
+ $res.Count | Should -Be 1
+ $res.Name | Should -Be "System.String"
+ }
+
+ It 'Infers left side of assignment expression when it is a ConvertExpression' {
+ $res = [AstTypeInference]::InferTypeOf( { [string]$Test1 = 42 }.Ast.Find({param($ast) $ast -is [Language.AssignmentStatementAst]}, $true))
+ $res.Count | Should -Be 1
+ $res.Name | Should -Be "System.String"
+ }
+
+ It 'Infers left side of assignment expression when there is a ConvertExpression among other attributes' {
+ $res = [AstTypeInference]::InferTypeOf( {
+ [ValidateLength()] [string] [ValidatePattern()]$Test1 = 42
+ }.Ast.Find({param($ast) $ast -is [Language.AssignmentStatementAst]}, $true))
+ $res.Count | Should -Be 1
+ $res.Name | Should -Be "System.String"
+ }
+
It 'Infers type of all scope variable after variable assignment' {
$res = [AstTypeInference]::InferTypeOf( { $true = "Hello";$true }.Ast)
$res.Count | Should -Be 1
@@ -1479,6 +1523,30 @@ Describe "Type inference Tests" -tags "CI" {
$res.Name | Should -Be 'System.Management.Automation.Internal.Host.InternalHost'
}
+ It 'Infers type of variable assigned inside do while loop' {
+ $res = [AstTypeInference]::InferTypeOf(({
+ do
+ {
+ $Test = 1
+ $Test
+ }
+ while (1)
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Int32'
+ }
+
+ It 'Infers type of variable assigned inside do until loop' {
+ $res = [AstTypeInference]::InferTypeOf(({
+ do
+ {
+ $Test = 1
+ $Test
+ }
+ until ($null = gci)
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst] -and $Ast.VariablePath.UserPath -eq 'Test'}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Int32'
+ }
+
It 'Infers type of external applications' {
$res = [AstTypeInference]::InferTypeOf( { pwsh }.Ast)
$res.Name | Should -Be 'System.String'
@@ -1492,6 +1560,230 @@ Describe "Type inference Tests" -tags "CI" {
$null = [AstTypeInference]::InferTypeOf($FoundAst)
}
+ It 'Ignores type constraint defined outside of scope' {
+ $res = [AstTypeInference]::InferTypeOf(({
+ function Outer
+ {
+ [string] $Test = "Hello"
+ function Inner
+ {
+ $Test = 2
+ $Test
+ }
+ }
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Int32'
+ }
+
+ It 'Considers the type constraint defined outside of scope when dot sourcing' {
+ $res = [AstTypeInference]::InferTypeOf(({
+ [string] $Test = "Hello"
+ . {$Test = 2; $Test}
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.String'
+ }
+
+ It 'Infers type of ref assigned variable' {
+ $res = [AstTypeInference]::InferTypeOf(({
+ $MyRefVar = $null
+ $null = [System.Management.Automation.Language.Parser]::ParseInput("", [ref] $MyRefVar, [ref] $null)
+ $MyRefVar
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Management.Automation.Language.Token[]'
+ }
+
+ It 'Infers type of variable assigned with New/Set-Variable' {
+ $res = [AstTypeInference]::InferTypeOf( {
+ New-Variable -Name Var1 -Value $true | Out-Null
+ New-Variable -Name Var2 -Value "Hello" | Out-Null
+ $Var1
+ $Var2
+ }.Ast)
+ $res[0].Name | Should -Be 'System.Boolean'
+ $res[1].Name | Should -Be 'System.String'
+ }
+
+ It 'Infers type of variable assigned with common parameter' -TestCases @(
+ @{ParameterName = "WarningVariable"; ExpectedType = [List[WarningRecord]]}
+ @{ParameterName = "wv"; ExpectedType = [List[WarningRecord]]}
+ @{ParameterName = "ErrorVariable"; ExpectedType = [List[ErrorRecord]]}
+ @{ParameterName = "ev"; ExpectedType = [List[ErrorRecord]]}
+ @{ParameterName = "InformationVariable"; ExpectedType = [List[InformationalRecord]]}
+ @{ParameterName = "iv"; ExpectedType = [List[InformationalRecord]]}
+ @{ParameterName = "OutVariable"; ExpectedType = [guid]}
+ @{ParameterName = "ov"; ExpectedType = [guid]}
+ @{ParameterName = "PipelineVariable"; ExpectedType = [guid]}
+ @{ParameterName = "pv"; ExpectedType = [guid]}
+ ) -Test {
+ param($ParameterName, $ExpectedType)
+ $Ast = [scriptblock]::Create("New-Guid -$ParameterName MyOutVar | % {`$MyOutVar}").Ast.FindAll({
+ param($Ast)
+ $Ast -is [Language.VariableExpressionAst]
+ }, $true) | Select-Object -Last 1
+ $res = [AstTypeInference]::InferTypeOf($Ast)
+ $res.Type | Should -Be $ExpectedType
+ }
+
+ It 'Infers type of variable assigned via Data statement' {
+ $res = [AstTypeInference]::InferTypeOf(({
+ Data MyDataVar {"Hello"}
+ $MyDataVar
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.String'
+ }
+
+ It 'Infers type of well known variable with global scope' {
+ $res = [AstTypeInference]::InferTypeOf({$global:true}.Ast)
+ $res.Name | Should -Be 'System.Boolean'
+ }
+
+ It 'Infers parameter type from closest parameter' {
+ $res = [AstTypeInference]::InferTypeOf( ({
+ param([string]$Param1)
+ function TestFunction {param([bool]$Param1) $Param1}
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Boolean'
+ }
+
+ It 'Infers variable type from closest foreach statement' {
+ $res = [AstTypeInference]::InferTypeOf( ({
+ foreach ($X in 1..10)
+ {
+ $X
+ }
+ foreach ($X in New-Guid)
+ {
+ $X
+ }
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Guid'
+ }
+
+ It 'Infers global variable type in child scope' {
+ $res = [AstTypeInference]::InferTypeOf( ({
+ $Global:GlobalTest1 = "Hello"
+ function TestFunction {$GlobalTest1}
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.String'
+ }
+
+ It 'Does not infer private variable type in child scope' {
+ $res = [AstTypeInference]::InferTypeOf( ({
+ $Private:PrivateTest1 = "Hello"
+ function TestFunction {$PrivateTest1}
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Count | Should -Be 0
+ }
+
+ It 'Infers variable assigned with an attribute' {
+ $res = [AstTypeInference]::InferTypeOf( ({
+ [ValidateNotNull()]$ValidatedVar1 = New-Guid
+ $ValidatedVar1
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Guid'
+ }
+
+ It 'Infers variable assigned with multiple type constraints' {
+ $res = [AstTypeInference]::InferTypeOf( ({
+ [int] [string]$MultiConstraintVar1 = "10"
+ $MultiConstraintVar1
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $res.Name | Should -Be 'System.Int32'
+ }
+
+ It 'Infers variable assigned by redirection' {
+ $res = [AstTypeInference]::InferTypeOf( ({
+ New-Guid *>&1 1>variable:RedirVar1; $RedirVar1
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 1 ))
+ $ExpectedTypeNames = @(
+ [ErrorRecord].FullName
+ [WarningRecord].FullName
+ [VerboseRecord].FullName
+ [DebugRecord].FullName
+ [InformationRecord].FullName
+ [guid].FullName
+ ) -join ';'
+ $res.Name -join ';' | Should -Be $ExpectedTypeNames
+ }
+
+ It 'Infers variables assigned by redirection from specific streams' {
+ $VarAsts = [List[Language.Ast]]{
+ [void](New-Guid 1>variable:RedirSuccess 2>variable:RedirError 3>variable:RedirWarning 4>variable:RedirVerbose 5>variable:RedirDebug 6>variable:RedirInfo)
+ $RedirSuccess
+ $RedirError
+ $RedirWarning
+ $RedirVerbose
+ $RedirDebug
+ $RedirInfo
+ }.Ast.FindAll({param($Ast) $Ast -is [Language.VariableExpressionAst]}, $true)
+ $ExpectedTypeNames = @(
+ [guid].FullName
+ [ErrorRecord].FullName
+ [WarningRecord].FullName
+ [VerboseRecord].FullName
+ [DebugRecord].FullName
+ [InformationRecord].FullName
+ )
+
+ for ($i = 0; $i -lt $VarAsts.Count; $i++)
+ {
+ $res = [AstTypeInference]::InferTypeOf($VarAsts[$i])
+ $res.Name | Should -Be $ExpectedTypeNames[$i]
+ }
+ }
+
+ It 'Should infer output from anonymous function' {
+ $res = [AstTypeInference]::InferTypeOf( { & {"Hello"} }.Ast)
+ $res.Name | Should -Be 'System.String'
+ }
+
+ It 'Should infer output from function without OutputType attribute' {
+ function MyHello{"Hello"}
+ $res = [AstTypeInference]::InferTypeOf( { MyHello }.Ast)
+ $res.Name | Should -Be 'System.String'
+ }
+
+ It 'Infers type of command with all streams redirected to Success stream' {
+ $res = [AstTypeInference]::InferTypeOf( { Get-PSDrive *>&1 }.Ast)
+ $ExpectedTypeNames = @(
+ [ErrorRecord].FullName
+ [WarningRecord].FullName
+ [VerboseRecord].FullName
+ [DebugRecord].FullName
+ [InformationRecord].FullName
+ [PSDriveInfo].FullName
+ ) -join ';'
+ $res.Name -join ';' | Should -Be $ExpectedTypeNames
+ }
+
+ It 'Infers type of command with success stream redirected' {
+ $res = [AstTypeInference]::InferTypeOf( { Get-PSDrive *>&1 1>$null }.Ast)
+ $res.Count | Should -Be 0
+ }
+
+ It 'Infers type of command with some streams redirected to success' {
+ $res = [AstTypeInference]::InferTypeOf( { Get-PSDrive 3>&1 4>&1 }.Ast)
+ $res.Count | Should -Be 3
+ $ExpectedTypeNames = @(
+ [PSDriveInfo].FullName
+ [VerboseRecord].FullName
+ [WarningRecord].FullName
+ ) -join ';'
+ ($res.Name | Sort-Object) -join ';' | Should -Be $ExpectedTypeNames
+ }
+
+ It 'Infers type of command with other streams redirected to success' {
+ $res = [AstTypeInference]::InferTypeOf( { Get-PSDrive 2>&1 5>&1 6>&1 }.Ast)
+ $res.Count | Should -Be 4
+ $ExpectedTypeNames = @(
+ [DebugRecord].FullName
+ [ErrorRecord].FullName
+ [InformationRecord].FullName
+ [PSDriveInfo].FullName
+ ) -join ';'
+ ($res.Name | Sort-Object) -join ';' | Should -Be $ExpectedTypeNames
+ }
+
It 'Should only consider assignments wrapped in parentheses to be a part of the output in a Named block' {
$res = [AstTypeInference]::InferTypeOf( { [string]$Assignment1 = "Hello"; ([int]$Assignment2 = 42) }.Ast)
$res.Count | Should -Be 1
diff --git a/test/tools/NamedPipeConnection/build.ps1 b/test/tools/NamedPipeConnection/build.ps1
index e9941d2b1f4..a0978c4cb34 100644
--- a/test/tools/NamedPipeConnection/build.ps1
+++ b/test/tools/NamedPipeConnection/build.ps1
@@ -36,8 +36,8 @@ param (
[ValidateSet("Debug", "Release")]
[string] $BuildConfiguration = "Debug",
- [ValidateSet("net9.0")]
- [string] $BuildFramework = "net9.0"
+ [ValidateSet("net10.0")]
+ [string] $BuildFramework = "net10.0"
)
$script:ModuleName = 'Microsoft.PowerShell.NamedPipeConnection'
diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj
index 2320b1d90e8..89147481bc3 100644
--- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj
+++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj
@@ -8,7 +8,7 @@
1.0.0.0
1.0.0
1.0.0
- net9.0
+ net10.0
true
13.0
diff --git a/test/tools/OpenCover/OpenCover.psm1 b/test/tools/OpenCover/OpenCover.psm1
index 6f2b3bdde4e..9e7adb640ca 100644
--- a/test/tools/OpenCover/OpenCover.psm1
+++ b/test/tools/OpenCover/OpenCover.psm1
@@ -624,7 +624,7 @@ function Invoke-OpenCover
[parameter()]$OutputLog = "$HOME/Documents/OpenCover.xml",
[parameter()]$TestPath = "${script:psRepoPath}/test/powershell",
[parameter()]$OpenCoverPath = "$HOME/OpenCover",
- [parameter()]$PowerShellExeDirectory = "${script:psRepoPath}/src/powershell-win-core/bin/CodeCoverage/net9.0/win7-x64/publish",
+ [parameter()]$PowerShellExeDirectory = "${script:psRepoPath}/src/powershell-win-core/bin/CodeCoverage/net10.0/win7-x64/publish",
[parameter()]$PesterLogElevated = "$HOME/Documents/TestResultsElevated.xml",
[parameter()]$PesterLogUnelevated = "$HOME/Documents/TestResultsUnelevated.xml",
[parameter()]$PesterLogFormat = "NUnitXml",
diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj
index e5e132e9423..7d06d8897f8 100644
--- a/test/tools/TestService/TestService.csproj
+++ b/test/tools/TestService/TestService.csproj
@@ -15,8 +15,7 @@
-
-
+
diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj
index 2f9314cee75..a582db86d78 100644
--- a/test/tools/WebListener/WebListener.csproj
+++ b/test/tools/WebListener/WebListener.csproj
@@ -7,7 +7,6 @@
-
-
+
diff --git a/test/xUnit/csharp/test_CompletionHelpers.cs b/test/xUnit/csharp/test_CompletionHelpers.cs
new file mode 100644
index 00000000000..c91a478fd85
--- /dev/null
+++ b/test/xUnit/csharp/test_CompletionHelpers.cs
@@ -0,0 +1,96 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Management.Automation;
+using Xunit;
+
+namespace PSTests.Parallel
+{
+ public class CompletionHelpersTests
+ {
+ [Theory]
+ [InlineData("", "'", "''")]
+ [InlineData("", "\"", "\"\"")]
+ [InlineData("'", "'", "''''")]
+ [InlineData("", "", "''")]
+ [InlineData("", null, "''")]
+ [InlineData("word", "'", "'word'")]
+ [InlineData("word", "\"", "\"word\"")]
+ [InlineData("word's", "'", "'word''s'")]
+ [InlineData("already 'quoted'", "'", "'already ''quoted'''")]
+ [InlineData("multiple 'quotes' in 'text'", "'", "'multiple ''quotes'' in ''text'''")]
+ [InlineData("\"word\"", "'", "'\"word\"'")]
+ [InlineData("'word'", "'", "''word''")]
+ [InlineData("word", "", "word")]
+ [InlineData("word", null, "word")]
+ [InlineData("\"word\"", "\"", "\"\"word\"\"")]
+ [InlineData("'word'", "\"", "\"'word'\"")]
+ [InlineData("word with space", "'", "'word with space'")]
+ [InlineData("word with space", "\"", "\"word with space\"")]
+ [InlineData("word\"with\"quotes", "'", "'word\"with\"quotes'")]
+ [InlineData("word'with'quotes", "\"", "\"word'with'quotes\"")]
+ [InlineData("while", "'", "'while'")]
+ [InlineData("while", "", "while")]
+ [InlineData("while", "\"", "\"while\"")]
+ [InlineData("$variable", "'", "'$variable'")]
+ [InlineData("$variable", "", "$variable")]
+ [InlineData("$variable", "\"", "\"$variable\"")]
+ [InlineData("key$word", "'", "'key$word'")]
+ [InlineData("key$word", "", "'key$word'")]
+ [InlineData("key$word", "\"", "\"key$word\"")]
+ public void TestQuoteCompletionText(
+ string completionText,
+ string quote,
+ string expected)
+ {
+ string result = CompletionHelpers.QuoteCompletionText(completionText, quote);
+ Assert.Equal(expected, result);
+ }
+
+ [Theory]
+ [InlineData("normaltext", false)]
+ [InlineData("$variable", false)]
+ [InlineData("abc def", true)]
+ [InlineData("while", false)] // PowerShell keyword
+ [InlineData("key$word", true)]
+ [InlineData("abc`def", true)]
+ [InlineData("normal-text", false)]
+ [InlineData("\"doublequotes\"", false)]
+ [InlineData("'singlequotes'", false)]
+ [InlineData("normal 'text'", true)]
+ [InlineData("normal \"text\"", true)]
+ [InlineData("text with ' and \"", true)]
+ [InlineData("text\"with\"quotes", false)]
+ [InlineData("text'with'quotes", false)]
+ [InlineData("\"key$", true)]
+ [InlineData("\"", true)]
+ [InlineData("'", true)]
+ [InlineData("", true)]
+ public void TestCompletionRequiresQuotes(string completion, bool expected)
+ {
+ bool result = CompletionHelpers.CompletionRequiresQuotes(completion);
+ Assert.Equal(expected, result);
+ }
+
+ [Theory]
+ [InlineData("", "", "")]
+ [InlineData("\"", "", "\"")]
+ [InlineData("'", "", "'")]
+ [InlineData("\"word\"", "word", "\"")]
+ [InlineData("'word'", "word", "'")]
+ [InlineData("\"word", "word", "\"")]
+ [InlineData("'word", "word", "'")]
+ [InlineData("word\"", "word\"", "")]
+ [InlineData("word'", "word'", "")]
+ [InlineData("\"word's\"", "word's", "\"")]
+ [InlineData("'word\"", "'word\"", "")]
+ [InlineData("\"word'", "\"word'", "")]
+ [InlineData("'word\"s'", "word\"s", "'")]
+ public void TestHandleDoubleAndSingleQuote(string wordToComplete, string expectedWordToComplete, string expectedQuote)
+ {
+ string quote = CompletionHelpers.HandleDoubleAndSingleQuote(ref wordToComplete);
+ Assert.Equal(expectedQuote, quote);
+ Assert.Equal(expectedWordToComplete, wordToComplete);
+ }
+ }
+}
diff --git a/test/xUnit/csharp/test_Feedback.cs b/test/xUnit/csharp/test_Feedback.cs
index 2c90118be55..eba627f7b0d 100644
--- a/test/xUnit/csharp/test_Feedback.cs
+++ b/test/xUnit/csharp/test_Feedback.cs
@@ -97,7 +97,7 @@ public static void GetFeedback()
// Test the result from the 'general' feedback provider.
Assert.Single(feedbacks);
- Assert.Equal("general", feedbacks[0].Name);
+ Assert.Equal("General Feedback", feedbacks[0].Name);
Assert.Equal(expectedCmd, feedbacks[0].Item.RecommendedActions[0]);
// Expect the result from both 'general' and the 'slow' feedback providers.
@@ -107,7 +107,7 @@ public static void GetFeedback()
Assert.Equal(2, feedbacks.Count);
FeedbackResult entry1 = feedbacks[0];
- Assert.Equal("general", entry1.Name);
+ Assert.Equal("General Feedback", entry1.Name);
Assert.Equal(expectedCmd, entry1.Item.RecommendedActions[0]);
FeedbackResult entry2 = feedbacks[1];
diff --git a/test/xUnit/csharp/test_WildcardPattern.cs b/test/xUnit/csharp/test_WildcardPattern.cs
index 07f4045ef11..7aa4fc8c259 100644
--- a/test/xUnit/csharp/test_WildcardPattern.cs
+++ b/test/xUnit/csharp/test_WildcardPattern.cs
@@ -25,6 +25,22 @@ public void TestEscape_Empty()
[InlineData("a", "a")]
[InlineData("a*", "a`*")]
[InlineData("*?[]", "`*`?`[`]")]
+ [InlineData("`", "``")]
+ [InlineData("```", "``````")]
+ [InlineData("a`", "a``")]
+ [InlineData("abc`def", "abc``def")]
+ [InlineData("abc``def", "abc````def")]
+ [InlineData("text with `backticks", "text with ``backticks")]
+ [InlineData("ends with `", "ends with ``")]
+ [InlineData("`starts with", "``starts with")]
+ [InlineData("`in`between`", "``in``between``")]
+ [InlineData("no special characters", "no special characters")]
+ [InlineData("`*`", "```*``")]
+ [InlineData("*`?[]", "`*```?`[`]")]
+ [InlineData("`*`?`[", "```*```?```[")]
+ [InlineData("*?[]`", "`*`?`[`]``")]
+ [InlineData("nested `backticks `inside`", "nested ``backticks ``inside``")]
+ [InlineData("wildcard*with`backtick", "wildcard`*with``backtick")]
public void TestEscape_String(string source, string expected)
{
Assert.Equal(WildcardPattern.Escape(source), expected);
diff --git a/test/xUnit/xUnit.tests.csproj b/test/xUnit/xUnit.tests.csproj
index 424ef33406d..b843ec370ec 100644
--- a/test/xUnit/xUnit.tests.csproj
+++ b/test/xUnit/xUnit.tests.csproj
@@ -29,7 +29,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json
index b655aae740c..eb4f1035136 100644
--- a/tools/cgmanifest.json
+++ b/tools/cgmanifest.json
@@ -1,5 +1,4 @@
{
- "$schema": "https://json.schemastore.org/component-detection-manifest.json",
"Registrations": [
{
"Component": {
@@ -56,7 +55,7 @@
"Type": "nuget",
"Nuget": {
"Name": "JsonSchema.Net",
- "Version": "7.3.3"
+ "Version": "7.3.4"
}
},
"DevelopmentDependency": false
@@ -76,7 +75,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.ApplicationInsights",
- "Version": "2.22.0"
+ "Version": "2.23.0"
}
},
"DevelopmentDependency": false
@@ -86,7 +85,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Bcl.AsyncInterfaces",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -96,7 +95,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.CodeAnalysis.Analyzers",
- "Version": "3.3.4"
+ "Version": "3.11.0"
}
},
"DevelopmentDependency": true
@@ -106,7 +105,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.CodeAnalysis.Common",
- "Version": "4.12.0"
+ "Version": "4.13.0"
}
},
"DevelopmentDependency": false
@@ -116,7 +115,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.CodeAnalysis.CSharp",
- "Version": "4.12.0"
+ "Version": "4.13.0"
}
},
"DevelopmentDependency": false
@@ -126,17 +125,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Extensions.ObjectPool",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "Microsoft.Management.Infrastructure.Runtime.Unix",
- "Version": "3.0.0"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -151,16 +140,6 @@
},
"DevelopmentDependency": true
},
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "Microsoft.Management.Infrastructure",
- "Version": "3.0.0"
- }
- },
- "DevelopmentDependency": false
- },
{
"Component": {
"Type": "nuget",
@@ -171,16 +150,6 @@
},
"DevelopmentDependency": false
},
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "Microsoft.PowerShell.Native",
- "Version": "7.4.0"
- }
- },
- "DevelopmentDependency": false
- },
{
"Component": {
"Type": "nuget",
@@ -196,17 +165,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Win32.Registry.AccessControl",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "Microsoft.Win32.Registry",
- "Version": "5.0.0"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -216,7 +175,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Win32.SystemEvents",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -226,7 +185,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Windows.Compatibility",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -246,7 +205,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-arm.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -256,7 +215,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -266,7 +225,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -276,7 +235,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-x86.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -286,7 +245,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-arm.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -296,7 +255,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -306,7 +265,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -316,7 +275,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -326,7 +285,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -336,7 +295,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -346,7 +305,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -356,7 +315,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -366,7 +325,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -376,7 +335,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -396,7 +355,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -406,7 +365,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.osx-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -416,7 +375,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.osx-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -476,17 +435,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.CodeDom",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Collections.Immutable",
- "Version": "8.0.0"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -496,7 +445,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ComponentModel.Composition.Registration",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -506,7 +455,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ComponentModel.Composition",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -516,7 +465,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Configuration.ConfigurationManager",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -526,7 +475,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Data.Odbc",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -536,7 +485,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Data.OleDb",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -551,22 +500,12 @@
},
"DevelopmentDependency": false
},
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Diagnostics.DiagnosticSource",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
{
"Component": {
"Type": "nuget",
"Nuget": {
"Name": "System.Diagnostics.EventLog",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -576,7 +515,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Diagnostics.PerformanceCounter",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -586,7 +525,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.DirectoryServices.AccountManagement",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -596,7 +535,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.DirectoryServices.Protocols",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -606,7 +545,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.DirectoryServices",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -616,7 +555,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Drawing.Common",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -626,7 +565,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.IO.Packaging",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -636,7 +575,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.IO.Ports",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -646,7 +585,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Management",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -656,17 +595,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Net.Http.WinHttpHandler",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Numerics.Vectors",
- "Version": "4.5.0"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -686,27 +615,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Reflection.Context",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Reflection.DispatchProxy",
- "Version": "4.7.1"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Reflection.Metadata",
- "Version": "8.0.0"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -716,17 +625,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Runtime.Caching",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Security.AccessControl",
- "Version": "6.0.1"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -736,7 +635,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Cryptography.Pkcs",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -746,7 +645,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Cryptography.ProtectedData",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -756,7 +655,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Cryptography.Xml",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -766,17 +665,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Permissions",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Security.Principal.Windows",
- "Version": "5.0.0"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -836,7 +725,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ServiceModel.Syndication",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -846,7 +735,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ServiceProcess.ServiceController",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -856,27 +745,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Speech",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Text.Encoding.CodePages",
- "Version": "9.0.2"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Text.Encodings.Web",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -886,7 +755,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Threading.AccessControl",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
@@ -896,7 +765,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Web.Services.Description",
- "Version": "4.10.0"
+ "Version": "8.1.1"
}
},
"DevelopmentDependency": false
@@ -906,10 +775,11 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Windows.Extensions",
- "Version": "9.0.2"
+ "Version": "9.0.3"
}
},
"DevelopmentDependency": false
}
- ]
+ ],
+ "$schema": "https://json.schemastore.org/component-detection-manifest.json"
}
diff --git a/tools/findMissingNotices.ps1 b/tools/findMissingNotices.ps1
index 490edebb81b..42722701d97 100644
--- a/tools/findMissingNotices.ps1
+++ b/tools/findMissingNotices.ps1
@@ -193,8 +193,8 @@ function Get-CGRegistrations {
$registrationChanged = $false
- $dotnetTargetName = 'net9.0'
- $dotnetTargetNameWin7 = 'net9.0-windows8.0'
+ $dotnetTargetName = 'net10.0'
+ $dotnetTargetNameWin7 = 'net10.0-windows8.0'
$unixProjectName = 'powershell-unix'
$windowsProjectName = 'powershell-win-core'
$actualRuntime = $Runtime
@@ -203,28 +203,34 @@ function Get-CGRegistrations {
"alpine-.*" {
$folder = $unixProjectName
$target = "$dotnetTargetName|$Runtime"
+ $neutralTarget = "$dotnetTargetName"
}
"linux-.*" {
$folder = $unixProjectName
$target = "$dotnetTargetName|$Runtime"
+ $neutralTarget = "$dotnetTargetName"
}
"osx-.*" {
$folder = $unixProjectName
$target = "$dotnetTargetName|$Runtime"
+ $neutralTarget = "$dotnetTargetName"
}
"win-x*" {
$sdkToUse = $winDesktopSdk
$folder = $windowsProjectName
$target = "$dotnetTargetNameWin7|$Runtime"
+ $neutralTarget = "$dotnetTargetNameWin7"
}
"win-.*" {
$folder = $windowsProjectName
$target = "$dotnetTargetNameWin7|$Runtime"
+ $neutralTarget = "$dotnetTargetNameWin7"
}
"modules" {
$folder = "modules"
$actualRuntime = 'linux-x64'
$target = "$dotnetTargetName|$actualRuntime"
+ $neutralTarget = "$dotnetTargetName"
}
Default {
throw "Invalid runtime name: $Runtime"
@@ -241,6 +247,7 @@ function Get-CGRegistrations {
$null = New-PADrive -Path $PSScriptRoot\..\src\$folder\obj\project.assets.json -Name $folder
try {
$targets = Get-ChildItem -Path "${folder}:/targets/$target" -ErrorAction Stop | Where-Object { $_.Type -eq 'package' } | select-object -ExpandProperty name
+ $targets += Get-ChildItem -Path "${folder}:/targets/$neutralTarget" -ErrorAction Stop | Where-Object { $_.Type -eq 'project' } | select-object -ExpandProperty name
} catch {
Get-ChildItem -Path "${folder}:/targets" | Out-String | Write-Verbose -Verbose
throw
@@ -250,27 +257,53 @@ function Get-CGRegistrations {
Get-PSDrive -Name $folder -ErrorAction Ignore | Remove-PSDrive
}
+ # Name to skip for TPN generation
+ $skipNames = @(
+ "Microsoft.PowerShell.Native"
+ "Microsoft.Management.Infrastructure.Runtime.Unix"
+ "Microsoft.Management.Infrastructure"
+ "Microsoft.PowerShell.Commands.Diagnostics"
+ "Microsoft.PowerShell.Commands.Management"
+ "Microsoft.PowerShell.Commands.Utility"
+ "Microsoft.PowerShell.ConsoleHost"
+ "Microsoft.PowerShell.SDK"
+ "Microsoft.PowerShell.Security"
+ "Microsoft.Management.Infrastructure.CimCmdlets"
+ "Microsoft.WSMan.Management"
+ "Microsoft.WSMan.Runtime"
+ "System.Management.Automation"
+ "Microsoft.PowerShell.GraphicalHost"
+ "Microsoft.PowerShell.CoreCLR.Eventing"
+ )
+
+ Write-Verbose "Found $($targets.Count) targets to process..." -Verbose
$targets | ForEach-Object {
$target = $_
$parts = ($target -split '\|')
$name = $parts[0]
- $targetVersion = $parts[1]
- $publicVersion = Get-NuGetPublicVersion -Name $name -Version $targetVersion
-
- # Add the registration to the cgmanifest if the TPN does not contain the name of the target OR
- # the exisitng CG contains the registration, because if the existing CG contains the registration,
- # that might be the only reason it is in the TPN.
- if (!$RegistrationTable.ContainsKey($target)) {
- $DevelopmentDependency = $false
- if (!$existingRegistrationTable.ContainsKey($name) -or $existingRegistrationTable.$name.Component.Version() -ne $publicVersion) {
- $registrationChanged = $true
- }
- if ($existingRegistrationTable.ContainsKey($name) -and $existingRegistrationTable.$name.DevelopmentDependency) {
- $DevelopmentDependency = $true
- }
- $registration = New-NugetComponent -Name $name -Version $publicVersion -DevelopmentDependency:$DevelopmentDependency
- $RegistrationTable.Add($target, $registration)
+ if ($name -in $skipNames) {
+ Write-Verbose "Skipping $name..."
+
+ } else {
+ $targetVersion = $parts[1]
+ $publicVersion = Get-NuGetPublicVersion -Name $name -Version $targetVersion
+
+ # Add the registration to the cgmanifest if the TPN does not contain the name of the target OR
+ # the exisitng CG contains the registration, because if the existing CG contains the registration,
+ # that might be the only reason it is in the TPN.
+ if (!$RegistrationTable.ContainsKey($target)) {
+ $DevelopmentDependency = $false
+ if (!$existingRegistrationTable.ContainsKey($name) -or $existingRegistrationTable.$name.Component.Version() -ne $publicVersion) {
+ $registrationChanged = $true
+ }
+ if ($existingRegistrationTable.ContainsKey($name) -and $existingRegistrationTable.$name.DevelopmentDependency) {
+ $DevelopmentDependency = $true
+ }
+
+ $registration = New-NugetComponent -Name $name -Version $publicVersion -DevelopmentDependency:$DevelopmentDependency
+ $RegistrationTable.Add($target, $registration)
+ }
}
}
diff --git a/tools/metadata.json b/tools/metadata.json
index f6cf10f7cdf..fd740b4ec2b 100644
--- a/tools/metadata.json
+++ b/tools/metadata.json
@@ -1,10 +1,10 @@
{
"StableReleaseTag": "v7.5.0",
- "PreviewReleaseTag": "v7.6.0-preview.2",
+ "PreviewReleaseTag": "v7.6.0-preview.3",
"ServicingReleaseTag": "v7.0.13",
"ReleaseTag": "v7.5.0",
"LTSReleaseTag" : ["v7.4.7"],
- "NextReleaseTag": "v7.6.0-preview.3",
+ "NextReleaseTag": "v7.6.0-preview.4",
"LTSRelease": { "Latest": false, "Package": false },
"StableRelease": { "Latest": false, "Package": false }
}
diff --git a/tools/packaging/boms/windows.json b/tools/packaging/boms/windows.json
index c9fd280930f..18b25f019f9 100644
--- a/tools/packaging/boms/windows.json
+++ b/tools/packaging/boms/windows.json
@@ -879,10 +879,6 @@
"Pattern": "Modules/PSReadLine/*.txt",
"FileType": "NonProduct"
},
- {
- "Pattern": "Modules/ThreadJob/*.dll",
- "FileType": "NonProduct"
- },
{
"Pattern": "Modules/ThreadJob/*.psd1",
"FileType": "NonProduct"
@@ -899,10 +895,34 @@
"Pattern": "Modules\\Microsoft.PowerShell.PSResourceGet\\PSResourceRepository.admx",
"FileType": "NonProduct"
},
+ {
+ "Pattern": "Modules\\Microsoft.PowerShell.ThreadJob\\.signature.p7s",
+ "FileType": "NonProduct"
+ },
+ {
+ "Pattern": "Modules\\Microsoft.PowerShell.ThreadJob\\en-us\\Microsoft.PowerShell.ThreadJob.dll-Help.xml",
+ "FileType": "NonProduct"
+ },
+ {
+ "Pattern": "Modules\\Microsoft.PowerShell.ThreadJob\\LICENSE",
+ "FileType": "NonProduct"
+ },
+ {
+ "Pattern": "Modules\\Microsoft.PowerShell.ThreadJob\\ThirdPartyNotices.txt",
+ "FileType": "NonProduct"
+ },
{
"Pattern": "Modules\\PSReadLine\\.signature.p7s",
"FileType": "NonProduct"
},
+ {
+ "Pattern": "Modules\\ThreadJob\\.signature.p7s",
+ "FileType": "NonProduct"
+ },
+ {
+ "Pattern": "Modules\\ThreadJob\\ThreadJob.psm1",
+ "FileType": "NonProduct"
+ },
{
"Pattern": "mscordaccore_*.dll",
"FileType": "NonProduct"
@@ -1875,6 +1895,10 @@
"Pattern": "ref\\System.IO.Pipelines.dll",
"FileType": "NonProduct"
},
+ {
+ "Pattern": "ref\\System.Linq.AsyncEnumerable.dll",
+ "FileType": "NonProduct"
+ },
{
"Pattern": "ru/Microsoft.CodeAnalysis.CSharp.resources.dll",
"FileType": "NonProduct"
@@ -2471,6 +2495,10 @@
"Pattern": "System.IO.UnmanagedMemoryStream.dll",
"FileType": "NonProduct"
},
+ {
+ "Pattern": "System.Linq.AsyncEnumerable.dll",
+ "FileType": "NonProduct"
+ },
{
"Pattern": "System.Linq.dll",
"FileType": "NonProduct"
@@ -2615,6 +2643,10 @@
"Pattern": "System.Private.Windows.Core.dll",
"FileType": "NonProduct"
},
+ {
+ "Pattern": "System.Private.Windows.GdiPlus.dll",
+ "FileType": "NonProduct"
+ },
{
"Pattern": "System.Private.Xml.dll",
"FileType": "NonProduct"
@@ -2991,6 +3023,10 @@
"Pattern": "System.Windows.Presentation.dll",
"FileType": "NonProduct"
},
+ {
+ "Pattern": "System.Windows.Primitives.dll",
+ "FileType": "NonProduct"
+ },
{
"Pattern": "System.Xaml.dll",
"FileType": "NonProduct"
@@ -3455,6 +3491,14 @@
"Pattern": "Modules\\Microsoft.PowerShell.PSResourceGet\\InstallPSResourceGetPolicyDefinitions.ps1",
"FileType": "Product"
},
+ {
+ "Pattern": "Modules\\Microsoft.PowerShell.ThreadJob\\Microsoft.PowerShell.ThreadJob.dll",
+ "FileType": "Product"
+ },
+ {
+ "Pattern": "Modules\\Microsoft.PowerShell.ThreadJob\\Microsoft.PowerShell.ThreadJob.psd1",
+ "FileType": "Product"
+ },
{
"Pattern": "pwsh.dll",
"FileType": "Product"
diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1
index 50c47062c3e..f8961cc4883 100644
--- a/tools/packaging/packaging.psm1
+++ b/tools/packaging/packaging.psm1
@@ -16,7 +16,7 @@ $AllDistributions = @()
$AllDistributions += $DebianDistributions
$AllDistributions += $RedhatDistributions
$AllDistributions += 'macOs'
-$script:netCoreRuntime = 'net9.0'
+$script:netCoreRuntime = 'net10.0'
$script:iconFileName = "Powershell_black_64.png"
$script:iconPath = Join-Path -path $PSScriptRoot -ChildPath "../../assets/$iconFileName" -Resolve
@@ -1621,7 +1621,7 @@ function Get-PackageDependencies
)
if($Script:Options.Runtime -like 'fx*') {
$Dependencies += @(
- "dotnet-runtime-9.0"
+ "dotnet-runtime-10.0"
)
}
} elseif ($Distribution -eq 'macOS') {
diff --git a/tools/packaging/packaging.strings.psd1 b/tools/packaging/packaging.strings.psd1
index fda97df9cdc..eeb9a86ec10 100644
--- a/tools/packaging/packaging.strings.psd1
+++ b/tools/packaging/packaging.strings.psd1
@@ -166,7 +166,7 @@ open {0}
-
+
diff --git a/tools/packaging/projects/reference/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/tools/packaging/projects/reference/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
index eccdcfa9479..f358b454baa 100644
--- a/tools/packaging/projects/reference/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
+++ b/tools/packaging/projects/reference/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
@@ -1,6 +1,6 @@
- net9.0
+ net10.0
$(RefAsmVersion)
true
$(SnkFile)
@@ -14,7 +14,8 @@
-
+
+
diff --git a/tools/packaging/projects/reference/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj b/tools/packaging/projects/reference/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj
index 7f45926e29f..c0794a6a708 100644
--- a/tools/packaging/projects/reference/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj
+++ b/tools/packaging/projects/reference/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj
@@ -1,6 +1,6 @@
- net9.0
+ net10.0
$(RefAsmVersion)
true
$(SnkFile)
diff --git a/tools/packaging/projects/reference/System.Management.Automation/System.Management.Automation.csproj b/tools/packaging/projects/reference/System.Management.Automation/System.Management.Automation.csproj
index 3a021bb5517..f4626e110fd 100644
--- a/tools/packaging/projects/reference/System.Management.Automation/System.Management.Automation.csproj
+++ b/tools/packaging/projects/reference/System.Management.Automation/System.Management.Automation.csproj
@@ -1,6 +1,6 @@
- net9.0
+ net10.0
$(RefAsmVersion)
true
$(SnkFile)
@@ -9,6 +9,7 @@
-
+
+
diff --git a/tools/releaseBuild/.gitignore b/tools/releaseBuild/.gitignore
deleted file mode 100644
index 0ff566888a7..00000000000
--- a/tools/releaseBuild/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-PSRelease/
diff --git a/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 b/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1
deleted file mode 100644
index 2475dce7d89..00000000000
--- a/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-
-# PowerShell Script to build and package PowerShell from specified form and branch
-# Script is intented to use in Docker containers
-# Ensure PowerShell is available in the provided image
-
-param (
- [string] $location = "/powershell",
-
- # Destination location of the package on docker host
- [string] $destination = '/mnt',
-
- [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")]
- [ValidateNotNullOrEmpty()]
- [string]$ReleaseTag,
-
- [switch]$TarX64,
- [switch]$TarArm,
- [switch]$TarArm64,
- [switch]$TarMinSize,
- [switch]$FxDependent,
- [switch]$Alpine
-)
-
-$releaseTagParam = @{}
-if ($ReleaseTag)
-{
- $releaseTagParam = @{ 'ReleaseTag' = $ReleaseTag }
-}
-
-#Remove the initial 'v' from the ReleaseTag
-$version = $ReleaseTag -replace '^v'
-$semVersion = [System.Management.Automation.SemanticVersion] $version
-
-$metadata = Get-Content "$location/tools/metadata.json" -Raw | ConvertFrom-Json
-
-$LTS = $metadata.LTSRelease.Package
-
-Write-Verbose -Verbose -Message "LTS is set to: $LTS"
-
-function BuildPackages {
- param(
- [switch] $LTS
- )
-
- Push-Location
- try {
- Set-Location $location
- Import-Module "$location/build.psm1"
- Import-Module "$location/tools/packaging"
-
- Start-PSBootstrap -Package -NoSudo
-
- $buildParams = @{ Configuration = 'Release'; PSModuleRestore = $true; Restore = $true }
-
- if ($FxDependent.IsPresent) {
- $projectAssetsZipName = 'linuxFxDependantProjectAssetssymbols.zip'
- $buildParams.Add("Runtime", "fxdependent")
- } elseif ($Alpine.IsPresent) {
- $projectAssetsZipName = 'linuxAlpineProjectAssetssymbols.zip'
- $buildParams.Add("Runtime", 'musl-x64')
- } else {
- # make the artifact name unique
- $projectAssetsZipName = "linuxProjectAssets-$((Get-Date).Ticks)-symbols.zip"
- }
-
- Start-PSBuild @buildParams @releaseTagParam
- $options = Get-PSOptions
-
- if ($FxDependent) {
- Start-PSPackage -Type 'fxdependent' @releaseTagParam -LTS:$LTS
- } elseif ($Alpine) {
- Start-PSPackage -Type 'tar-alpine' @releaseTagParam -LTS:$LTS
- } else {
- Start-PSPackage @releaseTagParam -LTS:$LTS
- }
-
- if ($TarX64) { Start-PSPackage -Type tar @releaseTagParam -LTS:$LTS }
-
- if ($TarMinSize) {
- Write-Verbose -Verbose "---- Min-Size ----"
- Write-Verbose -Verbose "options.Output: $($options.Output)"
- Write-Verbose -Verbose "options.Top $($options.Top)"
-
- $binDir = Join-Path -Path $options.Top -ChildPath 'bin'
- Write-Verbose -Verbose "Remove $binDir, to get a clean build for min-size package"
- Remove-Item -Path $binDir -Recurse -Force
-
- ## Build 'min-size' and create 'tar.gz' package for it.
- $buildParams['ForMinimalSize'] = $true
- Start-PSBuild @buildParams @releaseTagParam
- Start-PSPackage -Type min-size @releaseTagParam -LTS:$LTS
- }
-
- if ($TarArm) {
- ## Build 'linux-arm' and create 'tar.gz' package for it.
- ## Note that 'linux-arm' can only be built on Ubuntu environment.
- Start-PSBuild -Configuration Release -Restore -Runtime linux-arm -PSModuleRestore @releaseTagParam
- Start-PSPackage -Type tar-arm @releaseTagParam -LTS:$LTS
- }
-
- if ($TarArm64) {
- Start-PSBuild -Configuration Release -Restore -Runtime linux-arm64 -PSModuleRestore @releaseTagParam
- Start-PSPackage -Type tar-arm64 @releaseTagParam -LTS:$LTS
- }
- } finally {
- Pop-Location
- }
-}
-
-BuildPackages
-
-if ($LTS) {
- Write-Verbose -Verbose "Packaging LTS"
- BuildPackages -LTS
-}
-
-$linuxPackages = Get-ChildItem "$location/powershell*" -Include *.deb,*.rpm,*.tar.gz
-
-foreach ($linuxPackage in $linuxPackages)
-{
- $filePath = $linuxPackage.FullName
- Write-Verbose "Copying $filePath to $destination" -Verbose
- Copy-Item -Path $filePath -Destination $destination -Force
-}
-
-Write-Verbose "Exporting project.assets files ..." -Verbose
-
-$projectAssetsCounter = 1
-$projectAssetsFolder = Join-Path -Path $destination -ChildPath 'projectAssets'
-$projectAssetsZip = Join-Path -Path $destination -ChildPath $projectAssetsZipName
-Get-ChildItem $location\project.assets.json -Recurse | ForEach-Object {
- $subfolder = $_.FullName.Replace($location,'')
- $subfolder.Replace('project.assets.json','')
- $itemDestination = Join-Path -Path $projectAssetsFolder -ChildPath $subfolder
- New-Item -Path $itemDestination -ItemType Directory -Force
- $file = $_.FullName
- Write-Verbose "Copying $file to $itemDestination" -Verbose
- Copy-Item -Path $file -Destination "$itemDestination\" -Force
- $projectAssetsCounter++
-}
-
-Compress-Archive -Path $projectAssetsFolder -DestinationPath $projectAssetsZip
-Remove-Item -Path $projectAssetsFolder -Recurse -Force -ErrorAction SilentlyContinue
diff --git a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1
deleted file mode 100644
index 41ec53fa495..00000000000
--- a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-[cmdletbinding(DefaultParameterSetName='default')]
-# PowerShell Script to clone, build and package PowerShell from specified fork and branch
-param (
- [string] $fork = 'powershell',
-
- [string] $branch = 'master',
-
- [string] $location = "$PWD\powershell",
-
- [string] $destination = "$env:WORKSPACE",
-
- [ValidateSet("win7-x64", "win7-x86", "win-arm", "win-arm64", "fxdependent", "fxdependent-win-desktop")]
- [string] $Runtime = 'win7-x64',
-
- [switch] $ForMinimalSize,
-
- [switch] $Wait,
-
- [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")]
- [ValidateNotNullOrEmpty()]
- [string] $ReleaseTag,
-
- [Parameter(Mandatory,ParameterSetName='IncludeSymbols')]
- [switch] $Symbols,
-
- [Parameter(Mandatory,ParameterSetName='packageSigned')]
- [ValidatePattern("-signed.zip$")]
- [string] $BuildZip,
-
- [Parameter(Mandatory,ParameterSetName='ComponentRegistration')]
- [switch] $ComponentRegistration
-)
-
-$releaseTagParam = @{}
-if ($ReleaseTag)
-{
- $releaseTagParam = @{ 'ReleaseTag' = $ReleaseTag }
-}
-
-if (-not $env:homedrive)
-{
- Write-Verbose "fixing empty home paths..." -Verbose
- $profileParts = $env:userprofile -split ':'
- $env:homedrive = $profileParts[0]+':'
- $env:homepath = $profileParts[1]
-}
-
-if (! (Test-Path $destination))
-{
- Write-Verbose "Creating destination $destination" -Verbose
- $null = New-Item -Path $destination -ItemType Directory
-}
-
-Write-Verbose "homedrive : ${env:homedrive}"
-Write-Verbose "homepath : ${env:homepath}"
-
-# Don't use CIM_PhysicalMemory, docker containers may cache old values
-$memoryMB = (Get-CimInstance win32_computersystem).TotalPhysicalMemory /1MB
-$requiredMemoryMB = 2048
-if ($memoryMB -lt $requiredMemoryMB)
-{
- throw "Building powershell requires at least $requiredMemoryMB MiB of memory and only $memoryMB MiB is present."
-}
-Write-Verbose "Running with $memoryMB MB memory." -Verbose
-
-try
-{
- Set-Location $location
-
- Import-Module "$location\build.psm1" -Force
- Import-Module "$location\tools\packaging" -Force
- $env:platform = $null
-
- Write-Verbose "Sync'ing Tags..." -Verbose
- Sync-PSTags -AddRemoteIfMissing
-
- Write-Verbose "Bootstrapping powershell build..." -Verbose
- Start-PSBootstrap -Force -Package -ErrorAction Stop
-
- if ($PSCmdlet.ParameterSetName -eq 'packageSigned')
- {
- Write-Verbose "Expanding signed build..." -Verbose
- if($Runtime -like 'fxdependent*')
- {
- Expand-PSSignedBuild -BuildZip $BuildZip -SkipPwshExeCheck
- }
- else
- {
- Expand-PSSignedBuild -BuildZip $BuildZip
- }
-
- Remove-Item -Path $BuildZip
- }
- else
- {
- Write-Verbose "Starting powershell build for RID: $Runtime and ReleaseTag: $ReleaseTag ..." -Verbose
- $buildParams = @{
- ForMinimalSize = $ForMinimalSize
- }
-
- if($Symbols)
- {
- $buildParams['NoPSModuleRestore'] = $true
- }
- else
- {
- $buildParams['PSModuleRestore'] = $true
- }
-
- Start-PSBuild -Clean -Runtime $Runtime -Configuration Release @releaseTagParam @buildParams
- }
-
- if ($ComponentRegistration)
- {
- Write-Verbose "Exporting project.assets files ..." -Verbose
-
- $projectAssetsCounter = 1
- $projectAssetsFolder = Join-Path -Path $destination -ChildPath 'projectAssets'
- $projectAssetsZip = Join-Path -Path $destination -ChildPath 'windowsProjectAssetssymbols.zip'
- Get-ChildItem $location\project.assets.json -Recurse | ForEach-Object {
- $subfolder = $_.FullName.Replace($location,'')
- $subfolder.Replace('project.assets.json','')
- $itemDestination = Join-Path -Path $projectAssetsFolder -ChildPath $subfolder
- New-Item -Path $itemDestination -ItemType Directory -Force > $null
- $file = $_.FullName
- Write-Verbose "Copying $file to $itemDestination" -Verbose
- Copy-Item -Path $file -Destination "$itemDestination\" -Force
- $projectAssetsCounter++
- }
-
- Compress-Archive -Path $projectAssetsFolder -DestinationPath $projectAssetsZip
- Remove-Item -Path $projectAssetsFolder -Recurse -Force -ErrorAction SilentlyContinue
-
- return
- }
-
- if ($Runtime -like 'fxdependent*')
- {
- $pspackageParams = @{'Type' = $Runtime}
- }
- else
- {
- ## Set the default package type.
- $pspackageParams = @{'Type' = 'msi'; 'WindowsRuntime' = $Runtime}
- if ($ForMinimalSize)
- {
- ## Special case for the minimal size self-contained package.
- $pspackageParams['Type'] = 'min-size'
- }
- }
-
- if (!$Symbols -and $Runtime -notlike 'fxdependent*' -and !$ForMinimalSize)
- {
- Write-Verbose "Starting powershell packaging(msi)..." -Verbose
- Start-PSPackage @pspackageParams @releaseTagParam
-
- $pspackageParams['Type']='msix'
- Write-Verbose "Starting powershell packaging(msix)..." -Verbose
- Start-PSPackage @pspackageParams @releaseTagParam
- }
-
- if ($Runtime -like 'fxdependent*' -or $ForMinimalSize)
- {
- ## Add symbols for just like zip package.
- $pspackageParams['IncludeSymbols']=$Symbols
- Start-PSPackage @pspackageParams @releaseTagParam
-
- ## Copy the fxdependent Zip package to destination.
- Get-ChildItem $location\PowerShell-*.zip | ForEach-Object {
- $file = $_.FullName
- Write-Verbose "Copying $file to $destination" -Verbose
- Copy-Item -Path $file -Destination "$destination\" -Force
- }
- }
- else
- {
- if (!$Symbols) {
- $pspackageParams['Type'] = 'zip-pdb'
- Write-Verbose "Starting powershell symbols packaging(zip)..." -Verbose
- Start-PSPackage @pspackageParams @releaseTagParam
- }
-
- $pspackageParams['Type']='zip'
- $pspackageParams['IncludeSymbols']=$Symbols
- Write-Verbose "Starting powershell packaging(zip)..." -Verbose
- Start-PSPackage @pspackageParams @releaseTagParam
-
- Write-Verbose "Exporting packages ..." -Verbose
-
- Get-ChildItem $location\*.msi,$location\*.zip,$location\*.wixpdb,$location\*.msix,$location\*.exe | ForEach-Object {
- $file = $_.FullName
- Write-Verbose "Copying $file to $destination" -Verbose
- Copy-Item -Path $file -Destination "$destination\" -Force
- }
- }
-}
-finally
-{
- Write-Verbose "Beginning build clean-up..." -Verbose
- if ($Wait)
- {
- $path = Join-Path $PSScriptRoot -ChildPath 'delete-to-continue.txt'
- $null = New-Item -Path $path -ItemType File
- Write-Verbose "Computer name: $env:COMPUTERNAME" -Verbose
- Write-Verbose "Delete $path to exit." -Verbose
- while(Test-Path -LiteralPath $path)
- {
- Start-Sleep -Seconds 60
- }
- }
-}
diff --git a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/dockerInstall.psm1 b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/dockerInstall.psm1
deleted file mode 100644
index 311fed7e169..00000000000
--- a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/dockerInstall.psm1
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-function Install-ChocolateyPackage
-{
- param(
- [Parameter(Mandatory=$true)]
- [string]
- $PackageName,
-
- [Parameter(Mandatory=$false)]
- [string]
- $Executable,
-
- [string[]]
- $ArgumentList,
-
- [switch]
- $Cleanup,
-
- [int]
- $ExecutionTimeout = 2700,
-
- [string]
- $Version
- )
-
- if(-not(Get-Command -Name Choco -ErrorAction SilentlyContinue))
- {
- Write-Verbose "Installing Chocolatey provider..." -Verbose
- Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression
- }
-
- Write-Verbose "Installing $PackageName..." -Verbose
- $extraCommand = @()
- if($Version)
- {
- $extraCommand += '--version', $version
- }
- choco install -y $PackageName --no-progress --execution-timeout=$ExecutionTimeout $ArgumentList $extraCommands
-
- if($executable)
- {
- Write-Verbose "Verifing $Executable is in path..." -Verbose
- $exeSource = $null
- $exeSource = Get-ChildItem -Path "$env:ProgramFiles\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
- if(!$exeSource)
- {
- Write-Verbose "Falling back to x86 program files..." -Verbose
- $exeSource = Get-ChildItem -Path "${env:ProgramFiles(x86)}\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
- }
-
- # Don't search the chocolatey program data until more official locations have been searched
- if(!$exeSource)
- {
- Write-Verbose "Falling back to chocolatey..." -Verbose
- $exeSource = Get-ChildItem -Path "$env:ProgramData\chocolatey\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
- }
-
- # all obvious locations are exhausted, use brute force and search from the root of the filesystem
- if(!$exeSource)
- {
- Write-Verbose "Falling back to the root of the drive..." -Verbose
- $exeSource = Get-ChildItem -Path "/$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
- }
-
- if(!$exeSource)
- {
- throw "$Executable not found"
- }
-
- $exePath = Split-Path -Path $exeSource
- Append-Path -path $exePath
- }
-
- if($Cleanup.IsPresent)
- {
- Remove-Folder -Folder "$env:temp\chocolatey"
- }
-}
-
-function Append-Path
-{
- param
- (
- $path
- )
- $machinePathString = [System.Environment]::GetEnvironmentVariable('path',[System.EnvironmentVariableTarget]::Machine)
- $machinePath = $machinePathString -split ';'
-
- if($machinePath -inotcontains $path)
- {
- $newPath = "$machinePathString;$path"
- Write-Verbose "Adding $path to path..." -Verbose
- [System.Environment]::SetEnvironmentVariable('path',$newPath,[System.EnvironmentVariableTarget]::Machine)
- Write-Verbose "Added $path to path." -Verbose
- }
- else
- {
- Write-Verbose "$path already in path." -Verbose
- }
-}
-
-function Remove-Folder
-{
- param(
- [string]
- $Folder
- )
-
- Write-Verbose "Cleaning up $Folder..." -Verbose
- $filter = Join-Path -Path $Folder -ChildPath *
- [int]$measuredCleanupMB = (Get-ChildItem $filter -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB
- Remove-Item -Recurse -Force $filter -ErrorAction SilentlyContinue
- Write-Verbose "Cleaned up $measuredCleanupMB MB from $Folder" -Verbose
-}
diff --git a/tools/releaseBuild/README.md b/tools/releaseBuild/README.md
deleted file mode 100644
index 9b78e742b5f..00000000000
--- a/tools/releaseBuild/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Azure Dev Ops Release Builds
-
-## Requirements
-
-Docker must be installed to run any of the release builds.
-
-## Running Windows Release Builds Locally
-
-From PowerShell on Windows, run `.\vstsbuild.ps1 -ReleaseTag -Name `.
-
-For the package builds, run `.\vstsbuild.ps1 -ReleaseTag -Name -BuildPath -SignedFilesPath `
-
-Windows Build Names:
-
-* `win7-x64-symbols`
- * Builds the Windows x64 Zip with symbols
-* `win7-x86-symbols`
- * Builds the Windows x86 Zip with symbols
-* `win7-arm-symbols`
- * Builds the Windows ARM Zip with symbols
-* `win7-arm64-symbols`
- * Builds the Windows ARM64 Zip with symbols
-* `win7-fxdependent-symbols`
- * Builds the Windows FxDependent Zip with symbols
-* `win7-x64-package`
- * Builds the Windows x64 packages
-* `win7-x86-package`
- * Builds the Windows x86 packages
-* `win7-arm-package`
- * Builds the Windows ARM packages
-* `win7-arm64-package`
- * Builds the Windows ARM64 packages
-* `win7-fxdependent-package`
- * Builds the Windows FxDependent packages
-
-## Running Linux Release Builds Locally
-
-From PowerShell on Linux or macOS, run `.\vstsbuild.ps1 -ReleaseTag -Name `.
-
-Linux Build Names:
-
-* `deb`
- * Builds the Debian Packages, ARM32 and ARM64.
-* `alpine`
- * Builds the Alpine Package
-* `rpm`
- * Builds the RedHat variant Package
-
-## Azure Dev Ops Build
-
-The release build is fairly complicated. The definition is at `./azureDevOps/releaseBuild.yml`.
-
-Here is a diagram of the build:
-
-[](https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/releaseBuild/azureDevOps/diagram.svg?sanitize=true)
diff --git a/tools/releaseBuild/azureDevOps/AzArtifactFeed/PSGalleryToAzArtifacts.yml b/tools/releaseBuild/azureDevOps/AzArtifactFeed/PSGalleryToAzArtifacts.yml
deleted file mode 100644
index da26ea6d348..00000000000
--- a/tools/releaseBuild/azureDevOps/AzArtifactFeed/PSGalleryToAzArtifacts.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-# Sync packages from PSGallery to Azure DevOps Artifacts feed
-
-resources:
-- repo: self
- clean: true
-
-pool:
- name: 1es
- demands:
- - ImageOverride -equals PSMMS2019-Minimal
-
-steps:
- - pwsh: |
- $minVer = [version]"2.2.3"
- $curVer = Get-Module PowerShellGet -ListAvailable | Select-Object -First 1 | ForEach-Object Version
- if (-not $curVer -or $curVer -lt $minVer) {
- Install-Module -Name PowerShellGet -MinimumVersion 2.2.3 -Force
- }
- displayName: Update PSGet and PackageManagement
- condition: succeededOrFailed()
-
- - pwsh: |
- Write-Verbose -Verbose "Packages to upload"
- if(Test-Path $(Build.ArtifactStagingDirectory)) { Get-ChildItem "$(Build.ArtifactStagingDirectory)/*.nupkg" | ForEach-Object { $_.FullName }}
- displayName: List packages to upload
- condition: succeededOrFailed()
-
- - task: NuGetCommand@2
- displayName: 'NuGet push'
- inputs:
- command: push
- publishVstsFeed: 'pscore-release'
- publishFeedCredentials: 'AzArtifactsFeed'
diff --git a/tools/releaseBuild/azureDevOps/compliance.yml b/tools/releaseBuild/azureDevOps/compliance.yml
deleted file mode 100644
index 3624f1e1081..00000000000
--- a/tools/releaseBuild/azureDevOps/compliance.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Compliance-$(Build.BuildId)
-
-trigger: none
-pr: none
-
-schedules:
- # Chrontab format, see https://en.wikipedia.org/wiki/Cron
- # this is in UTC
- - cron: '0 13 * * *'
- branches:
- include:
- - master
-
-resources:
- repositories:
- - repository: ComplianceRepo
- type: github
- endpoint: ComplianceGHRepo
- name: PowerShell/compliance
- ref: master
-
-parameters:
-- name: InternalSDKBlobURL
- displayName: URL to the blob havibg internal .NET SDK
- type: string
- default: ' '
-
-variables:
- - name: DOTNET_CLI_TELEMETRY_OPTOUT
- value: 1
- - name: POWERSHELL_TELEMETRY_OPTOUT
- value: 1
- - name: nugetMultiFeedWarnLevel
- value: none
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- # Defines the variables AzureFileCopySubscription, StorageAccount, StorageAccountKey, StorageResourceGroup, StorageSubscriptionName
- - group: 'Azure Blob variable group'
- # Defines the variables CgPat, CgOrganization, and CgProject
- - group: 'ComponentGovernance'
- - group: 'PoolNames'
- - name: __DOTNET_RUNTIME_FEED
- value: ${{ parameters.InternalSDKBlobURL }}
-
-
-stages:
- - stage: compliance
- displayName: 'Compliance'
- dependsOn: []
- jobs:
- - template: templates/compliance/compliance.yml
- parameters:
- parentJobs: []
- - stage: APIScan
- displayName: 'ApiScan'
- dependsOn: []
- jobs:
- - template: templates/compliance/apiscan.yml
- parameters:
- parentJobs: []
- - stage: notice
- displayName: Generate Notice File
- dependsOn: []
- jobs:
- - template: templates/compliance/generateNotice.yml
- parameters:
- parentJobs: []
diff --git a/tools/releaseBuild/azureDevOps/diagram.puml b/tools/releaseBuild/azureDevOps/diagram.puml
deleted file mode 100644
index ade53b11b9c..00000000000
--- a/tools/releaseBuild/azureDevOps/diagram.puml
+++ /dev/null
@@ -1,107 +0,0 @@
-@startuml
-
-folder "Linux Builds" as LinuxBuilds {
- ' Define the build tasks as business processes
- agent "DEB" as BuildDEB
- agent "RPM" as BuildRPM
- agent "Alpine" as BuildAlpine
- agent "Linux-FxDependent" as BuildLinuxFx
-
-}
-
-agent "macOS Build" as BuildMac
-
-agent "Upload build metadata" as BuildMetadata
-
-folder "Windows Builds" as WinBuilds {
- agent "x64" as BuildWinX64
- agent "x86" as BuildWinX86
- agent "arm32" as BuildWinArm32
- agent "arm64" as BuildWinArm64
- agent "FxDependent" as BuildWinFx
-}
-
-agent "ComponentRegistration" as BuildCG
-
-folder "Linux Package Scanning and Upload" as PkgScanUploadLinux {
- agent "DEB" as UploadDEB
- agent "RPM" as UploadRPM
- agent "Alpine" as UploadAlpine
- agent "Linux-FxDependent" as UploadLinuxFx
-}
-
-folder "Package Signing and Upload" as PkgSignUpload {
- agent "macOS" as SignMac
-
- agent "Windows" as SignWin
-}
-
-folder "Build Test Artifacts" as TestArtifacts {
- agent "Windows" as WinTest
- agent "Linux" as LinuxTest
- agent "Linux-ARM" as LinuxArmTest
- agent "Linux-ARM64" as LinuxArm64Test
-}
-
-agent "Compliance" as Compliance
-
-
-agent "Create SDK and Global Tool and Upload" as BuildNuGet
-
-
-' Define finishing the build as a goal filled
-control "Finish" as Finish
-control "Start" as Start
-
-' map the various Upload task dependencies
-BuildDEB -down-> UploadDEB
-BuildRPM -down-> UploadRPM
-BuildLinuxFx -down-> UploadLinuxFx
-BuildAlpine -down-> UploadAlpine
-
-' map all of the SignMac task dependencies
-BuildMac -down-> SignMac
-
-' map all of the SignWin task dependencies
-WinBuilds -down-> SignWin
-'BuildWinX64 -down-> SignWin
-'BuildWinX86 -down-> SignWin
-'BuildWinArm32 -down-> SignWin
-'BuildWinArm64 -down-> SignWin
-'BuildWinFx -down-> SignWin
-
-' map all of the Compliance task dependencies
-BuildWinX86 -down-> Compliance
-BuildWinX64 -down-> Compliance
-BuildWinFx -down-> Compliance
-
-PkgSignUpload -down-> BuildNuGet
-LinuxBuilds -down-> BuildNuGet
-
-' map all leafs to finish
-Compliance ~~ Finish
-UploadAlpine ~~ Finish
-UploadDEB ~~ Finish
-UploadRPM ~~ Finish
-UploadLinuxFx ~~ Finish
-SignMac ~~ Finish
-BuildCG ~~ Finish
-BuildNuGet ~~ Finish
-TestArtifacts ~~ Finish
-BuildMetadata ~~ Finish
-
-Start ~~ BuildDEB
-Start ~~ BuildRPM
-Start ~~ BuildAlpine
-Start ~~ BuildLinuxFx
-Start ~~ BuildMac
-Start ~~ BuildWinX64
-Start ~~ BuildWinX86
-Start ~~ BuildWinFx
-Start ~~ BuildWinArm32
-Start ~~ BuildWinArm64
-Start ~~ BuildCG
-Start ~~ TestArtifacts
-Start ~~ BuildMetadata
-
-@enduml
diff --git a/tools/releaseBuild/azureDevOps/diagram.svg b/tools/releaseBuild/azureDevOps/diagram.svg
deleted file mode 100644
index 024128bf988..00000000000
--- a/tools/releaseBuild/azureDevOps/diagram.svg
+++ /dev/null
@@ -1,108 +0,0 @@
-Linux Builds Windows Builds Linux Package Scanning and Upload Package Signing and Upload Build Test Artifacts DEB RPM Alpine Linux-FxDependent x64 x86 arm32 arm64 FxDependent DEB RPM Alpine Linux-FxDependent macOS Windows Windows Linux Linux-ARM Linux-ARM64 macOS Build Upload build metadata ComponentRegistration Compliance Create SDK and Global Tool and Upload Finish Start
\ No newline at end of file
diff --git a/tools/releaseBuild/azureDevOps/releaseBuild.yml b/tools/releaseBuild/azureDevOps/releaseBuild.yml
deleted file mode 100644
index 3be90bbefbc..00000000000
--- a/tools/releaseBuild/azureDevOps/releaseBuild.yml
+++ /dev/null
@@ -1,379 +0,0 @@
-name: UnifiedPackageBuild-$(Build.BuildId)
-trigger:
- branches:
- include:
- - master
- - release*
-pr:
- branches:
- include:
- - master
- - release*
-
-parameters:
- - name: ForceAzureBlobDelete
- displayName: Delete Azure Blob
- type: string
- values:
- - true
- - false
- default: false
- - name: InternalSDKBlobURL
- displayName: URL to the blob having internal .NET SDK
- type: string
- default: ' '
-
-resources:
- repositories:
- - repository: ComplianceRepo
- type: github
- endpoint: ComplianceGHRepo
- name: PowerShell/compliance
- ref: master
-
-variables:
- - name: PS_RELEASE_BUILD
- value: 1
- - name: DOTNET_CLI_TELEMETRY_OPTOUT
- value: 1
- - name: POWERSHELL_TELEMETRY_OPTOUT
- value: 1
- - name: nugetMultiFeedWarnLevel
- value: none
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- # Prevents auto-injection of nuget-security-analysis@0
- - name: skipNugetSecurityAnalysis
- value: true
- - name: branchCounterKey
- value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])]
- - name: branchCounter
- value: $[counter(variables['branchCounterKey'], 1)]
- - name: ForceAzureBlobDelete
- value: ${{ parameters.ForceAzureBlobDelete }}
- - name: Github_Build_Repository_Uri
- value: https://github.com/powershell/powershell
- - name: SBOMGenerator_Formats
- value: spdx:2.2
- - name: BUILDSECMON_OPT_IN
- value: true
- - group: PoolNames
- - name: __DOTNET_RUNTIME_FEED
- value: ${{ parameters.InternalSDKBlobURL }}
-
-stages:
- - stage: prep
- jobs:
- - template: templates/checkAzureContainer.yml
-
- - stage: macos
- dependsOn: ['prep']
- jobs:
- - template: templates/mac.yml
- parameters:
- buildArchitecture: x64
-
- - template: templates/mac.yml
- parameters:
- buildArchitecture: arm64
-
- - stage: linux
- dependsOn: ['prep']
- jobs:
- - template: templates/linux.yml
- parameters:
- buildName: deb
-
- - template: templates/linux.yml
- parameters:
- buildName: rpm
- parentJob: build_deb
-
- - template: templates/linux.yml
- parameters:
- buildName: fxdependent
- parentJob: build_deb
-
- - template: templates/linux.yml
- parameters:
- buildName: alpine
-
- - stage: windows
- dependsOn: ['prep']
- jobs:
- - template: templates/windows-hosted-build.yml
- parameters:
- Architecture: x64
-
- - template: templates/windows-hosted-build.yml
- parameters:
- Architecture: x64
- BuildConfiguration: minSize
-
- - template: templates/windows-hosted-build.yml
- parameters:
- Architecture: x86
-
- - template: templates/windows-hosted-build.yml
- parameters:
- Architecture: arm64
-
- - template: templates/windows-hosted-build.yml
- parameters:
- Architecture: fxdependent
-
- - template: templates/windows-hosted-build.yml
- parameters:
- Architecture: fxdependentWinDesktop
-
- - stage: SignFiles
- displayName: Sign files
- dependsOn: ['windows', 'linux', 'macos']
- jobs:
- - template: templates/mac-file-signing.yml
- parameters:
- buildArchitecture: x64
-
- - template: templates/mac-file-signing.yml
- parameters:
- buildArchitecture: arm64
-
- - job: SignFilesWinLinux
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- displayName: Sign files
-
- variables:
- - group: ESRP
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: repoFolder
- value: PowerShell
- - name: repoRoot
- value: $(Agent.BuildDirectory)\$(repoFolder)
- - name: complianceRepoFolder
- value: compliance
-
- strategy:
- matrix:
- linux-x64:
- runtime: linux-x64
- unsignedBuildArtifactContainer: pwshLinuxBuild.tar.gz
- unsignedBuildArtifactName: pwshLinuxBuild.tar.gz
- signedBuildArtifactName: pwshLinuxBuild.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-x64-Alpine:
- runtime: linux-x64-Alpine
- unsignedBuildArtifactContainer: pwshLinuxBuildAlpine.tar.gz
- unsignedBuildArtifactName: pwshLinuxBuild.tar.gz
- signedBuildArtifactName: pwshLinuxBuildAlpine.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-x64-Alpine-Fxdependent:
- runtime: linux-x64-Alpine-Fxdependent
- unsignedBuildArtifactContainer: pwshAlpineFxdBuildAmd64.tar.gz
- unsignedBuildArtifactName: pwshAlpineFxdBuildAmd64.tar.gz
- signedBuildArtifactName: pwshAlpineFxdBuildAmd64.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-arm32:
- runtime: linux-arm32
- unsignedBuildArtifactContainer: pwshLinuxBuildArm32.tar.gz
- unsignedBuildArtifactName: pwshLinuxBuildArm32.tar.gz
- signedBuildArtifactName: pwshLinuxBuildArm32.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-arm64:
- runtime: linux-arm64
- unsignedBuildArtifactContainer: pwshLinuxBuildArm64.tar.gz
- unsignedBuildArtifactName: pwshLinuxBuildArm64.tar.gz
- signedBuildArtifactName: pwshLinuxBuildArm64.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-fxd:
- runtime: linux-fxd
- unsignedBuildArtifactContainer: pwshLinuxBuildFxdependent.tar.gz
- unsignedBuildArtifactName: pwshLinuxBuild.tar.gz
- signedBuildArtifactName: pwshLinuxBuildFxdependent.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-mariner:
- runtime: linux-mariner
- unsignedBuildArtifactContainer: pwshMarinerBuildAmd64.tar.gz
- unsignedBuildArtifactName: pwshMarinerBuildAmd64.tar.gz
- signedBuildArtifactName: pwshMarinerBuildAmd64.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-arm64-mariner:
- runtime: linux-arm64-mariner
- unsignedBuildArtifactContainer: pwshMarinerBuildArm64.tar.gz
- unsignedBuildArtifactName: pwshMarinerBuildArm64.tar.gz
- signedBuildArtifactName: pwshMarinerBuildArm64.tar.gz
- signedArtifactContainer: authenticode-signed
- linux-minsize:
- runtime: linux-minsize
- unsignedBuildArtifactContainer: pwshLinuxBuildMinSize.tar.gz
- unsignedBuildArtifactName: pwshLinuxBuildMinSize.tar.gz
- signedBuildArtifactName: pwshLinuxBuildMinSize.tar.gz
- signedArtifactContainer: authenticode-signed
- win-x64:
- runtime: win-x64
- unsignedBuildArtifactContainer: results
- unsignedBuildArtifactName: '**/*-symbols-win-x64.zip'
- signedBuildArtifactName: '-symbols-win-x64-signed.zip'
- signedArtifactContainer: results
- win-x86:
- runtime: win-x86
- unsignedBuildArtifactContainer: results
- unsignedBuildArtifactName: '**/*-symbols-win-x86.zip'
- signedBuildArtifactName: '-symbols-win-x86-signed.zip'
- signedArtifactContainer: results
- win-arm64:
- runtime: win-arm64
- unsignedBuildArtifactContainer: results
- unsignedBuildArtifactName: '**/*-symbols-win-arm64.zip'
- signedBuildArtifactName: '-symbols-win-arm64-signed.zip'
- signedArtifactContainer: results
- win-x64-gc:
- runtime: win-x64-gc
- unsignedBuildArtifactContainer: results
- unsignedBuildArtifactName: '**/*-symbols-win-x64-gc.zip'
- signedBuildArtifactName: '-symbols-win-x64-gc-signed.zip'
- signedArtifactContainer: results
- win-fxdependent:
- runtime: win-fxdependent
- unsignedBuildArtifactContainer: results
- unsignedBuildArtifactName: '**/*-symbols-win-fxdependent.zip'
- signedBuildArtifactName: '-symbols-win-fxdependent-signed.zip'
- signedArtifactContainer: results
- win-fxdependentWinDesktop:
- runtime: win-fxdependentWinDesktop
- unsignedBuildArtifactContainer: results
- unsignedBuildArtifactName: '**/*-symbols-win-fxdependentWinDesktop.zip'
- signedBuildArtifactName: '-symbols-win-fxdependentWinDesktop-signed.zip'
- signedArtifactContainer: results
- steps:
- - template: templates/sign-build-file.yml
-
- - stage: mac_packaging
- displayName: macOS packaging
- dependsOn: ['SignFiles']
- jobs:
- - template: templates/mac-package-build.yml
- parameters:
- buildArchitecture: x64
-
- - template: templates/mac-package-build.yml
- parameters:
- buildArchitecture: arm64
-
- - stage: linux_packaging
- displayName: Linux Packaging
- dependsOn: ['SignFiles']
- jobs:
- - template: templates/linux-packaging.yml
- parameters:
- buildName: deb
-
- - template: templates/linux-packaging.yml
- parameters:
- buildName: rpm
- uploadDisplayName: Upload and Sign
-
- - template: templates/linux-packaging.yml
- parameters:
- buildName: alpine
-
- - template: templates/linux-packaging.yml
- parameters:
- buildName: fxdependent
-
- - stage: win_packaging
- displayName: Windows Packaging
- dependsOn: ['SignFiles']
- jobs:
- - template: templates/windows-packaging.yml
- parameters:
- Architecture: x64
- parentJob: build_windows_x64_release
-
- - template: templates/windows-packaging.yml
- parameters:
- Architecture: x64
- BuildConfiguration: minSize
- parentJob: build_windows_x64_minSize
-
- - template: templates/windows-packaging.yml
- parameters:
- Architecture: x86
- parentJob: build_windows_x86_release
-
- - template: templates/windows-packaging.yml
- parameters:
- Architecture: arm64
- parentJob: build_windows_arm64_release
-
- - template: templates/windows-packaging.yml
- parameters:
- Architecture: fxdependent
- parentJob: build_windows_fxdependent_release
-
- - template: templates/windows-packaging.yml
- parameters:
- Architecture: fxdependentWinDesktop
- parentJob: build_windows_fxdependentWinDesktop_release
-
- - stage: package_signing
- displayName: Package Signing
- dependsOn: ['mac_packaging', 'linux_packaging', 'win_packaging']
- jobs:
- - template: templates/windows-package-signing.yml
-
- - template: templates/mac-package-signing.yml
- parameters:
- buildArchitecture: x64
-
- - template: templates/mac-package-signing.yml
- parameters:
- buildArchitecture: arm64
-
- - stage: nuget_and_json
- displayName: NuGet Packaging and Build Json
- dependsOn: ['package_signing']
- jobs:
- - template: templates/nuget.yml
- - template: templates/json.yml
-
- # This is done late so that we dont use resources before the big signing and packaging tasks.
- - stage: compliance
- dependsOn: ['package_signing']
- jobs:
- - template: templates/compliance.yml
-
- - stage: test_and_release_artifacts
- displayName: Test and Release Artifacts
- dependsOn: ['prep']
- jobs:
- - template: templates/testartifacts.yml
-
- - job: release_json
- displayName: Create and Upload release.json
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- steps:
- - checkout: self
- clean: true
- - template: templates/SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - powershell: |
- $metadata = Get-Content '$(Build.SourcesDirectory)/tools/metadata.json' -Raw | ConvertFrom-Json
- $LTS = $metadata.LTSRelease.Package
- @{ ReleaseVersion = "$(Version)"; LTSRelease = $LTS } | ConvertTo-Json | Out-File "$(Build.StagingDirectory)\release.json"
- Get-Content "$(Build.StagingDirectory)\release.json"
- Write-Host "##vso[artifact.upload containerfolder=metadata;artifactname=metadata]$(Build.StagingDirectory)\release.json"
- displayName: Create and upload release.json file to build artifact
- retryCountOnTaskFailure: 2
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/releasePipeline.yml b/tools/releaseBuild/azureDevOps/releasePipeline.yml
deleted file mode 100644
index e21f6d590fe..00000000000
--- a/tools/releaseBuild/azureDevOps/releasePipeline.yml
+++ /dev/null
@@ -1,673 +0,0 @@
-trigger: none
-
-# needed to disable CI trigger and allow manual trigger
-# when the branch is same as pipeline source, the latest build from the source is used.
-# all environment used are for manual tasks and approvals.
-
-parameters:
- - name: skipPackagesMsftComPublish
- displayName: Skip actual publishing to Packages.microsoft.com, AFTER we upload it. Used to test the publishing script.
- default: false
- type: boolean
- - name: skipNugetPublish
- displayName: Skip nuget publishing. Used in testing publishing stage.
- default: false
- type: boolean
-
-resources:
- pipelines:
- - pipeline: releasePipeline
- source: 'Coordinated Packages'
- trigger:
- branches:
- - release/*
-
- repositories:
- - repository: Internal-PowerShellTeam-Tools
- type: git
- trigger: none
- name: Internal-PowerShellTeam-Tools
- ref: main-mirror
-
- - repository: ComplianceRepo
- type: github
- endpoint: ComplianceGHRepo
- name: PowerShell/compliance
- ref: master
-
-variables:
- - name: runCodesignValidationInjection
- value : false
- - name: nugetMultiFeedWarnLevel
- value: none
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: skipComponentGovernanceDetection
- value: true
- - name: BUILDSECMON_OPT_IN
- value: true
- - group: ReleasePipelineSecrets
- - group: PipelineExecutionPats
-
-stages:
-- stage: MSIXBundle
- displayName: Create MSIX Bundle package
- dependsOn: []
- jobs:
- - template: templates/release-MsixBundle.yml
-
-- stage: ValidateSDK
- displayName: Validate SDK
- dependsOn: []
- jobs:
- - template: templates/release-SDKTests.yml
- parameters:
- jobName: WinSDK
- displayName: Windows SDK Test
- imageName: windows-latest
-
- - template: templates/release-SDKTests.yml
- parameters:
- jobName: LinuxSDK
- displayName: Linux SDK Test
- imageName: ubuntu-latest
-
- - template: templates/release-SDKTests.yml
- parameters:
- jobName: macOSSDK
- displayName: macOS SDK Test
- imageName: macOS-latest
-
-- stage: PRCreation
- displayName: Create PR in GH Master
- dependsOn: []
- jobs:
- - deployment: CreatePRInMaster
- displayName: Update README.md and metadata.json
- pool: server
- environment: PSReleaseCreatePR
-
-- stage: ValidateGlobalTool
- displayName: Validate Global Tool
- dependsOn: []
- jobs:
- - template: templates/release-GlobalToolTest.yml
- parameters:
- jobName: WinGblTool
- displayName: Global Tool Test Windows
- imageName: windows-latest
- globalToolExeName: 'pwsh.exe'
- globalToolPackageName: 'PowerShell.Windows.x64'
-
- - template: templates/release-GlobalToolTest.yml
- parameters:
- jobName: LinuxWinGblTool
- displayName: Global Tool Test Linux
- imageName: ubuntu-latest
- globalToolExeName: 'pwsh'
- globalToolPackageName: 'PowerShell.Linux.x64'
-
-- stage: ValidateFxdPackage
- displayName: Validate Fxd Package
- dependsOn: []
- jobs:
- - template: templates/release-ValidateFxdPackage.yml
- parameters:
- jobName: WinFxdPackage
- displayName: Fxd Package Test Win
- imageName: windows-latest
- packageNamePattern: '**/*win-fxdependent.zip'
-
- - template: templates/release-ValidateFxdPackage.yml
- parameters:
- jobName: FxdPackageWindDesktop
- displayName: Fxd Package Test WinDesktop
- imageName: windows-latest
- packageNamePattern: '**/*win-fxdependentWinDesktop.zip'
-
- - template: templates/release-ValidateFxdPackage.yml
- parameters:
- jobName: FxdPackageLinux
- displayName: Fxd Package Test Linux
- imageName: ubuntu-latest
- packageNamePattern: '**/*linux-x64-fxdependent.tar.gz'
-
- - template: templates/release-ValidateFxdPackage.yml
- parameters:
- jobName: FxdPackageLinuxonARM
- displayName: Fxd Package Test Linux ARM64
- imageName: 'PSMMSUbuntu20.04-ARM64-secure'
- packageNamePattern: '**/*linux-x64-fxdependent.tar.gz'
- use1ES: true
-
-- stage: StaticPkgValidation
- dependsOn: []
- displayName: Static package validation
- jobs:
- - job: ValidatePkgNames
- displayName: Validate Package Names
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- variables:
- - group: 'Azure Blob variable group'
- steps:
- - template: templates/release-ValidatePackageNames.yml
- - job: ValidatePkgBOM
- displayName: Validate Package BOM
- pool:
- # testing
- vmImage: ubuntu-latest
- steps:
- - template: templates/release-ValidatePackageBOM.yml
-
-- stage: StartDocker
- dependsOn: []
- displayName: Kick Off Docker Staging build
- jobs:
- - deployment: PSDockerKickOff
- displayName: Start Docker build
- pool: server
- environment: PSReleaseDockerKickOff
-
-- stage: ManualValidation
- dependsOn: []
- displayName: Manual Validation
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Validate Windows Packages
- jobName: ValidateWinPkg
- instructions: |
- Validate zip and msipackages on Windows Server 2012 R2
-
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Validate OSX Packages
- jobName: ValidateOsxPkg
- instructions: |
- Validate tar.gz package on osx-arm64
-
-- stage: ReleaseAutomation
- displayName: Release Automation
- dependsOn: []
- jobs:
- - job: KickOffRA
- displayName: Kickoff Release Automation
- timeoutInMinutes: 240
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: Internal-PowerShellTeam-Tools
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: metadata
- path: '$(Pipeline.Workspace)/releasePipeline/metadata'
-
- - pwsh: |
- Get-ChildItem -Path $(Build.SourcesDirectory)
- Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force
- Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName Release-Automation
- Set-AzDoAuthToken -Token $(powershellRelExecutionPat)
- $packageBuildID = $(resources.pipeline.releasePipeline.runID)
- $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json
- $buildInvocationInfo = Start-AzDOBuild -BuildDefinitionId 10 -BuildArguments @{ POWERSHELL_PACKAGE_BUILD_BUILDID = $packageBuildID } -Tag $metadata.ReleaseVersion, 'InProgress' -PassThru
- Write-Verbose -Verbose "Kicked off release automation:`n$($buildInvocationInfo | Out-String)"
- $status = $buildInvocationInfo | Wait-AzDOBuildStatus -Status Completed -timeoutMinutes 240
- if ($status.result -ne 'Succeeded') {
- Write-Verbose "There are errors in release automation tests. Please triage failures."
- }
-
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Triage Release Automation Results
- jobName: TriageRA
- dependsOnJob: KickOffRA
- instructions: |
- Validate all the test failures and continue when signed off
-
- - job: MarkRASignOff
- displayName: Mark release automation signoff
- dependsOn: TriageRA
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: Internal-PowerShellTeam-Tools
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: metadata
- path: '$(Pipeline.Workspace)/releasePipeline/metadata'
-
- - pwsh: |
- Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force
- Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName Release-Automation
- Set-AzDoAuthToken -Token $(powershellRelExecutionPat)
- $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json
- $azDOBuild = Get-AzDOBuild -buildDefinitionId 10 -MaximumResult 100 | Where-Object { $_.tags -in $metadata.ReleaseVersion }
- $azDoBuild | Remove-AzDOBuildTag -tag 'InProgress' -Pass | Add-AzDOBuildTag -tag 'SignedOff'
- displayName: Signoff Release-Automation run
-
-- stage: UpdateChangeLog
- displayName: Update the changelog
- # do not include stages that are likely to fail in dependency as there is no way to force deploy.
- dependsOn:
- - MSIXBundle
- - ValidateSDK
- - PRCreation
- - StaticPkgValidation
- - StartDocker
- - ManualValidation
- - ValidateFxdPackage
- - ValidateGlobalTool
-
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Make sure the changelog is updated
- jobName: MergeChangeLog
- instructions: |
- Update and merge the changelog for the release.
- This step is required for creating GitHub draft release.
-
-- stage: BlobPublic
- displayName: Make Blob Public
- # do not include stages that are likely to fail in dependency as there is no way to force deploy.
- dependsOn: UpdateChangeLog
-
- # The environment here is used for approval.
- jobs:
- - deployment: AzureBlobPublic
- displayName: Make Azure Blob Public
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- variables:
- - group: 'Staging_ACR'
- environment: PSReleaseAzureBlobPublic
- strategy:
- runOnce:
- deploy:
- steps:
- - template: templates/release-MakeContainerPublic.yml
-
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Copy Global tool packages to PSInfra storage
- jobName: CopyBlobApproval
- instructions: |
- Approval for Copy global tool packages to PSInfra storage
-
- - job: PSInfraBlobPublic
- displayName: Copy global tools to PSInfra storage
- dependsOn: CopyBlobApproval
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- variables:
- - group: 'PSInfraStorage'
-
- steps:
- - template: templates/release-CopyGlobalTools.yml
- parameters:
- sourceContainerName: 'tool-private'
- destinationContainerName: 'tool'
- sourceStorageAccountName: '$(GlobalToolStorageAccount)'
- destinationStorageAccountName: '$(PSInfraStorageAccount)'
- blobPrefix: '$(Version)'
-
-- stage: GitHubTasks
- displayName: GitHub tasks
- dependsOn: BlobPublic
- jobs:
- - job: GitHubDraft
- displayName: Create GitHub Draft release
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- variables:
- - group: 'Azure Blob variable group'
- - group: mscodehub-feed-read-general
- - group: mscodehub-feed-read-akv
- - group: ReleasePipelineSecrets
- steps:
- - template: templates/release-CreateGitHubDraft.yml
-
- - deployment: PushTag
- dependsOn: GitHubDraft
- displayName: Push Git Tag
- pool : server
- environment: PSReleasePushTag
-
- - deployment: MakeDraftPublic
- dependsOn: PushTag
- displayName: Make GitHub Draft public
- pool : server
- environment: PSReleaseDraftPublic
-
-- stage: PublishPackages
- displayName: Publish packages
- dependsOn: GitHubTasks
- jobs:
- - job: PublishNuget
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - template: templates/release-ReleaseToNuGet.yml
- parameters:
- skipPublish: ${{ parameters.skipNugetPublish }}
-
- - job: PublishPkgsMsftCom
-
- timeoutInMinutes: 120
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMSUbuntu20.04-Secure
-
- variables:
- - group: mscodehub-feed-read-general
- - group: mscodehub-feed-read-akv
- - group: 'packages.microsoft.com'
- - group: 'mscodehub-code-read-akv'
- steps:
- - template: templates/release-PublishPackageMsftCom.yml
- parameters:
- skipPublish: ${{ parameters.skipPackagesMsftComPublish }}
-
-- stage: PublishSymbols
- displayName: Publish symbols
- dependsOn: PublishPackages
- jobs:
- - job: PublishSymbol
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - template: templates/release-PublishSymbols.yml
-
-- stage: ChangesToMaster
- displayName: Ensure changes are in GH master
- dependsOn: PublishPackages
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Make sure changes are in master
- jobName: MergeToMaster
- instructions: |
- Make sure that changes README.md and metadata.json are merged into master on GitHub.
-
-- stage: ReleaseDocker
- displayName: Release Docker
- dependsOn:
- - GitHubTasks
- jobs:
- - deployment: ReleaseDocker
- displayName: Release Docker
- pool: server
- environment: PSReleaseDockerRelease
-
-- stage: ReleaseSnap
- displayName: Release Snap
- dependsOn:
- - PublishPackages
- - ChangesToMaster
- variables:
- # adds newPwshOrgName (exists in new and old org)
- - group: PowerShellRelease
- jobs:
- - job: KickoffSnap
- displayName: Kickoff Snap build
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: Internal-PowerShellTeam-Tools
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: metadata
- path: '$(Pipeline.Workspace)/releasePipeline/metadata'
- - pwsh: |
- Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force
- Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName PowerShell
- Set-AzDoAuthToken -Token $(powershellRelExecutionPat)
- $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json
- $buildInvocationInfo = Start-AzDOBuild -BuildDefinitionId 49 -Tag $metadata.ReleaseVersion, 'InProgress' -PassThru
- Write-Verbose -Verbose "Kicked off snap build: $($buildInvocationInfo.WebUrl)"
- $status = $buildInvocationInfo | Wait-AzDOBuildStatus -Status Completed -timeoutMinutes 60
- if ($status.result -ne 'Succeeded') {
- throw "There are errors in snap build!!"
- }
-
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Approve the release
- jobName: SnapEnd
- dependsOnJob: KickoffSnap
- instructions: |
- Once the build is finished, approve the release of all channels.
-
- - job: MarkSnapSignOff
- displayName: Mark release automation signoff
- dependsOn: SnapEnd
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: Internal-PowerShellTeam-Tools
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: metadata
- path: '$(Pipeline.Workspace)/releasePipeline/metadata'
- - pwsh: |
- Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force
- Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName PowerShell
- Set-AzDoAuthToken -Token $(powershellRelExecutionPat)
- $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json
- $azDOBuild = Get-AzDOBuild -buildDefinitionId 49 -MaximumResult 100 | Where-Object { $_.tags -in $metadata.ReleaseVersion }
- $azDoBuild | Remove-AzDOBuildTag -tag 'InProgress' -Pass | Add-AzDOBuildTag -tag 'SignedOff'
- displayName: Signoff Release-Automation run
-
-- stage: ReleaseToMU
- displayName: Release to MU
- dependsOn:
- - PublishPackages
- - ChangesToMaster
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Release to MU
- instructions: |
- Notify the PM team to start the process of releasing to MU.
-
-- stage: UpdateDotnetDocker
- dependsOn: GitHubTasks
- displayName: Update DotNet SDK Docker images
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Update .NET SDK docker images
- jobName: DotnetDocker
- instructions: |
- Create PR for updating dotnet-docker images to use latest PowerShell version.
- 1. Fork and clone https://github.com/dotnet/dotnet-docker.git
- 2. git checkout upstream/nightly -b updatePS
- 3. dotnet run --project .\eng\update-dependencies\ -- --product-version powershell= --compute-shas
- 4. create PR targeting nightly branch
-
-- stage: UpdateWinGet
- dependsOn: GitHubTasks
- displayName: Add manifest entry to winget
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Add manifest entry to winget
- jobName: UpdateWinGet
- instructions: |
- This is typically done by the community 1-2 days after the release.
-
-- stage: PublishMsix
- dependsOn: GitHubTasks
- displayName: Publish MSIX to store
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Publish the MSIX Bundle package to store
- jobName: PublishMsix
- instructions: |
- Ask Steve to release MSIX bundle package to Store
-
-- stage: BuildInfoJson
- dependsOn: GitHubTasks
- displayName: Upload BuildInfoJson
- jobs:
- - deployment: UploadJson
- displayName: Upload BuildInfoJson
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- variables:
- - group: 'Azure Blob variable group'
- environment: PSReleaseBuildInfoJson
- strategy:
- runOnce:
- deploy:
- steps:
- - template: templates/release-BuildJson.yml
-
-- stage: ReleaseVPack
- dependsOn: GitHubTasks
- displayName: Release VPack
- jobs:
- - job: KickoffvPack
- displayName: Kickoff vPack build
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: Internal-PowerShellTeam-Tools
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: metadata
- path: '$(Pipeline.Workspace)/releasePipeline/metadata'
-
- - pwsh: |
- Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force
- Set-AzDoProjectInfo -ProjectOwner mscodehub -ProjectName PowerShellCore
- Set-AzDoAuthToken -Token $(mscodehubBuildExecutionPat)
- $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json
- $releaseVersion = $metadata.ReleaseVersion -replace '^v',''
- $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion
- $isPreview = $semanticVersion.PreReleaseLabel -ne $null
-
- if (-not $isPreview) {
- $buildInvocationInfo = Start-AzDOBuild -BuildDefinitionId 1238 -Branch '$(Build.SourceBranch)' -Tag $metadata.ReleaseVersion, 'InProgress' -PassThru
- Write-Verbose -Verbose "Kicked off vPack build: $($buildInvocationInfo.WebUrl)"
- $status = $buildInvocationInfo | Wait-AzDOBuildStatus -Status Completed -timeoutMinutes 60
- if ($status.result -ne 'Succeeded') {
- throw "There are errors in snap build!!"
- }
- else {
- $buildInvocationInfo | Remove-AzDOBuildTag -tag 'InProgress' -Pass | Add-AzDOBuildTag -tag 'SignedOff'
- }
- }
- else {
- Write-Verbose -Verbose "This is a preview release with version: $semanticVersion skipping releasing vPack"
- }
-
-- stage: ReleaseDeps
- dependsOn: GitHubTasks
- displayName: Update pwsh.deps.json links
- jobs:
- - template: templates/release-UpdateDepsJson.yml
-
-- stage: ReleaseClose
- displayName: Finish Release
- dependsOn:
- - ReleaseVPack
- - BuildInfoJson
- - UpdateDotnetDocker
- - ReleaseDocker
- - ReleaseSnap
- - ChangesToMaster
- - ReleaseDeps
- jobs:
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Retain Build
- jobName: RetainBuild
- instructions: |
- Retain the build
-
- - template: templates/release/approvalJob.yml
- parameters:
- displayName: Delete release branch
- jobName: DeleteBranch
- instructions: |
- Delete release
diff --git a/tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml b/tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml
deleted file mode 100644
index da1889f5bf7..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml
+++ /dev/null
@@ -1,63 +0,0 @@
-parameters:
- ReleaseTagVar: v6.2.0
- ReleaseTagVarName: ReleaseTagVar
- CreateJson: 'no'
- UseJson: 'yes'
-
-steps:
-- ${{ if eq(parameters['UseJson'],'yes') }}:
- - task: DownloadBuildArtifacts@0
- inputs:
- artifactName: 'BuildInfoJson'
- itemPattern: '**/*.json'
- downloadPath: '$(System.ArtifactsDirectory)'
- displayName: Download Build Info Json
-
-- powershell: |
- $path = "./build.psm1"
-
- if($env:REPOROOT){
- Write-Verbose "reporoot already set to ${env:REPOROOT}" -Verbose
- exit 0
- }
-
- if(Test-Path -Path $path)
- {
- Write-Verbose "reporoot detect at: ." -Verbose
- $repoRoot = '.'
- }
- else{
- $path = "./PowerShell/build.psm1"
- if(Test-Path -Path $path)
- {
- Write-Verbose "reporoot detect at: ./PowerShell" -Verbose
- $repoRoot = './PowerShell'
- }
- }
- if($repoRoot) {
- $vstsCommandString = "vso[task.setvariable variable=repoRoot]$repoRoot"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- } else {
- Write-Verbose -Verbose "repo not found"
- }
- displayName: 'Set repo Root'
-
-- powershell: |
- $createJson = ("${{ parameters.CreateJson }}" -ne "no")
- $releaseTag = & "$env:REPOROOT/tools/releaseBuild/setReleaseTag.ps1" -ReleaseTag ${{ parameters.ReleaseTagVar }} -Variable "${{ parameters.ReleaseTagVarName }}" -CreateJson:$createJson
- $version = $releaseTag.Substring(1)
- $vstsCommandString = "vso[task.setvariable variable=Version]$version"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
-
- $azureVersion = $releaseTag.ToLowerInvariant() -replace '\.', '-'
- $vstsCommandString = "vso[task.setvariable variable=AzureVersion]$azureVersion"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- displayName: 'Set ${{ parameters.ReleaseTagVarName }} and other version Variables'
-
-- powershell: |
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: Capture environment
- condition: succeededOrFailed()
diff --git a/tools/releaseBuild/azureDevOps/templates/checkAzureContainer.yml b/tools/releaseBuild/azureDevOps/templates/checkAzureContainer.yml
deleted file mode 100644
index af6451004e4..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/checkAzureContainer.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-jobs:
-- job: DeleteBlob
- variables:
- - name: runCodesignValidationInjection
- value : false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: Azure Blob variable group
- displayName: Delete blob is exists
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- steps:
- - checkout: self
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
-
- - task: AzurePowerShell@4
- displayName: Check if blob exists and delete if specified
- inputs:
- azureSubscription: '$(AzureFileCopySubscription)'
- scriptType: inlineScript
- azurePowerShellVersion: latestVersion
- inline: |
- try {
- $container = Get-AzStorageContainer -Container '$(AzureVersion)' -Context (New-AzStorageContext -StorageAccountName '$(StorageAccount)') -ErrorAction Stop
-
- if ($container -ne $null -and '$(ForceAzureBlobDelete)' -eq 'false') {
- throw 'Azure blob container $(AzureVersion) already exists. To overwrite, use ForceAzureBlobDelete parameter'
- }
- elseif ($container -ne $null -and '$(ForceAzureBlobDelete)' -eq 'true') {
- Write-Verbose -Verbose 'Removing container $(AzureVersion) due to ForceAzureBlobDelete parameter'
- Remove-AzStorageContainer -Name '$(AzureVersion)' -Context (New-AzStorageContext -StorageAccountName '$(StorageAccount)') -Force
- }
- }
- catch {
- if ($_.FullyQualifiedErrorId -eq 'ResourceNotFoundException,Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.GetAzureStorageContainerCommand') {
- Write-Verbose -Verbose 'Container "$(AzureVersion)" does not exists.'
- }
- else {
- throw $_
- }
- }
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/cloneToOfficialPath.yml b/tools/releaseBuild/azureDevOps/templates/cloneToOfficialPath.yml
deleted file mode 100644
index 352458390f9..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/cloneToOfficialPath.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-parameters:
- nativePathRoot: ''
-
-steps:
- - powershell: |
- $dirSeparatorChar = [system.io.path]::DirectorySeparatorChar
- $nativePath = "${{parameters.nativePathRoot }}${dirSeparatorChar}PowerShell"
- Write-Host "##vso[task.setvariable variable=PowerShellRoot]$nativePath"
-
- if ((Test-Path "$nativePath")) {
- Remove-Item -Path "$nativePath" -Force -Recurse -Verbose -ErrorAction ignore
- }
- else {
- Write-Verbose -Verbose -Message "No cleanup required."
- }
-
- git clone --quiet $env:REPOROOT $nativePath
- displayName: Clone PowerShell Repo to /PowerShell
- errorActionPreference: silentlycontinue
diff --git a/tools/releaseBuild/azureDevOps/templates/compliance.yml b/tools/releaseBuild/azureDevOps/templates/compliance.yml
deleted file mode 100644
index 0a416389bf4..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/compliance.yml
+++ /dev/null
@@ -1,124 +0,0 @@
-parameters:
- parentJobs: []
-
-jobs:
-- job: compliance
- variables:
- - name: runCodesignValidationInjection
- value : false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
-
- displayName: Compliance
- dependsOn:
- ${{ parameters.parentJobs }}
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: self
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download artifacts'
- inputs:
- buildType: current
- downloadType: single
- artifactName: results
- downloadPath: '$(System.ArtifactsDirectory)'
-
- - powershell: |
- dir "$(System.ArtifactsDirectory)\*" -Recurse
- displayName: 'Capture artifacts directory'
- continueOnError: true
-
- - template: expand-compliance.yml
- parameters:
- architecture: fxdependent
- version: $(version)
-
- - template: expand-compliance.yml
- parameters:
- architecture: x86
- version: $(version)
-
- - template: expand-compliance.yml
- parameters:
- architecture: x64
- version: $(version)
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-antimalware.AntiMalware@3
- displayName: 'Run Defender Scan'
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@3
- displayName: 'Run BinSkim '
- inputs:
- InputType: Basic
- AnalyzeTarget: '$(CompliancePath)\*.dll;$(CompliancePath)\*.exe'
- AnalyzeSymPath: 'SRV*'
- AnalyzeVerbose: true
- AnalyzeHashes: true
- AnalyzeStatistics: true
- continueOnError: true
-
- # add RoslynAnalyzers
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-autoapplicability.AutoApplicability@1
- displayName: 'Run AutoApplicability'
- inputs:
- ExternalRelease: true
- IsSoftware: true
- DataSensitivity: lbi
- continueOnError: true
-
- # add codeMetrics
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-vulnerabilityassessment.VulnerabilityAssessment@0
- displayName: 'Run Vulnerability Assessment'
- continueOnError: true
-
- # FXCop is not applicable
-
- # PreFASt is not applicable
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
- displayName: 'Publish Security Analysis Logs to Build Artifacts'
- continueOnError: true
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-uploadtotsa.TSAUpload@1
- displayName: 'TSA upload to Codebase: PowerShellCore_201906'
- inputs:
- tsaVersion: TsaV2
- codeBaseName: 'PowerShellCore_201906'
- uploadAPIScan: false
- uploadBinSkim: true
- uploadCredScan: false
- uploadFortifySCA: false
- uploadFxCop: false
- uploadModernCop: false
- uploadPoliCheck: false
- uploadPREfast: false
- uploadRoslyn: false
- uploadTSLint: false
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-report.SdtReport@1
- displayName: 'Create Security Analysis Report'
- inputs:
- TsvFile: false
- APIScan: false
- BinSkim: true
- CredScan: true
- PoliCheck: true
- PoliCheckBreakOn: Severity2Above
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(Build.SourcesDirectory)\tools'
- snapshotForceEnabled: true
diff --git a/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml b/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml
deleted file mode 100644
index 2047ad3e0b9..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml
+++ /dev/null
@@ -1,180 +0,0 @@
-jobs:
- - job: APIScan
- variables:
- - name: runCodesignValidationInjection
- value : false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: ReleaseTagVar
- value: fromBranch
- # Defines the variables APIScanClient, APIScanTenant and APIScanSecret
- - group: PS-PS-APIScan
- # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission.
- # A PAT in the wrong org will give a single Error 203. No PAT will give a single Error 401, and individual pdbs may be missing even if permissions are correct.
- - group: symbols
- - name: branchCounterKey
- value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])]
- - name: branchCounter
- value: $[counter(variables['branchCounterKey'], 1)]
- - group: DotNetPrivateBuildAccess
- - group: Azure Blob variable group
- - group: ReleasePipelineSecrets
- - group: mscodehub-feed-read-general
- - group: mscodehub-feed-read-akv
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- # APIScan can take a long time
- timeoutInMinutes: 180
-
- steps:
- - template: ../SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
-
- - template: ../insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: '$(Build.SourcesDirectory)'
-
- - pwsh: |
- Import-Module .\build.psm1 -force
- Start-PSBootstrap
- workingDirectory: '$(Build.SourcesDirectory)'
- retryCountOnTaskFailure: 2
- displayName: 'Bootstrap'
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- Import-Module .\build.psm1 -force
- Find-DotNet
- dotnet tool install dotnet-symbol --tool-path $(Agent.ToolsDirectory)\tools\dotnet-symbol
- $symbolToolPath = Get-ChildItem -Path $(Agent.ToolsDirectory)\tools\dotnet-symbol\dotnet-symbol.exe | Select-Object -First 1 -ExpandProperty FullName
- Write-Host "##vso[task.setvariable variable=symbolToolPath]$symbolToolPath"
- displayName: Install dotnet-symbol
- retryCountOnTaskFailure: 2
-
- - pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1'
- Install-AzCopy
- displayName: Install AzCopy
- retryCountOnTaskFailure: 2
-
- - pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1'
- $azcopy = Find-AzCopy
- Write-Verbose -Verbose "Found AzCopy: $azcopy"
-
- $winverifySymbolsPath = New-Item -ItemType Directory -Path '$(System.ArtifactsDirectory)/winverify-symbols' -Force
- Write-Host "##vso[task.setvariable variable=winverifySymbolsPath]$winverifySymbolsPath"
-
- & $azcopy cp https://$(StorageAccount).blob.core.windows.net/winverify-private $winverifySymbolsPath --recursive
-
- Get-ChildItem $winverifySymbolsPath -Recurse | Out-String | Write-Verbose -Verbose
-
- displayName: Download winverify-private Artifacts
- retryCountOnTaskFailure: 2
- env:
- AZCOPY_AUTO_LOGIN_TYPE: MSI
-
- - pwsh: |
- Import-Module .\build.psm1 -force
- Find-DotNet
- Start-PSBuild -Configuration StaticAnalysis -PSModuleRestore -Clean -Runtime fxdependent-win-desktop
-
- $OutputFolder = Split-Path (Get-PSOutput)
- Write-Host "##vso[task.setvariable variable=BinDir]$OutputFolder"
-
- Write-Verbose -Verbose -Message "Deleting ref folder from output folder"
- if (Test-Path $OutputFolder/ref) {
- Remove-Item -Recurse -Force $OutputFolder/ref
- }
- workingDirectory: '$(Build.SourcesDirectory)'
- displayName: 'Build PowerShell Source'
-
- - pwsh: |
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: Capture Environment
- condition: succeededOrFailed()
-
- # Explicitly download symbols for the drop since the SDL image doesn't have http://SymWeb access and APIScan cannot handle https yet.
- - pwsh: |
- Import-Module .\build.psm1 -force
- Find-DotNet
- $pat = '$(SymbolServerPAT)'
- if ($pat -like '*PAT*' -or $pat -eq '')
- {
- throw 'No PAT defined'
- }
- $url = 'https://microsoft.artifacts.visualstudio.com/defaultcollection/_apis/symbol/symsrv'
- $(symbolToolPath) --authenticated-server-path $(SymbolServerPAT) $url --symbols -d "$env:BinDir\*" --recurse-subdirectories
- displayName: 'Download Symbols for binaries'
- retryCountOnTaskFailure: 2
- workingDirectory: '$(Build.SourcesDirectory)'
-
- - pwsh: |
- Get-ChildItem '$(BinDir)' -File -Recurse |
- Foreach-Object {
- [pscustomobject]@{
- Path = $_.FullName
- Version = $_.VersionInfo.FileVersion
- Md5Hash = (Get-FileHash -Algorithm MD5 -Path $_.FullName).Hash
- Sha512Hash = (Get-FileHash -Algorithm SHA512 -Path $_.FullName).Hash
- }
- } | Export-Csv -Path '$(Build.SourcesDirectory)/ReleaseFileHash.csv'
- displayName: 'Create release file hash artifact'
-
- - task: PublishBuildArtifacts@1
- displayName: 'Publish Build File Hash artifact'
- inputs:
- pathToPublish: '$(Build.SourcesDirectory)/ReleaseFileHash.csv'
- artifactName: ReleaseFilesHash
- retryCountOnTaskFailure: 2
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-apiscan.APIScan@2
- displayName: 'Run APIScan'
- inputs:
- softwareFolder: '$(BinDir)'
- softwareName: PowerShell
- softwareVersionNum: '$(ReleaseTagVar)'
- isLargeApp: false
- preserveTempFiles: false
- verbosityLevel: standard
- # write a status update every 5 minutes. Default is 1 minute
- statusUpdateInterval: '00:05:00'
- env:
- AzureServicesAuthConnectionString: RunAs=App
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-report.SdtReport@2
- continueOnError: true
- displayName: 'Guardian Export'
- inputs:
- GdnExportVstsConsole: true
- GdnExportSarifFile: true
- GdnExportHtmlFile: true
- GdnExportAllTools: false
- GdnExportGdnToolApiScan: true
- #this didn't do anything GdnExportCustomLogsFolder: '$(Build.ArtifactStagingDirectory)/Guardian'
-
- - task: TSAUpload@2
- displayName: 'TSA upload'
- inputs:
- GdnPublishTsaOnboard: false
- GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)\tools\guardian\tsaconfig-APIScan.json'
-
- - pwsh: |
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: Capture Environment
- condition: succeededOrFailed()
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3
- displayName: 'Publish Guardian Artifacts'
- inputs:
- AllTools: false
- APIScan: true
- ArtifactName: APIScan
diff --git a/tools/releaseBuild/azureDevOps/templates/compliance/compliance.yml b/tools/releaseBuild/azureDevOps/templates/compliance/compliance.yml
deleted file mode 100644
index 8db52fc83f0..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/compliance/compliance.yml
+++ /dev/null
@@ -1,83 +0,0 @@
-parameters:
- - name: parentJobs
- type: jobList
-
-jobs:
-- job: compliance
- variables:
- - name: runCodesignValidationInjection
- value : false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
-
- # Defines the variables APIScanClient, APIScanTenant and APIScanSecret
- - group: PS-PS-APIScan
-
- displayName: Compliance
- dependsOn:
- ${{ parameters.parentJobs }}
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- # APIScan can take a long time
- timeoutInMinutes: 180
-
- steps:
- - checkout: self
- clean: true
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
- displayName: 'Run CredScan'
- inputs:
- suppressionsFile: tools/credScan/suppress.json
- debugMode: false
- continueOnError: true
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2
- displayName: 'Run PoliCheck'
- inputs:
- # targetType F means file or folder and is the only applicable value and the default
- targetType: F
- # 1 to enable source code comment scanning, which is what we should do for open source
- optionsFC: 1
- # recurse
- optionsXS: 1
- # run for severity 1, 2, 3 and 4 issues
- optionsPE: '1|2|3|4'
- # disable history management
- optionsHMENABLE: 0
- # Excluclusion access database
- optionsRulesDBPath: '$(Build.SourcesDirectory)\tools\terms\PowerShell-Terms-Rules.mdb'
- # Terms Exclusion xml file
- optionsUEPath: $(Build.SourcesDirectory)\tools\terms\TermsExclusion.xml
- continueOnError: true
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3
- displayName: 'Publish Security Analysis Logs to Build Artifacts'
- continueOnError: true
-
- - task: TSAUpload@2
- displayName: 'TSA upload'
- inputs:
- GdnPublishTsaOnboard: false
- GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)\tools\guardian\tsaconfig-others.json'
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-report.SdtReport@1
- displayName: 'Create Security Analysis Report'
- inputs:
- TsvFile: false
- APIScan: false
- BinSkim: false
- CredScan: true
- PoliCheck: true
- PoliCheckBreakOn: Severity2Above
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(Build.SourcesDirectory)\tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/compliance/generateNotice.yml b/tools/releaseBuild/azureDevOps/templates/compliance/generateNotice.yml
deleted file mode 100644
index 3e91b9174d2..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/compliance/generateNotice.yml
+++ /dev/null
@@ -1,90 +0,0 @@
-parameters:
- - name: parentJobs
- type: jobList
-
-jobs:
-- job: generateNotice
- variables:
- - name: runCodesignValidationInjection
- value : false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
-
- displayName: Generate Notice
- dependsOn:
- ${{ parameters.parentJobs }}
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- timeoutInMinutes: 15
-
- steps:
- - checkout: self
- clean: true
-
- - pwsh: |
- [string]$Branch=$env:BUILD_SOURCEBRANCH
- $branchOnly = $Branch -replace '^refs/heads/';
- $branchOnly = $branchOnly -replace '[_\-]'
-
- if ($branchOnly -eq 'master') {
- $container = 'tpn'
- } else {
- $branchOnly = $branchOnly -replace '[\./]', '-'
- $container = "tpn-$branchOnly"
- }
-
- $vstsCommandString = "vso[task.setvariable variable=tpnContainer]$container"
- Write-Verbose -Message $vstsCommandString -Verbose
- Write-Host -Object "##$vstsCommandString"
- displayName: Set ContainerName
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(Build.SourcesDirectory)\tools'
-
- - pwsh: |
- ./tools/clearlyDefined/ClearlyDefined.ps1 -TestAndHarvest
- displayName: Verify that packages have license data
-
- - task: msospo.ospo-extension.8d7f9abb-6896-461d-9e25-4f74ed65ddb2.notice@0
- displayName: 'NOTICE File Generator'
- inputs:
- outputfile: '$(System.ArtifactsDirectory)\ThirdPartyNotices.txt'
- # output format can be html or text
- outputformat: text
- # this isn't working
- # additionaldata: $(Build.SourcesDirectory)\assets\additionalAttributions.txt
-
-
- - pwsh: |
- Get-Content -Raw -Path $(Build.SourcesDirectory)\assets\additionalAttributions.txt | Out-File '$(System.ArtifactsDirectory)\ThirdPartyNotices.txt' -Encoding utf8NoBOM -Force -Append
- Get-Content -Raw -Path '$(Build.SourcesDirectory)\assets\additionalAttributions.txt'
- displayName: Append Additional Attributions
- continueOnError: true
-
- - pwsh: |
- Get-Content -Raw -Path '$(System.ArtifactsDirectory)\ThirdPartyNotices.txt'
- displayName: Capture Notice
- continueOnError: true
-
- - task: AzureFileCopy@4
- displayName: 'upload Notice'
- inputs:
- SourcePath: $(System.ArtifactsDirectory)\ThirdPartyNotices.txt
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: $(tpnContainer)
- resourceGroup: '$(StorageResourceGroup)'
- retryCountOnTaskFailure: 2
-
- - task: PublishPipelineArtifact@1
- inputs:
- targetPath: $(System.ArtifactsDirectory)
- artifactName: notice
- displayName: Publish notice artifacts
- retryCountOnTaskFailure: 2
diff --git a/tools/releaseBuild/azureDevOps/templates/expand-compliance.yml b/tools/releaseBuild/azureDevOps/templates/expand-compliance.yml
deleted file mode 100644
index 4cc25433262..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/expand-compliance.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-parameters:
- architecture: x86
- version: 6.2.0
-
-steps:
- - powershell: |
- Expand-Archive -Path "$(System.ArtifactsDirectory)\results\PowerShell-${{ parameters.version }}-symbols-win-${{ parameters.architecture }}.zip" -Destination "$(Build.StagingDirectory)\symbols\${{ parameters.architecture }}"
- displayName: Expand symbols zip - ${{ parameters.architecture }}
-
- - powershell: |
- tools/releaseBuild/createComplianceFolder.ps1 -ArtifactFolder "$(Build.StagingDirectory)\symbols\${{ parameters.architecture }}" -VSTSVariableName 'CompliancePath'
- displayName: Expand Compliance file - ${{ parameters.architecture }}
diff --git a/tools/releaseBuild/azureDevOps/templates/global-tool-pkg-sbom.yml b/tools/releaseBuild/azureDevOps/templates/global-tool-pkg-sbom.yml
deleted file mode 100644
index 5cdf5675079..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/global-tool-pkg-sbom.yml
+++ /dev/null
@@ -1,64 +0,0 @@
-parameters:
- - name: PackageVersion
- - name: LinuxBinPath
- - name: WindowsBinPath
- - name: WindowsDesktopBinPath
- - name: AlpineBinPath
- - name: DestinationPath
- - name: ListOfPackageTypes
- type: object
- default:
- - Unified
- - PowerShell.Linux.Alpine
- - PowerShell.Linux.x64
- - PowerShell.Linux.arm32
- - PowerShell.Linux.arm64
- - PowerShell.Windows.x64
-
-steps:
-
-- pwsh: |
- Write-Verbose -Verbose 'LinuxBinPath path: ${{ parameters.LinuxBinPath }}'
- Write-Verbose -Verbose 'WindowsBinPath path: ${{ parameters.WindowsBinPath }}'
- Write-Verbose -Verbose 'WindowsDesktopBinPath path: ${{ parameters.WindowsDesktopBinPath }}'
- Write-Verbose -Verbose 'AlpineBinPath path: ${{ parameters.AlpineBinPath }}'
-
- Import-Module -Name $env:REPOROOT\build.psm1
- Import-Module -Name $env:REPOROOT\tools\packaging
- Start-PrepForGlobalToolNupkg -LinuxBinPath '${{ parameters.LinuxBinPath }}' -WindowsBinPath '${{ parameters.WindowsBinPath }}' -WindowsDesktopBinPath '${{ parameters.WindowsDesktopBinPath }}' -AlpineBinPath '${{ parameters.AlpineBinPath }}'
- displayName: 'Preparation for Global Tools package creation.'
-
-# NOTE: The Unified package must always be created first, and so must always be first in ListOfPackageTypes.
-- ${{ each value in parameters.ListOfPackageTypes }}:
- - pwsh: |
- $PackageType = '${{ value }}'
-
- Write-Verbose -Verbose "PackageType: $PackageType"
- Write-Verbose -Verbose 'Destination path: ${{ parameters.PackagePath }}'
-
- # Create global tool NuSpec source for package.
- Import-Module -Name $env:REPOROOT\build.psm1
- Import-Module -Name $env:REPOROOT\tools\packaging
- New-GlobalToolNupkgSource -PackageType $PackageType -PackageVersion '${{ parameters.PackageVersion }}' -LinuxBinPath '${{ parameters.LinuxBinPath }}' -WindowsBinPath '${{ parameters.WindowsBinPath }}' -WindowsDesktopBinPath '${{ parameters.WindowsDesktopBinPath }}' -AlpineBinPath '${{ parameters.AlpineBinPath }}'
- displayName: 'Create global tool NuSpec source for package.'
-
- - pwsh: |
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: 'Capture environment variables after Global Tool package source is created.'
-
- # NOTE: The above 'New-GlobalToolNupkgSource' task function sets the 'GlobalToolNuSpecSourcePath', 'GlobalToolPkgName',
- # and 'GlobalToolCGManifestPath' environment variables.
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: $(GlobalToolNuSpecSourcePath)
- Build_Repository_Uri: 'https://github.com/powershell/powershell'
- PackageName: $(GlobalToolPkgName)
- PackageVersion: ${{ parameters.PackageVersion }}
- sourceScanPath: $(GlobalToolCGManifestPath)
- displayName: SBOM for Global Tool package
-
- - pwsh: |
- Import-Module -Name $env:REPOROOT\build.psm1
- Import-Module -Name $env:REPOROOT\tools\packaging
- New-GlobalToolNupkgFromSource -PackageNuSpecPath "$env:GlobalToolNuSpecSourcePath" -PackageName "$env:GlobalToolPkgName" -DestinationPath '${{ parameters.DestinationPath }}' -CGManifestPath "$env:GlobalToolCGManifestPath"
- displayName: 'Create global tool NuSpec package from NuSpec source.'
diff --git a/tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml b/tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml
deleted file mode 100644
index 61b9df6c342..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-parameters:
-- name: "repoRoot"
- default: $(REPOROOT)
-steps:
- - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self
- parameters:
- repoRoot: $(REPOROOT)
-
diff --git a/tools/releaseBuild/azureDevOps/templates/json.yml b/tools/releaseBuild/azureDevOps/templates/json.yml
deleted file mode 100644
index 48a50e0bf14..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/json.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-parameters:
- parentJobs: []
-
-jobs:
-- job: json
- variables:
- - name: runCodesignValidationInjection
- value : false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- displayName: Create Json for Blob
- dependsOn:
- ${{ parameters.parentJobs }}
- condition: succeeded()
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- #- task: @
- # inputs:
- #
- # displayName: ''
- - checkout: self
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
-
- - task: AzureFileCopy@4
- displayName: 'upload daily-build-info JSON file to Azure - ${{ parameters.architecture }}'
- inputs:
- SourcePath: '$(BuildInfoPath)'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: 'BuildInfo'
- condition: and(succeeded(), eq(variables['IS_DAILY'], 'true'))
-
- - task: AzureCLI@1
- displayName: 'Make blob public'
- inputs:
- azureSubscription: '$(AzureFileCopySubscription)'
- scriptLocation: inlineScript
- inlineScript: 'az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion) --public-access blob'
- condition: and(succeeded(), eq(variables['IS_DAILY'], 'true'))
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(Build.SourcesDirectory)\tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml b/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml
deleted file mode 100644
index 719ba1a6c30..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml
+++ /dev/null
@@ -1,184 +0,0 @@
-jobs:
-- job: sign_linux_builds
- displayName: Sign all linux builds
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- dependsOn: ['build_fxdependent', 'build_rpm']
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: ESRP
-
- steps:
- - checkout: self
- clean: true
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuild.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars
- displayName: Download deb build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildMinSize.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars
- displayName: Download min-size build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildArm32.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars
- displayName: Download arm32 build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildArm64.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars
- displayName: Download arm64 build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshMarinerBuildAmd64.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars
- displayName: Download mariner build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshMarinerBuildArm64.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars
- displayName: Download mariner arm64 build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildAlpine.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildAlpine.tar.gz
- displayName: Download alpine build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildAlpine.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars/pwshAlpineFxdBuildAmd64.tar.gz
- displayName: Download alpine fxdependent build
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildFxdependent.tar.gz
- path: $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildFxdependent.tar.gz
- displayName: Download fxdependent build
-
- - pwsh: |
- Get-ChildItem -Path $(Build.ArtifactStagingDirectory)/linuxTars
- displayName: Capture downloaded tars
-
- - pwsh: |
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild
- Write-Verbose -Verbose "File permisions after expanding"
- Get-ChildItem -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild/pwsh | Select-Object -Property 'unixmode', 'size', 'name'
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildMinSize.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildMinSize.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm32.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm32.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildAlpine.tar.gz/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildAlpine.tar.gz/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshAlpineFxdBuildAmd64.tar.gz/pwshAlpineFxdBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpineFxd"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpineFxd -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshAlpineFxdBuildAmd64.tar.gz/pwshAlpineFxdBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpineFxd
-
- Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildFxdependent.tar.gz/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildFxdependent.tar.gz/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent
- displayName: Expand builds
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - template: cloneToOfficialPath.yml
-
- - template: insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(PowerShellRoot)
-
- - pwsh: |
- Set-Location $env:POWERSHELLROOT
- import-module "$env:POWERSHELLROOT/build.psm1"
- Sync-PSTags -AddRemoteIfMissing
- displayName: SyncTags
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
-
- - checkout: ComplianceRepo
- clean: true
-
- - template: shouldSign.yml
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshLinuxBuild
- buildPrefixName: 'PowerShell Linux'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshLinuxBuildMinSize
- buildPrefixName: 'PowerShell Linux Minimum Size'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshLinuxBuildArm32
- buildPrefixName: 'PowerShell Linux Arm32'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshLinuxBuildArm64
- buildPrefixName: 'PowerShell Linux Arm64'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshMarinerBuildAmd64
- buildPrefixName: 'PowerShell Linux x64 (Mariner) Framework Dependent'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshMarinerBuildArm64
- buildPrefixName: 'PowerShell Linux arm64 (Mariner) Framework Dependent'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshLinuxBuildAlpine
- buildPrefixName: 'PowerShell Linux Alpine x64'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshLinuxBuildAlpineFxd
- buildPrefixName: 'PowerShell Linux Alpine Fxd x64'
-
- - template: signBuildFiles.yml
- parameters:
- binLocation: pwshLinuxBuildFxdependent
- buildPrefixName: 'PowerShell Linux Framework Dependent'
diff --git a/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml b/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml
deleted file mode 100644
index 9d0c69053b5..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml
+++ /dev/null
@@ -1,489 +0,0 @@
-parameters:
- buildName: ''
- uploadDisplayName: 'Upload'
-
-jobs:
-- job: pkg_${{ parameters.buildName }}
- displayName: Package ${{ parameters.buildName }}
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMSUbuntu20.04-Secure
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: build
- value: ${{ parameters.buildName }}
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: ESRP
- - group: DotNetPrivateBuildAccess
-
- steps:
- - ${{ if or(eq(variables.build,'deb'), eq(variables.build,'rpm')) }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-signed
- pattern: '**/pwshLinuxBuild.tar.gz'
- displayName: Download deb build
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-signed
- pattern: '**/pwshLinuxBuildMinSize.tar.gz'
- displayName: Download min-size build
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-signed
- pattern: '**/pwshLinuxBuildArm32.tar.gz'
- displayName: Download arm32 build
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-signed
- pattern: '**/pwshLinuxBuildArm64.tar.gz'
- displayName: Download arm64 build
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-signed
- pattern: '**/pwshMarinerBuildAmd64.tar.gz'
- displayName: Download mariner amd64 build
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-signed
- pattern: '**/pwshMarinerBuildArm64.tar.gz'
- displayName: Download mariner arm64 build
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine-signed
- pattern: '**/pwshLinuxBuildAlpine.tar.gz'
- displayName: Download alpine build
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-signed
- pattern: '**/pwshAlpineFxdBuildAmd64.tar.gz'
- displayName: Download alpine framework dependent build
-
- - ${{ if eq(variables.build,'fxdependent') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: authenticode-signed
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent-signed
- pattern: '**/pwshLinuxBuildFxdependent.tar.gz'
- displayName: Download fxdependent build
-
- - ${{ if or(eq(variables.build,'deb'), eq(variables.build,'rpm')) }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuild-meta
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta
- displayName: Download deb build meta
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildMinSize-meta
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-meta
- displayName: Download min-size build meta
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildArm32-meta
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-meta
- displayName: Download arm32 build meta
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildArm64-meta
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-meta
- displayName: Download arm64 build meta
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshMarinerBuildAmd64-meta
- path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-meta
- displayName: Download mariner x64 build meta
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshMarinerBuildArm64-meta
- path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-meta
- displayName: Download mariner arm64 build meta
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildAlpine-meta
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta
- displayName: Download alpine build meta
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshAlpineFxdBuildAmd64-meta
- path: $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-meta
- displayName: Download alpine build meta
-
- - ${{ if eq(variables.build,'fxdependent') }} :
- - task: DownloadPipelineArtifact@2
- inputs:
- artifact: pwshLinuxBuildFxdependent-meta
- path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta
- displayName: Download fxdependent build meta
-
- - pwsh: |
- Get-ChildItem '$(Build.ArtifactStagingDirectory)' | Select-Object -Property 'unixmode', 'size', 'name'
- displayName: Capture downloads
-
- - pwsh: |
- if ('$(build)' -eq 'deb' -or '$(build)' -eq 'rpm') {
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-signed/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-signed/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild
- }
-
- if ('$(build)' -eq 'deb') {
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-signed/pwshLinuxBuildMinSize.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-signed/pwshLinuxBuildMinSize.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize
-
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-signed/pwshLinuxBuildArm32.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-signed/pwshLinuxBuildArm32.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32
-
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-signed/pwshLinuxBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-signed/pwshLinuxBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64
- }
-
- if ('$(build)' -eq 'rpm') {
- # for mariner x64
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-signed/pwshMarinerBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-signed/pwshMarinerBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64
-
- # for mariner arm64
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-signed/pwshMarinerBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-signed/pwshMarinerBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64
- }
-
- if ('$(build)' -eq 'alpine') {
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine-signed/pwshLinuxBuildAlpine.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine-signed/pwshLinuxBuildAlpine.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild
-
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-signed/pwshAlpineFxdBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64 -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-signed/pwshAlpineFxdBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64
- }
-
- if ('$(build)' -eq 'fxdependent') {
- Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent-signed/pwshLinuxBuildFxdependent.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild"
- New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory
- tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent-signed/pwshLinuxBuildFxdependent.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild
- }
- displayName: Expand all signed tar.gz
-
- - pwsh: |
- Get-ChildItem '$(Build.ArtifactStagingDirectory)' | Select-Object -Property 'unixmode', 'size', 'name'
- displayName: Capture expanded
-
- - checkout: self
- clean: true
-
- - checkout: ComplianceRepo
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - pwsh: |
- # create folder
- sudo mkdir /PowerShell
-
- # make the current user the owner
- sudo chown $env:USER /PowerShell
- displayName: 'Create /PowerShell'
-
- - template: cloneToOfficialPath.yml
-
- - template: insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(PowerShellRoot)
-
- - powershell: |
- import-module "$env:POWERSHELLROOT/build.psm1"
- Sync-PSTags -AddRemoteIfMissing
- displayName: SyncTags
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
- workingDirectory: $(PowerShellRoot)
-
- - powershell: |
- Import-Module "$env:POWERSHELLROOT/build.psm1"
-
- Start-PSBootstrap -Scenario Package
- displayName: 'Bootstrap'
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
- workingDirectory: $(PowerShellRoot)
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - powershell: |
- try {
- Import-Module "$env:POWERSHELLROOT/build.psm1"
- Import-Module "$env:POWERSHELLROOT/tools/packaging"
-
- $metadata = Get-Content "$env:POWERSHELLROOT/tools/metadata.json" -Raw | ConvertFrom-Json
-
- # LTSRelease.Package indicates that the release should be packaged as an LTS
- $LTS = $metadata.LTSRelease.Package
- Write-Verbose -Verbose -Message "LTS is set to: $LTS"
-
- Invoke-AzDevOpsLinuxPackageCreation -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)'
-
- if ($LTS) {
- Write-Verbose -Verbose "Packaging LTS"
- Invoke-AzDevOpsLinuxPackageCreation -LTS -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)'
- }
- } catch {
- Get-Error
- throw
- }
- displayName: 'Package'
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
- workingDirectory: $(PowerShellRoot)
-
- - powershell: |
- $linuxPackages = Get-ChildItem "$env:POWERSHELLROOT/powershell*" -Include *.deb,*.rpm,*.tar.gz
-
- $bucket = 'release'
- foreach ($linuxPackage in $linuxPackages)
- {
- $filePath = $linuxPackage.FullName
- Write-Verbose "Publishing $filePath to $bucket" -Verbose
- Write-Host "##vso[artifact.upload containerfolder=$bucket;artifactname=$bucket]$filePath"
- }
- displayName: Publish artifacts
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
- workingDirectory: $(PowerShellRoot)
- retryCountOnTaskFailure: 2
-
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
-
-- job: upload_${{ parameters.buildName }}
- displayName: ${{ parameters.uploadDisplayName }} ${{ parameters.buildName }}
- dependsOn: pkg_${{ parameters.buildName }}
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- variables:
- - name: buildName
- value: ${{ parameters.buildName }}
- - group: ESRP
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: skipComponentGovernanceDetection
- value: true
-
- steps:
- - checkout: self
- clean: true
-
- - checkout: ComplianceRepo
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
- - template: shouldSign.yml
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download Deb Artifacts'
- inputs:
- downloadType: specific
- itemPattern: '**/*.deb'
- downloadPath: '$(System.ArtifactsDirectory)\finished'
- condition: and(eq(variables['buildName'], 'DEB'), succeeded())
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download tar.gz Artifacts copy'
- inputs:
- downloadType: specific
- itemPattern: '**/*.tar.gz'
- downloadPath: '$(System.ArtifactsDirectory)\finished'
-
- - powershell: |
- Write-Host 'We handle the min-size package only when uploading for deb build.'
- Write-Host '- For deb build, the min-size package is moved to a separate folder "finished\minSize",'
- Write-Host ' so that the min-size package can be uploaded to a different Az Blob container.'
- Write-Host '- For other builds, the min-size package is removed after being downloaded, so that it'
- Write-Host ' does not get accidentally uploaded to the wrong Az Blob container.'
-
- $minSizePkg = '$(System.ArtifactsDirectory)\finished\release\*-gc.tar.gz'
- if (Test-Path -Path $minSizePkg)
- {
- if ('$(buildName)' -eq 'DEB')
- {
- $minSizeDir = '$(System.ArtifactsDirectory)\finished\minSize'
- New-Item -Path $minSizeDir -Type Directory -Force > $null
- Move-Item -Path $minSizePkg -Destination $minSizeDir
-
- Write-Host "`nCapture the min-size package moved to the target folder."
- Get-ChildItem -Path $minSizeDir
- }
- else
- {
- Write-Host '$(buildName): Remove the min-size package.'
- Remove-Item -Path $minSizePkg -Force
- }
- }
- else
- {
- Write-Host 'min-size package not found, so skip this step.'
- }
- displayName: 'Move minSize package to separate folder'
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download rpm Artifacts copy'
- inputs:
- downloadType: specific
- itemPattern: '**/*.rpm'
- downloadPath: '$(System.ArtifactsDirectory)\rpm'
- condition: and(eq(variables['buildName'], 'RPM'), succeeded())
-
- - template: EsrpScan.yml@ComplianceRepo
- parameters:
- scanPath: $(System.ArtifactsDirectory)
- pattern: |
- **\*.rpm
- **\*.deb
- **\*.tar.gz
-
- - ${{ if eq(variables['buildName'], 'RPM') }}:
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\rpm
- signOutputPath: $(Build.StagingDirectory)\signedPackages
- certificateId: "CP-450779-Pgp"
- pattern: |
- **\*.rh.*.rpm
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign RedHat RPM
- OutputMode: AlwaysCopy
-
- - ${{ if eq(variables['buildName'], 'RPM') }}:
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- # Sign in-place, previous task copied the files to this folder
- buildOutputPath: $(Build.StagingDirectory)\signedPackages
- signOutputPath: $(Build.StagingDirectory)\signedPackages
- certificateId: "CP-459159-Pgp"
- pattern: |
- **\*.cm.*.rpm
- **\*.cm?.*.rpm
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign Mariner RPM
- OutputMode: NeverCopy
-
- # requires windows
- - ${{ if ne(variables['buildName'], 'RPM') }}:
- - task: AzureFileCopy@4
- displayName: 'Upload to Azure - DEB and tar.gz'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\finished\release\*'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)'
- retryCountOnTaskFailure: 2
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\finished\release
-
- # requires windows
- - task: AzureFileCopy@4
- displayName: 'Upload to Azure - min-size package for Guest Config'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\finished\minSize\*'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)-gc'
- condition: and(eq(variables['buildName'], 'DEB'), succeeded())
- retryCountOnTaskFailure: 2
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\finished\minSize
- condition: and(eq(variables['buildName'], 'DEB'), succeeded())
-
- # requires windows
- - task: AzureFileCopy@4
- displayName: 'Upload to Azure - RPM - Unsigned'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\rpm\release\*'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)'
- condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM'))
- retryCountOnTaskFailure: 2
-
- # requires windows
- - task: AzureFileCopy@4
- displayName: 'Upload to Azure - RPM - Signed'
- inputs:
- SourcePath: '$(Build.StagingDirectory)\signedPackages\release\*'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)'
- condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM'))
- retryCountOnTaskFailure: 2
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\rpm\release
- condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM'))
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: '$(Build.StagingDirectory)\signedPackages\release'
- condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM'))
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/linux.yml b/tools/releaseBuild/azureDevOps/templates/linux.yml
deleted file mode 100644
index f61938ca130..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/linux.yml
+++ /dev/null
@@ -1,313 +0,0 @@
-parameters:
- buildName: ''
- uploadDisplayName: 'Upload'
- parentJob: ''
-
-jobs:
-- job: build_${{ parameters.buildName }}
- displayName: Build ${{ parameters.buildName }}
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMSUbuntu20.04-Secure
- dependsOn: ${{ parameters.parentJob }}
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: build
- value: ${{ parameters.buildName }}
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: ESRP
- - group: DotNetPrivateBuildAccess
-
- steps:
- - checkout: self
- clean: true
-
- - checkout: ComplianceRepo
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - pwsh: |
- # create folder
- sudo mkdir /PowerShell
-
- # make the current user the owner
- sudo chown $env:USER /PowerShell
- displayName: 'Create /PowerShell'
-
- - template: cloneToOfficialPath.yml
-
- - template: insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(PowerShellRoot)
-
- - powershell: |
- import-module "$env:POWERSHELLROOT/build.psm1"
- Sync-PSTags -AddRemoteIfMissing
- displayName: SyncTags
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
- workingDirectory: $(PowerShellRoot)
-
- - powershell: |
- Import-Module "$env:POWERSHELLROOT/build.psm1"
-
- Start-PSBootstrap -Scenario Package
- displayName: 'Bootstrap'
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
- workingDirectory: $(PowerShellRoot)
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- try {
- Import-Module "$env:POWERSHELLROOT/build.psm1"
- Import-Module "$env:POWERSHELLROOT/tools/packaging"
-
- Invoke-AzDevOpsLinuxPackageBuild -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)'
-
- Write-Verbose -Verbose "File permisions after building"
- Get-ChildItem -Path $(System.ArtifactsDirectory)/pwshLinuxBuild/pwsh | Select-Object -Property 'unixmode', 'size', 'name'
-
- } catch {
- Get-Error
- throw
- }
- displayName: 'Build'
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
- workingDirectory: $(PowerShellRoot)
-
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuild'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- displayName: ${{ parameters.buildName }} SBOM
- PackageName: PowerShell Linux
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - ${{ if eq(variables.build,'rpm') }} :
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- displayName: Mariner x64 SBOM
- PackageName: PowerShell Linux Framework Dependent
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - ${{ if eq(variables.build,'rpm') }} :
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- displayName: Mariner arm64 SBOM
- PackageName: PowerShell Linux Framework Dependent
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - ${{ if eq(variables.build,'deb') }} :
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- displayName: MinSize SBOM
- PackageName: PowerShell Linux Minimum Size
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - ${{ if eq(variables.build,'deb') }} :
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- displayName: Arm32 SBOM
- PackageName: PowerShell Linux Arm32
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - ${{ if eq(variables.build,'deb') }} :
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- displayName: Arm64 SBOM
- PackageName: PowerShell Linux Arm64
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - ${{ if eq(variables.build,'alpine') }} :
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- displayName: Alpine FXD SBOM
- PackageName: PowerShell Alpine Framework Dependent AMD64
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - pwsh: |
- Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuild'
- Write-Verbose -Verbose "File permisions before compressing"
- Get-ChildItem -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild/pwsh | Select-Object -Property 'unixmode', 'size', 'name'
- tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz *
- displayName: Compress pwshLinuxBuild
-
- - ${{ if eq(variables.build,'deb') }} :
- - pwsh: |
- Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize'
- tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuildMinSize.tar.gz *
- Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32'
- tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuildArm32.tar.gz *
- Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64'
- tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuildArm64.tar.gz *
- displayName: Compress deb
-
- - ${{ if eq(variables.build,'rpm') }} :
- - pwsh: |
- Set-Location '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64'
- tar -czvf $(System.ArtifactsDirectory)/pwshMarinerBuildAmd64.tar.gz *
- displayName: Compress pwshMarinerBuildAmd64
-
- - ${{ if eq(variables.build,'alpine') }} :
- - pwsh: |
- Set-Location '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64'
- tar -czvf $(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64.tar.gz *
- displayName: Compress pwshAlpineFxdBuildAmd64
-
- - ${{ if eq(variables.build,'rpm') }} :
- - pwsh: |
- Set-Location '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64'
- tar -czvf $(System.ArtifactsDirectory)/pwshMarinerBuildArm64.tar.gz *
- displayName: Compress pwshMarinerBuildArm64
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz'
- artifactName: pwshLinuxBuild.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta'
- artifactName: pwshLinuxBuild-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize.tar.gz'
- artifactName: pwshLinuxBuildMinSize.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize-meta'
- artifactName: pwshLinuxBuildMinSize-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32.tar.gz'
- artifactName: pwshLinuxBuildArm32.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32-meta'
- artifactName: pwshLinuxBuildArm32-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64.tar.gz'
- artifactName: pwshLinuxBuildArm64.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'deb') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64-meta'
- artifactName: pwshLinuxBuildArm64-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64.tar.gz'
- artifactName: pwshMarinerBuildAmd64.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64-meta'
- artifactName: pwshMarinerBuildAmd64-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64.tar.gz'
- artifactName: pwshMarinerBuildArm64.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'rpm') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64-meta'
- artifactName: pwshMarinerBuildArm64-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz'
- artifactName: pwshLinuxBuildAlpine.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta'
- artifactName: pwshLinuxBuildAlpine-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64.tar.gz'
- artifactName: pwshAlpineFxdBuildAmd64.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'alpine') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64-meta'
- artifactName: pwshAlpineFxdBuildAmd64-meta
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'fxdependent') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz'
- artifactName: pwshLinuxBuildFxdependent.tar.gz
- retryCountOnTaskFailure: 2
-
- - ${{ if eq(variables.build,'fxdependent') }} :
- - task: PublishPipelineArtifact@1
- inputs:
- path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta'
- artifactName: pwshLinuxBuildFxdependent-meta
- retryCountOnTaskFailure: 2
diff --git a/tools/releaseBuild/azureDevOps/templates/mac-file-signing.yml b/tools/releaseBuild/azureDevOps/templates/mac-file-signing.yml
deleted file mode 100644
index 8159c2bc7d9..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/mac-file-signing.yml
+++ /dev/null
@@ -1,121 +0,0 @@
-parameters:
- buildArchitecture: 'x64'
-
-jobs:
- - job: MacFileSigningJob_${{ parameters.buildArchitecture }}
- displayName: macOS File signing ${{ parameters.buildArchitecture }}
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- variables:
- - group: ESRP
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: repoFolder
- value: PowerShell
- - name: repoRoot
- value: $(Agent.BuildDirectory)\$(repoFolder)
- - name: complianceRepoFolder
- value: compliance
-
- steps:
- - checkout: self
- clean: true
- path: $(repoFolder)
-
- - checkout: ComplianceRepo
- clean: true
- path: $(complianceRepoFolder)
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - template: shouldSign.yml
-
- - task: DownloadBuildArtifacts@0
- inputs:
- artifactName: 'macosBinResults'
- itemPattern: '**/*.zip'
- downloadPath: '$(System.ArtifactsDirectory)\Symbols'
-
- - pwsh: |
- Get-ChildItem "$(System.ArtifactsDirectory)\*" -Recurse
- displayName: 'Capture Downloaded Artifacts'
- # Diagnostics is not critical it passes every time it runs
- continueOnError: true
-
- - pwsh: |
- $zipPath = Get-Item '$(System.ArtifactsDirectory)\Symbols\macosBinResults\*symbol*${{ parameters.buildArchitecture }}*.zip'
- Write-Verbose -Verbose "Zip Path: $zipPath"
-
- $expandedFolder = $zipPath.BaseName
- Write-Host "sending.. vso[task.setvariable variable=SymbolsFolder]$expandedFolder"
- Write-Host "##vso[task.setvariable variable=SymbolsFolder]$expandedFolder"
-
- Expand-Archive -Path $zipPath -Destination "$(System.ArtifactsDirectory)\$expandedFolder" -Force
- displayName: Expand symbols zip
-
- - pwsh: |
- Get-ChildItem "$(System.ArtifactsDirectory)\*" -Recurse
- displayName: 'Capture artifacts dir Binaries'
-
- - pwsh: |
- Get-ChildItem "$(System.ArtifactsDirectory)\$(SymbolsFolder)" -Recurse -Include pwsh, *.dylib
- displayName: 'Capture Expanded Binaries'
- # Diagnostics is not critical it passes every time it runs
- continueOnError: true
-
- - pwsh: |
- $null = new-item -type directory -path "$(Build.StagingDirectory)\macos"
- $zipFile = "$(Build.StagingDirectory)\macos\powershell-files-$(Version)-osx-${{ parameters.buildArchitecture }}.zip"
- Get-ChildItem "$(System.ArtifactsDirectory)\$(SymbolsFolder)" -Recurse -Include pwsh, *.dylib |
- Compress-Archive -Destination $zipFile
- Write-Host $zipFile
- displayName: 'Compress macOS binary files'
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(Build.StagingDirectory)\macos
- signOutputPath: $(Build.StagingDirectory)\signedMacOSPackages
- certificateId: "CP-401337-Apple"
- pattern: |
- **\*.zip
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign macOS Binaries
-
- - pwsh: |
- $destination = "$(System.ArtifactsDirectory)\azureMacOs_${{ parameters.buildArchitecture }}"
- New-Item -Path $destination -Type Directory
- $zipPath = Get-ChildItem "$(Build.StagingDirectory)\signedMacOSPackages\powershell-*.zip" -Recurse | select-object -expandproperty fullname
- foreach ($z in $zipPath) { Expand-Archive -Path $z -DestinationPath $destination }
- displayName: 'Extract and copy macOS artifacts for upload'
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\azureMacOs_${{ parameters.buildArchitecture }}
- artifactFilter: "*"
- artifactName: signedMacOsBins_${{ parameters.buildArchitecture }}
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - ${{ if eq(variables['SHOULD_SIGN'], 'true') }}:
- - template: EsrpScan.yml@ComplianceRepo
- parameters:
- scanPath: $(System.ArtifactsDirectory)\azureMacOs_${{ parameters.buildArchitecture }}
- pattern: |
- **\*
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(repoRoot)\tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/mac-package-build.yml b/tools/releaseBuild/azureDevOps/templates/mac-package-build.yml
deleted file mode 100644
index c853a21ef37..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/mac-package-build.yml
+++ /dev/null
@@ -1,143 +0,0 @@
-parameters:
- parentJob: ''
- buildArchitecture: x64
-
-jobs:
-- job: package_macOS_${{ parameters.buildArchitecture }}
- displayName: Package macOS ${{ parameters.buildArchitecture }}
- condition: succeeded()
- pool:
- vmImage: macos-latest
- variables:
- # Turn off Homebrew analytics
- - name: HOMEBREW_NO_ANALYTICS
- value: 1
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: DotNetPrivateBuildAccess
- steps:
- - checkout: self
- clean: true
-
- - pwsh: |
- # create folder
- sudo mkdir "$(Agent.TempDirectory)/PowerShell"
-
- # make the current user the owner
- sudo chown $env:USER "$(Agent.TempDirectory)/PowerShell"
- displayName: 'Create $(Agent.TempDirectory)/PowerShell'
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - template: shouldSign.yml
-
- - template: cloneToOfficialPath.yml
- parameters:
- nativePathRoot: '$(Agent.TempDirectory)'
-
- - task: DownloadBuildArtifacts@0
- displayName: Download macosBinResults
- inputs:
- artifactName: 'macosBinResults'
- itemPattern: '**/*${{ parameters.buildArchitecture }}.zip'
- downloadPath: '$(System.ArtifactsDirectory)/Symbols'
-
- - task: DownloadBuildArtifacts@0
- displayName: Download signedMacOsBins
- inputs:
- artifactName: 'signedMacOsBins_${{ parameters.buildArchitecture }}'
- itemPattern: '**/*'
- downloadPath: '$(System.ArtifactsDirectory)/macOsBins'
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - pwsh: |
- Get-ChildItem "$(System.ArtifactsDirectory)\*" -Recurse
- displayName: 'Capture Downloaded Artifacts'
- # Diagnostics is not critical it passes every time it runs
- continueOnError: true
-
- - pwsh: |
- $zipPath = Get-Item '$(System.ArtifactsDirectory)\Symbols\macosBinResults\*symbol*${{ parameters.buildArchitecture }}.zip'
- Write-Verbose -Verbose "Zip Path: $zipPath"
-
- $expandedFolder = $zipPath.BaseName
- Write-Host "sending.. vso[task.setvariable variable=SymbolsFolder]$expandedFolder"
- Write-Host "##vso[task.setvariable variable=SymbolsFolder]$expandedFolder"
-
- Expand-Archive -Path $zipPath -Destination "$(System.ArtifactsDirectory)\$expandedFolder" -Force
- displayName: Expand symbols zip
-
- - pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
- $signedFilesPath = '$(System.ArtifactsDirectory)/macOsBins/signedMacOsBins_${{ parameters.buildArchitecture }}/'
- $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)'
-
- Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath
- displayName: Merge signed files with Build
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)/$(SymbolsFolder)'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- PackageName: PowerShell macOS ${{ parameters.buildArchitecture }}
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)/tools'
-
- - pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
-
- $destFolder = '$(System.ArtifactsDirectory)\signedZip'
- $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)'
-
- $null = New-Item -ItemType Directory -Path $destFolder -Force
-
- $BuildPackagePath = New-PSBuildZip -BuildPath $BuildPath -DestinationFolder $destFolder
-
- Write-Verbose -Verbose "New-PSSignedBuildZip returned `$BuildPackagePath as: $BuildPackagePath"
- Write-Host "##vso[artifact.upload containerfolder=results;artifactname=results]$BuildPackagePath"
-
- $vstsCommandString = "vso[task.setvariable variable=BuildPackagePath]$BuildPackagePath"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- displayName: Compress signed files
- retryCountOnTaskFailure: 2
-
-
- - pwsh: |
- try {
- tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -location $(PowerShellRoot) -BootStrap
- } catch {
- Get-Error
- throw
- }
- displayName: 'Bootstrap VM'
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- # Add -SkipReleaseChecks as a mitigation to unblock release.
- # macos-10.15 does not allow creating a folder under root. Hence, moving the folder.
- try {
- $(Build.SourcesDirectory)/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -ReleaseTag $(ReleaseTagVar) -Destination $(System.ArtifactsDirectory) -location $(PowerShellRoot) -ArtifactName macosPkgResults -BuildZip $(BuildPackagePath) -ExtraPackage "tar" -Runtime 'osx-${{ parameters.buildArchitecture }}' -SkipReleaseChecks
- } catch {
- Get-Error
- throw
- }
- displayName: 'Package'
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(PowerShellRoot)/tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/mac-package-signing.yml b/tools/releaseBuild/azureDevOps/templates/mac-package-signing.yml
deleted file mode 100644
index d4901580b0b..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/mac-package-signing.yml
+++ /dev/null
@@ -1,135 +0,0 @@
-parameters:
- buildArchitecture: x64
-
-jobs:
-- job: MacPackageSigningJob_${{ parameters.buildArchitecture }}
- displayName: macOS Package signing ${{ parameters.buildArchitecture }}
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- variables:
- - group: ESRP
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: repoFolder
- value: PowerShell
- - name: repoRoot
- value: $(Agent.BuildDirectory)\$(repoFolder)
- - name: complianceRepoFolder
- value: compliance
-
- steps:
- - checkout: self
- clean: true
- path: $(repoFolder)
-
- - checkout: ComplianceRepo
- clean: true
- path: $(complianceRepoFolder)
-
- - template: shouldSign.yml
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - task: DownloadBuildArtifacts@0
- inputs:
- artifactName: 'macosPkgResults'
- itemPattern: '**/*'
- downloadPath: '$(System.ArtifactsDirectory)'
-
- - pwsh: |
- dir "$(System.ArtifactsDirectory)\*" -Recurse
- displayName: 'Capture Downloaded Artifacts'
- # Diagnostics is not critical it passes every time it runs
- continueOnError: true
-
- - pwsh: |
- $null = new-item -type directory -path "$(Build.StagingDirectory)\macos"
- $zipFile = "$(Build.StagingDirectory)\macos\powershell-$(Version)-osx-${{ parameters.buildArchitecture }}.zip"
- Compress-Archive -Path "$(System.ArtifactsDirectory)\macosPkgResults\powershell-$(Version)-osx-${{ parameters.buildArchitecture }}.pkg" -Destination $zipFile
- Write-Host $zipFile
-
- $ltsPkgPath = "$(System.ArtifactsDirectory)\macosPkgResults\powershell-lts-$(Version)-osx-${{ parameters.buildArchitecture }}.pkg"
-
- if(Test-Path $ltsPkgPath)
- {
- $ltsZipFile = "$(Build.StagingDirectory)\macos\powershell-lts-$(Version)-osx-${{ parameters.buildArchitecture }}.zip"
- Compress-Archive -Path $ltsPkgPath -Destination $ltsZipFile
- Write-Host $ltsZipFile
- }
- displayName: 'Compress macOS Package'
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(Build.StagingDirectory)\macos
- signOutputPath: $(Build.StagingDirectory)\signedMacOSPackages
- certificateId: "CP-401337-Apple"
- pattern: |
- **\*.zip
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign pkg
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\macosPkgResults
- artifactFilter: "*${{ parameters.buildArchitecture }}.tar.gz"
-
- - pwsh: |
- $destination = "$(System.ArtifactsDirectory)\azureMacOs"
- New-Item -Path $destination -Type Directory
- $zipPath = dir "$(Build.StagingDirectory)\signedMacOSPackages\powershell-*.zip" -Recurse | select-object -expandproperty fullname
- foreach ($z in $zipPath) { Expand-Archive -Path $z -DestinationPath $destination }
- $targzPath = dir "$(System.ArtifactsDirectory)\*osx*.tar.gz" -Recurse | select-object -expandproperty fullname
- Copy-Item -Path $targzPath -Destination $destination
- displayName: 'Extract and copy macOS artifacts for upload'
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\azureMacOs
- artifactFilter: "*.pkg"
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - pwsh: |
- $null = new-item -type directory -path "$(Build.StagingDirectory)\macos-unsigned"
- Copy-Item -Path "$(System.ArtifactsDirectory)\macosPkgResults\powershell-$(Version)-osx-x64.pkg" -Destination "$(Build.StagingDirectory)\macos-unsigned"
- Copy-Item -Path "$(System.ArtifactsDirectory)\macosPkgResults\powershell-$(Version)-osx-x64.tar.gz" -Destination "$(Build.StagingDirectory)\macos-unsigned"
- displayName: 'Create unsigned folder to upload'
- condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true'))
-
- - task: AzureFileCopy@4
- displayName: 'AzureBlob File Copy - unsigned'
- inputs:
- SourcePath: '$(Build.StagingDirectory)\macos-unsigned\*'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)'
- condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true'))
- retryCountOnTaskFailure: 2
-
- - task: AzureFileCopy@4
- displayName: 'AzureBlob File Copy - signed'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\azureMacOs\*'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)'
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
- retryCountOnTaskFailure: 2
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(repoRoot)/tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/mac.yml b/tools/releaseBuild/azureDevOps/templates/mac.yml
deleted file mode 100644
index d173e900434..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/mac.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-parameters:
- buildArchitecture: 'x64'
-
-jobs:
-- job: build_macOS_${{ parameters.buildArchitecture }}
- displayName: Build macOS ${{ parameters.buildArchitecture }}
- condition: succeeded()
- pool:
- vmImage: macos-latest
- variables:
- # Turn off Homebrew analytics
- - name: HOMEBREW_NO_ANALYTICS
- value: 1
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: DotNetPrivateBuildAccess
- steps:
- #- task: @
- # inputs:
- #
- # displayName: ''
- - checkout: self
- clean: true
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - pwsh: |
- # create folder
- sudo mkdir "$(Agent.TempDirectory)/PowerShell"
-
- # make the current user the owner
- sudo chown $env:USER "$(Agent.TempDirectory)/PowerShell"
- displayName: 'Create $(Agent.TempDirectory)/PowerShell'
-
- - template: cloneToOfficialPath.yml
- parameters:
- nativePathRoot: '$(Agent.TempDirectory)'
-
- - pwsh: |
- tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -location $(PowerShellRoot) -BootStrap
- displayName: 'Bootstrap VM'
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(PowerShellRoot)
-
- - pwsh: |
- $env:AzDevOpsFeedPAT2 = '$(powershellPackageReadPat)'
- # Add -SkipReleaseChecks as a mitigation to unblock release.
- # macos-10.15 does not allow creating a folder under root. Hence, moving the folder.
- $(Build.SourcesDirectory)/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -ReleaseTag $(ReleaseTagVar) -Destination $(System.ArtifactsDirectory) -Symbols -location $(PowerShellRoot) -Build -ArtifactName macosBinResults -Runtime 'osx-${{ parameters.buildArchitecture }}' -SkipReleaseChecks
- $env:AzDevOpsFeedPAT2 = $null
- displayName: 'Build'
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(Build.SourcesDirectory)/tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml b/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml
deleted file mode 100644
index 0a0e3b96cc1..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml
+++ /dev/null
@@ -1,139 +0,0 @@
-parameters:
- - name: PackageVersion
- - name: PackagePath
- - name: WinFxdPath
- - name: LinuxFxdPath
- - name: ListOfFiles
- type: object
- default:
- - Microsoft.Management.Infrastructure.CimCmdlets.dll
- - Microsoft.PowerShell.Commands.Diagnostics.dll
- - Microsoft.PowerShell.Commands.Management.dll
- - Microsoft.PowerShell.Commands.Utility.dll
- - Microsoft.PowerShell.ConsoleHost.dll
- - Microsoft.PowerShell.CoreCLR.Eventing.dll
- - Microsoft.PowerShell.Security.dll
- - Microsoft.PowerShell.SDK.dll
- - Microsoft.WSMan.Management.dll
- - Microsoft.WSMan.Runtime.dll
- - System.Management.Automation.dll
-
-steps:
-
-- template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self
- parameters:
- repoRoot: $(REPOROOT)
-
-- pwsh: |
- Import-Module "$env:REPOROOT/build.psm1" -Force
- Start-PSBootstrap
-
- $sharedModules = @('Microsoft.PowerShell.Commands.Management',
- 'Microsoft.PowerShell.Commands.Utility',
- 'Microsoft.PowerShell.ConsoleHost',
- 'Microsoft.PowerShell.Security',
- 'System.Management.Automation'
- )
-
- $winOnlyModules = @('Microsoft.Management.Infrastructure.CimCmdlets',
- 'Microsoft.PowerShell.Commands.Diagnostics',
- 'Microsoft.PowerShell.CoreCLR.Eventing',
- 'Microsoft.WSMan.Management',
- 'Microsoft.WSMan.Runtime'
- )
-
- $refAssemblyFolder = Join-Path '$(System.ArtifactsDirectory)' 'RefAssembly'
- $null = New-Item -Path $refAssemblyFolder -Force -Verbose -Type Directory
-
- Start-PSBuild -Clean -Runtime linux-x64 -Configuration Release
-
- $sharedModules | Foreach-Object {
- $refFile = Get-ChildItem -Path "$env:REPOROOT\src\$_\obj\Release\net9.0\refint\$_.dll"
- Write-Verbose -Verbose "RefAssembly: $refFile"
- Copy-Item -Path $refFile -Destination "$refAssemblyFolder\$_.dll" -Verbose
- $refDoc = "$env:REPOROOT\src\$_\bin\Release\net9.0\$_.xml"
- if (-not (Test-Path $refDoc)) {
- Write-Warning "$refDoc not found"
- Get-ChildItem -Path "$env:REPOROOT\src\$_\bin\Release\net9.0\" | Out-String | Write-Verbose -Verbose
- }
- else {
- Copy-Item -Path $refDoc -Destination "$refAssemblyFolder\$_.xml" -Verbose
- }
- }
-
- Start-PSBuild -Clean -Runtime win7-x64 -Configuration Release
-
- $winOnlyModules | Foreach-Object {
- $refFile = Get-ChildItem -Path "$env:REPOROOT\src\$_\obj\Release\net9.0\refint\*.dll"
- Write-Verbose -Verbose 'RefAssembly: $refFile'
- Copy-Item -Path $refFile -Destination "$refAssemblyFolder\$_.dll" -Verbose
- $refDoc = "$env:REPOROOT\src\$_\bin\Release\net9.0\$_.xml"
- if (-not (Test-Path $refDoc)) {
- Write-Warning "$refDoc not found"
- Get-ChildItem -Path "$env:REPOROOT\src\$_\bin\Release\net9.0" | Out-String | Write-Verbose -Verbose
- }
- else {
- Copy-Item -Path $refDoc -Destination "$refAssemblyFolder\$_.xml" -Verbose
- }
- }
-
- Get-ChildItem $refAssemblyFolder -Recurse | Out-String | Write-Verbose -Verbose
-
- # Set RefAssemblyPath path variable
- $vstsCommandString = "vso[task.setvariable variable=RefAssemblyPath]${refAssemblyFolder}"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
-
- displayName: Build reference assemblies
- env:
- __DOTNET_RUNTIME_FEED: $(RUNTIME_SOURCEFEED)
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
-- ${{ each value in parameters.ListOfFiles }}:
- - pwsh: |
- $FileName = '${{ value }}'
- $FileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName)
- $FilePackagePath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath $FileBaseName
- $CGManifestPath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath 'CGManifest'
- Write-Verbose -Verbose "FileName to package: $FileName"
- Write-Verbose -Verbose "FilePackage path: $FilePackagePath"
- Write-Verbose -Verbose "CGManifest path: $CGManifestPath"
- # Set SBOM package name
- $vstsCommandString = "vso[task.setvariable variable=SbomFilePackageName]${FileBaseName}"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- # Set SBOM package path variable
- $vstsCommandString = "vso[task.setvariable variable=SbomFilePackagePath]${FilePackagePath}"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- # Set CGManifest path variable
- $vstsCommandString = "vso[task.setvariable variable=CGManifestPath]${CGManifestPath}"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- # Create Nuget package sources
- Import-Module -Name $env:REPOROOT\build.psm1
- Import-Module -Name $env:REPOROOT\tools\packaging
- Find-DotNet
- New-ILNugetPackageSource -File $FileName -PackagePath '${{ parameters.PackagePath }}' -PackageVersion '${{ parameters.PackageVersion }}' -WinFxdBinPath '${{ parameters.WinFxdPath }}' -LinuxFxdBinPath '${{ parameters.LinuxFxdPath }}' -CGManifestPath $CGManifestPath -RefAssemblyPath $(RefAssemblyPath)
- displayName: 'Create NuGet Package source for single file'
-
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: $(SbomFilePackagePath)
- Build_Repository_Uri: 'https://github.com/powershell/powershell'
- PackageName: $(SbomFilePackageName)
- PackageVersion: ${{ parameters.PackageVersion }}
- sourceScanPath: $(CGManifestPath)
- displayName: SBOM for NuGetPkg
-
- - pwsh: |
- $FileName = '${{ value }}'
- $FileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName)
- $FilePackagePath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath $FileBaseName
- Write-Verbose -Verbose "FileName to package: $FileName"
- Write-Verbose -Verbose "FilePackage path: $FilePackagePath"
- Import-Module -Name $env:REPOROOT\build.psm1
- Import-Module -Name $env:REPOROOT\tools\packaging
- Find-DotNet
- New-ILNugetPackageFromSource -FileName $FileName -PackageVersion '${{ parameters.PackageVersion }}' -PackagePath '${{ parameters.PackagePath }}'
- displayName: 'Create NuGet Package for single file'
diff --git a/tools/releaseBuild/azureDevOps/templates/nuget.yml b/tools/releaseBuild/azureDevOps/templates/nuget.yml
deleted file mode 100644
index 22f791bf0eb..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/nuget.yml
+++ /dev/null
@@ -1,290 +0,0 @@
-parameters:
- parentJobs: []
-
-jobs:
-- job: build_nuget
- dependsOn:
- ${{ parameters.parentJobs }}
- displayName: Build NuGet packages
- condition: succeeded()
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- timeoutInMinutes: 90
-
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: build
- value: ${{ parameters.buildName }}
- - group: ESRP
- - name: GenAPIToolPath
- value: '$(System.ArtifactsDirectory)/GenAPI'
- - name: PackagePath
- value: '$(System.ArtifactsDirectory)/UnifiedPackagePath'
- - name: winFxdPath
- value: '$(System.ArtifactsDirectory)/winFxd'
- - name: winFxdWinDesktopPath
- value: '$(System.ArtifactsDirectory)/winFxdWinDesktop'
- - name: linuxFxdPath
- value: '$(System.ArtifactsDirectory)/linuxFxd'
- - name: alpineFxdPath
- value: '$(System.ArtifactsDirectory)/alpineFxd'
- - group: DotNetPrivateBuildAccess
-
- steps:
- - checkout: self
- clean: true
-
- - checkout: ComplianceRepo
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - powershell: |
- $content = Get-Content "$env:REPOROOT/global.json" -Raw | ConvertFrom-Json
- $vstsCommandString = "vso[task.setvariable variable=SDKVersion]$($content.sdk.version)"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- displayName: 'Find SDK version from global.json'
-
- - pwsh: |
- Import-Module "$env:REPOROOT/build.psm1" -Force
- # We just need .NET but we fixed this in an urgent situation.
- Start-PSBootStrap -Verbose
- displayName: Bootstrap
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download PowerShell build artifacts - finalResults'
- inputs:
- buildType: current
- downloadType: single
- artifactName: finalResults
- downloadPath: '$(System.ArtifactsDirectory)'
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download PowerShell build artifacts - macosPkgResults'
- inputs:
- buildType: current
- downloadType: single
- artifactName: macosPkgResults
- downloadPath: '$(System.ArtifactsDirectory)'
-
- - powershell: 'Get-ChildItem $(System.ArtifactsDirectory) -recurse'
- displayName: 'Capture downloaded artifacts'
-
- - powershell: |
- $packagePath = (Join-Path $(System.ArtifactsDirectory) packages)
- New-Item $packagePath -ItemType Directory -Force > $null
- $packages = Get-ChildItem $(System.ArtifactsDirectory) -Include *.zip, *.tar.gz -Recurse
- $packages | ForEach-Object { Copy-Item $_.FullName -Destination $packagePath -Verbose }
- Get-ChildItem $packagePath -Recurse
- displayName: 'Conflate packages to same folder'
-
- - task: ExtractFiles@1
- displayName: 'Extract files win-fxdependent'
- inputs:
- archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/PowerShell-*-win-fxdependent.zip'
- destinationFolder: '$(winFxdPath)'
-
- - task: ExtractFiles@1
- displayName: 'Extract files win-fxdependentWinDesktop'
- inputs:
- archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/PowerShell-*-win-fxdependentWinDesktop.zip'
- destinationFolder: '$(winFxdWinDesktopPath)'
-
- - task: ExtractFiles@1
- displayName: 'Extract files linux-fxdependent'
- inputs:
- archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/powershell-*-linux-x64-fxdependent.tar.gz'
- destinationFolder: '$(linuxFxdPath)'
-
- - task: ExtractFiles@1
- displayName: 'Extract files alpine-fxdependent'
- inputs:
- archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/powershell-*-linux-x64-musl-noopt-fxdependent.tar.gz'
- destinationFolder: '$(alpineFxdPath)'
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - template: shouldSign.yml
-
- - task: NuGetToolInstaller@1
- displayName: 'Install NuGet.exe'
-
- # Create nuget packages along with SBOM manifests.
- - template: nuget-pkg-sbom.yml
- parameters:
- PackageVersion: $(Version)
- PackagePath: $(PackagePath)
- WinFxdPath: $(winFxdPath)
- LinuxFxdPath: $(linuxFxdPath)
-
- - pwsh: |
- Get-ChildItem $(linuxFxdPath)
- Get-ChildItem $(winFxdPath)
- Get-ChildItem $(winFxdWinDesktopPath)
- Get-ChildItem $(alpineFxdPath)
- displayName: Capture fxd folders
-
- # Create Global Tool packages along with SBOM manifests
- - template: global-tool-pkg-sbom.yml
- parameters:
- PackageVersion: $(Version)
- LinuxBinPath: $(linuxFxdPath)
- WindowsBinPath: $(winFxdPath)
- WindowsDesktopBinPath: $(winFxdWinDesktopPath)
- AlpineBinPath: $(alpineFxdPath)
- DestinationPath: $(PackagePath)\globaltool
-
- - pwsh: |
- Get-ChildItem "$(PackagePath)" -Recurse
- displayName: Capture generated packages
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(PackagePath)
- signOutputPath: $(System.ArtifactsDirectory)\signed
- certificateId: "CP-401405"
- pattern: |
- **\*.nupkg
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign NuPkg
-
- - pwsh: |
- if (-not (Test-Path '$(System.ArtifactsDirectory)\signed\')) { $null = New-Item -ItemType Directory -Path '$(System.ArtifactsDirectory)\signed\' }
- Copy-Item -Path '$(PackagePath)\*.nupkg' -Destination '$(System.ArtifactsDirectory)\signed\' -Verbose -Force
- Copy-Item -Path '$(PackagePath)\globaltool\*.nupkg' -Destination '$(System.ArtifactsDirectory)\signed\' -Verbose -Force
- displayName: Fake copy when not signing
- condition: eq(variables['SHOULD_SIGN'], 'false')
-
- - pwsh: |
- Import-Module "${env:REPOROOT}\build.psm1" -Force
- Get-ChildItem -Recurse "$(System.ArtifactsDirectory)\signed\*.nupkg" -Verbose | ForEach-Object { Start-NativeExecution -sb { nuget.exe verify -All $_.FullName } }
- displayName: Verify all packages are signed
- condition: eq(variables['SHOULD_SIGN'], 'true')
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-antimalware.AntiMalware@3
- displayName: 'Run MpCmdRun.exe'
- inputs:
- FileDirPath: '$(PackagePath)'
- TreatStaleSignatureAs: Warning
-
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
- displayName: 'Publish Security Analysis Logs'
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: '$(System.ArtifactsDirectory)\signed'
-
- - pwsh: |
- if (-not (Test-Path "$(System.ArtifactsDirectory)\signed\globaltool"))
- {
- $null = New-Item -Path "$(System.ArtifactsDirectory)\signed\globaltool" -ItemType Directory -Force
- }
-
- Move-Item -Path "$(System.ArtifactsDirectory)\signed\PowerShell.*" -Destination "$(System.ArtifactsDirectory)\signed\globaltool" -Force
- Get-ChildItem "$(System.ArtifactsDirectory)\signed\globaltool" -Recurse
- displayName: Move global tool packages to subfolder and capture
-
- - pwsh: |
- $packagePath = (Join-Path $(System.ArtifactsDirectory) checksum)
- New-Item $packagePath -ItemType Directory -Force > $null
- $srcPaths = @("$(System.ArtifactsDirectory)\finalResults", "$(System.ArtifactsDirectory)\macosPkgResults", "$(System.ArtifactsDirectory)\signed")
-
- $packages = Get-ChildItem -Path $srcPaths -Include *.zip, *.tar.gz, *.msi*, *.pkg, *.deb, *.rpm -Exclude "PowerShell-Symbols*" -Recurse
- $packages | ForEach-Object { Copy-Item $_.FullName -Destination $packagePath -Verbose }
-
- $packagePathList = Get-ChildItem $packagePath -Recurse | Select-Object -ExpandProperty FullName | Out-String
- Write-Verbose -Verbose $packagePathList
-
- $checksums = Get-ChildItem -Path $packagePath -Exclude "SHA512SUMS" |
- ForEach-Object {
- Write-Verbose -Verbose "Generating checksum file for $($_.FullName)"
- $packageName = $_.Name
- $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA512).Hash.ToLower()
-
- # the '*' before the packagename signifies it is a binary
- "$hash *$packageName"
- }
-
- $checksums | Out-File -FilePath "$packagePath\SHA512SUMS" -Force
-
-
- $fileContent = Get-Content -Path "$packagePath\SHA512SUMS" -Raw | Out-String
- Write-Verbose -Verbose -Message $fileContent
-
- Copy-Item -Path "$packagePath\SHA512SUMS" -Destination '$(System.ArtifactsDirectory)\signed\' -verbose
- displayName: Generate checksum file for packages
-
- - pwsh: |
- $packagePath = (Join-Path $(System.ArtifactsDirectory) checksum_gbltool)
- New-Item $packagePath -ItemType Directory -Force > $null
- $srcPaths = @("$(System.ArtifactsDirectory)\signed\globaltool")
- $packages = Get-ChildItem -Path $srcPaths -Include *.nupkg -Recurse
- $packages | ForEach-Object { Copy-Item $_.FullName -Destination $packagePath -Verbose }
-
- $packagePathList = Get-ChildItem $packagePath -Recurse | Select-Object -ExpandProperty FullName | Out-String
- Write-Verbose -Verbose $packagePathList
-
- $checksums = Get-ChildItem -Path $packagePath -Exclude "SHA512SUMS" |
- ForEach-Object {
- Write-Verbose -Verbose "Generating checksum file for $($_.FullName)"
- $packageName = $_.Name
- $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA512).Hash.ToLower()
-
- # the '*' before the packagename signifies it is a binary
- "$hash *$packageName"
- }
-
- $checksums | Out-File -FilePath "$packagePath\SHA512SUMS" -Force
-
- $fileContent = Get-Content -Path "$packagePath\SHA512SUMS" -Raw | Out-String
- Write-Verbose -Verbose -Message $fileContent
-
- Copy-Item -Path "$packagePath\SHA512SUMS" -Destination '$(System.ArtifactsDirectory)\signed\globaltool\' -verbose
- displayName: Generate checksum for global tools
-
- - template: upload-final-results.yml
- parameters:
- artifactPath: '$(System.ArtifactsDirectory)\checksum'
- artifactFilter: SHA512SUMS
-
- - task: AzureFileCopy@4
- displayName: 'Upload NuGet packages to Azure'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\signed\*'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)-nuget'
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
- retryCountOnTaskFailure: 2
-
- - task: AzureFileCopy@4
- displayName: 'Upload global tool packages to Azure'
- inputs:
- sourcePath: '$(System.ArtifactsDirectory)\signed\globaltool\*'
- azureSubscription: '$(GlobalToolSubscription)'
- Destination: AzureBlob
- storage: '$(GlobalToolStorageAccount)'
- ContainerName: 'tool-private'
- blobPrefix: '$(Version)'
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
- retryCountOnTaskFailure: 2
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(PackagePath)'
diff --git a/tools/releaseBuild/azureDevOps/templates/release-BuildJson.yml b/tools/releaseBuild/azureDevOps/templates/release-BuildJson.yml
deleted file mode 100644
index d183601a06c..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-BuildJson.yml
+++ /dev/null
@@ -1,102 +0,0 @@
-steps:
-- checkout: self
- clean: true
-
-- task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: BuildInfoJson
- path: '$(Pipeline.Workspace)/releasePipeline/BuildInfoJson'
-
-- pwsh: |
- Import-Module '$(Build.SourcesDirectory)/tools/ci.psm1'
- $jsonFile = Get-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/BuildInfoJson/*.json"
- $fileName = Split-Path $jsonFile -Leaf
-
- $dateTime = [datetime]::UtcNow
- $dateTime = [datetime]::new($dateTime.Ticks - ($dateTime.Ticks % [timespan]::TicksPerSecond), $dateTime.Kind)
-
- $metadata = Get-Content ./tools/metadata.json | ConvertFrom-Json
- $stableRelease = $metadata.StableRelease.Latest
- $ltsRelease = $metadata.LTSRelease.Latest
-
- Write-Verbose -Verbose "Writing $jsonFile contents:"
- $buildInfoJsonContent = Get-Content $jsonFile -Encoding UTF8NoBom -Raw
- Write-Verbose -Verbose $buildInfoJsonContent
-
- $buildInfo = $buildInfoJsonContent | ConvertFrom-Json
- $buildInfo.ReleaseDate = $dateTime
-
- $targetFile = "$ENV:PIPELINE_WORKSPACE/$fileName"
- ConvertTo-Json -InputObject $buildInfo | Out-File $targetFile -Encoding ascii
-
- if ($stableRelease -or $fileName -eq "preview.json") {
- Set-BuildVariable -Name CopyMainBuildInfo -Value YES
- } else {
- Set-BuildVariable -Name CopyMainBuildInfo -Value NO
- }
-
- Set-BuildVariable -Name BuildInfoJsonFile -Value $targetFile
-
- ## Create 'lts.json' if it's the latest stable and also a LTS release.
-
- if ($fileName -eq "stable.json") {
- if ($ltsRelease) {
- $ltsFile = "$ENV:PIPELINE_WORKSPACE/lts.json"
- Copy-Item -Path $targetFile -Destination $ltsFile -Force
- Set-BuildVariable -Name LtsBuildInfoJsonFile -Value $ltsFile
- Set-BuildVariable -Name CopyLTSBuildInfo -Value YES
- } else {
- Set-BuildVariable -Name CopyLTSBuildInfo -Value NO
- }
-
- $releaseTag = $buildInfo.ReleaseTag
- $version = $releaseTag -replace '^v'
- $semVersion = [System.Management.Automation.SemanticVersion] $version
-
- $versionFile = "$ENV:PIPELINE_WORKSPACE/$($semVersion.Major)-$($semVersion.Minor).json"
- Copy-Item -Path $targetFile -Destination $versionFile -Force
- Set-BuildVariable -Name VersionBuildInfoJsonFile -Value $versionFile
- Set-BuildVariable -Name CopyVersionBuildInfo -Value YES
- } else {
- Set-BuildVariable -Name CopyVersionBuildInfo -Value NO
- }
- displayName: Download and Capture NuPkgs
-
-- task: AzureFileCopy@4
- displayName: 'AzureBlob build info JSON file Copy'
- inputs:
- SourcePath: '$(BuildInfoJsonFile)'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: BuildInfo
- condition: and(succeeded(), eq(variables['CopyMainBuildInfo'], 'YES'))
- retryCountOnTaskFailure: 2
-
-- task: AzureFileCopy@4
- displayName: 'AzureBlob build info ''lts.json'' Copy when needed'
- inputs:
- SourcePath: '$(LtsBuildInfoJsonFile)'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: BuildInfo
- condition: and(succeeded(), eq(variables['CopyLTSBuildInfo'], 'YES'))
- retryCountOnTaskFailure: 2
-
-- task: AzureFileCopy@4
- displayName: 'AzureBlob build info ''Major-Minor.json'' Copy when needed'
- inputs:
- SourcePath: '$(VersionBuildInfoJsonFile)'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: BuildInfo
- condition: and(succeeded(), eq(variables['CopyVersionBuildInfo'], 'YES'))
- retryCountOnTaskFailure: 2
diff --git a/tools/releaseBuild/azureDevOps/templates/release-CopyGlobalTools.yml b/tools/releaseBuild/azureDevOps/templates/release-CopyGlobalTools.yml
deleted file mode 100644
index 7c9306496ed..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-CopyGlobalTools.yml
+++ /dev/null
@@ -1,56 +0,0 @@
-parameters:
-- name: sourceContainerName
- type: string
- default: 'source-container'
-
-- name: destinationContainerName
- type: string
- default: 'destination-container'
-
-- name: sourceStorageAccountName
- type: string
- default: 'source-storage-account'
-
-- name: destinationStorageAccountName
- type: string
- default: 'destination-storage-account'
-
-- name: blobPrefix
- type: string
- default: '$(Version)'
-
-steps:
-- template: release-SetReleaseTagAndContainerName.yml
-
-- pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1'
- Install-AzCopy
- displayName: Install AzCopy
- retryCountOnTaskFailure: 2
-
-- pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1'
- $azcopy = Find-AzCopy
- Write-Verbose -Verbose "Found AzCopy: $azcopy"
-
- $sourceContainerName = "${{ parameters.sourceContainerName }}"
- $destinationContainerName = "${{ parameters.destinationContainerName }}"
- $sourceStorageAccountName = "${{ parameters.sourceStorageAccountName }}"
- $destinationStorageAccountName = "${{ parameters.destinationStorageAccountName }}"
- $blobPrefix = "${{ parameters.blobPrefix }}"
-
- $sourceBlobUrl = "https://${sourceStorageAccountName}.blob.core.windows.net/${sourceContainerName}/${blobPrefix}"
- Write-Verbose -Verbose "Source blob url: $sourceBlobUrl"
- $destinationBlobUrl = "https://${destinationStorageAccountName}.blob.core.windows.net/${destinationContainerName}"
- Write-Verbose -Verbose "Destination blob url: $destinationBlobUrl"
-
- & $azcopy cp $sourceBlobUrl $destinationBlobUrl --recursive
-
- $packagesPath = Get-ChildItem -Path $(System.ArtifactsDirectory)\*.deb -Recurse -File | Select-Object -First 1 -ExpandProperty DirectoryName
- Write-Host "sending -- vso[task.setvariable variable=PackagesRoot]$packagesPath"
- Write-Host "##vso[task.setvariable variable=PackagesRoot]$packagesPath"
-
- displayName: Copy blobs
- retryCountOnTaskFailure: 2
- env:
- AZCOPY_AUTO_LOGIN_TYPE: MSI
diff --git a/tools/releaseBuild/azureDevOps/templates/release-CreateGitHubDraft.yml b/tools/releaseBuild/azureDevOps/templates/release-CreateGitHubDraft.yml
deleted file mode 100644
index 64c4d1b6a24..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-CreateGitHubDraft.yml
+++ /dev/null
@@ -1,110 +0,0 @@
-steps:
-- checkout: self
- clean: true
-
-- download: none
-
-- template: release-SetReleaseTagAndContainerName.yml
-
-- pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/PowerShell/build.psm1'
- Install-AzCopy
- displayName: Install AzCopy
- retryCountOnTaskFailure: 2
-
-- pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/PowerShell/build.psm1'
- $azcopy = Find-AzCopy
- Write-Verbose -Verbose "Found AzCopy: $azcopy"
-
- & $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion) $(System.ArtifactsDirectory) --recursive
-
- $packagesPath = Get-ChildItem -Path $(System.ArtifactsDirectory)\*.deb -Recurse -File | Select-Object -First 1 -ExpandProperty DirectoryName
- Write-Host "sending -- vso[task.setvariable variable=PackagesRoot]$packagesPath"
- Write-Host "##vso[task.setvariable variable=PackagesRoot]$packagesPath"
-
- displayName: Download Azure Artifacts
- retryCountOnTaskFailure: 2
- env:
- AZCOPY_AUTO_LOGIN_TYPE: MSI
-
-- pwsh: |
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty FullName
- displayName: Capture downloaded artifacts
-
-- pwsh: |
- git clone https://$(AzureDevOpsPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools '$(Pipeline.Workspace)/tools'
- displayName: Clone Internal-Tools repository
-
-- pwsh: |
- $Path = "$(PackagesRoot)"
- $OutputPath = Join-Path $Path ‘hashes.sha256’
- $srcPaths = @($Path)
- $packages = Get-ChildItem -Path $srcPaths -Include * -Recurse -File
- $checksums = $packages |
- ForEach-Object {
- Write-Verbose -Verbose "Generating checksum file for $($_.FullName)"
- $packageName = $_.Name
- $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower()
- # the '*' before the packagename signifies it is a binary
- "$hash *$packageName"
- }
- $checksums | Out-File -FilePath $OutputPath -Force
- $fileContent = Get-Content -Path $OutputPath -Raw | Out-String
- Write-Verbose -Verbose -Message $fileContent
- displayName: Add sha256 hashes
-
-- checkout: ComplianceRepo
-
-- pwsh: |
- $releaseVersion = '$(ReleaseTag)' -replace '^v',''
- $vstsCommandString = "vso[task.setvariable variable=ReleaseVersion]$releaseVersion"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- displayName: 'Set release version'
-
-- template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(PackagesRoot)'
- Build_Repository_Uri: 'https://github.com/powershell/powershell.git'
- displayName: PowerShell Hashes SBOM
- packageName: PowerShell Artifact Hashes
- packageVersion: $(ReleaseVersion)
- sourceScanPath: '$(PackagesRoot)'
-
-- pwsh: |
- Import-module '$(Pipeline.Workspace)/tools/Scripts/GitHubRelease.psm1'
- $releaseVersion = '$(ReleaseTag)' -replace '^v',''
- $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion
-
- $isPreview = $semanticVersion.PreReleaseLabel -ne $null
-
- $fileName = if ($isPreview) {
- "preview.md"
- }
- else {
- $semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md"
- }
-
- $filePath = "$env:BUILD_SOURCESDIRECTORY/PowerShell/CHANGELOG/$fileName"
- Write-Verbose -Verbose "Selected Log file: $filePath"
-
- if (-not (Test-Path $filePath)) {
- throw "$filePath not found"
- }
-
- $changelog = Get-Content -Path $filePath
-
- $startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]"
- $endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch
-
- $clContent = $changelog | ForEach-Object {
- if ($_ -match $startPattern) { $outputLine = $true }
- elseif ($_ -match $endPattern) { $outputLine = $false }
- if ($outputLine) { $_}
- } | Out-String
-
- Write-Verbose -Verbose "Selected content: `n$clContent"
-
- Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder $(PackagesRoot) -Token $(GitHubReleasePat)
- displayName: Publish Release Draft
diff --git a/tools/releaseBuild/azureDevOps/templates/release-GlobalToolTest.yml b/tools/releaseBuild/azureDevOps/templates/release-GlobalToolTest.yml
deleted file mode 100644
index 8591791de0e..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-GlobalToolTest.yml
+++ /dev/null
@@ -1,149 +0,0 @@
-parameters:
- jobName: ""
- displayName: ""
- imageName: ""
- globalToolExeName: 'pwsh.exe'
- globalToolPackageName: 'PowerShell.Windows.x64'
-
-
-jobs:
-- job: ${{ parameters.jobName }}
- displayName: ${{ parameters.displayName }}
- pool:
- # test
- vmImage: ${{ parameters.imageName }}
- variables:
- - group: DotNetPrivateBuildAccess
-
- steps:
- - checkout: self
- clean: true
-
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: finalResults
- patterns: '**/*.nupkg'
- path: '$(Pipeline.Workspace)/releasePipeline/finalResults'
-
- - pwsh: |
- $dotnetMetadataPath = "$(Build.SourcesDirectory)/DotnetRuntimeMetadata.json"
- $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json
-
- # Channel is like: $Channel = "5.0.1xx-preview2"
- $Channel = $dotnetMetadataJson.sdk.channel
-
- $sdkVersion = (Get-Content "$(Build.SourcesDirectory)/global.json" -Raw | ConvertFrom-Json).sdk.version
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
-
- Find-Dotnet
-
- if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue))
- {
- $nugetFeed = ([xml](Get-Content $(Build.SourcesDirectory)/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value
- if ($nugetFeed) {
- Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet
- Write-Verbose -Message "Register new package source 'dotnet'" -verbose
- }
- }
-
- ## Install latest version from the channel
-
- #Install-Dotnet -Channel "$Channel" -Version $sdkVersion
- Start-PSBootstrap
-
- Write-Verbose -Message "Installing .NET SDK completed." -Verbose
-
- displayName: Install .NET
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- $branch = $ENV:BUILD_SOURCEBRANCH
- $version = $branch -replace '^.*(release[-/])v'
- $vstsCommandString = "vso[task.setvariable variable=PowerShellVersion]$version"
- Write-Verbose -Message "Version is $version" -Verbose
- Write-Host -Object "##$vstsCommandString"
- displayName: Set PowerShell Version
-
- - pwsh: |
- $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
- Start-PSBootstrap
-
- $toolPath = New-Item -ItemType Directory "$(System.DefaultWorkingDirectory)/toolPath" | Select-Object -ExpandProperty FullName
-
- dotnet tool install --add-source "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults" --tool-path $toolPath --version '$(PowerShellVersion)' '${{ parameters.globalToolPackageName }}'
-
- Get-ChildItem -Path $toolPath
-
- displayName: Install global tool
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- $toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}"
-
- if (-not (Test-Path $toolPath))
- {
- throw "Tool is not installed at $toolPath"
- }
- else
- {
- Write-Verbose -Verbose "Tool found at: $toolPath"
- }
- displayName: Validate tool is installed
-
- - pwsh: |
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
- Start-PSBootstrap
-
- $exeName = if ($IsWindows) { "pwsh.exe" } else { "pwsh" }
-
- $toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}"
-
- $source = (get-command -Type Application -Name dotnet | Select-Object -First 1 -ExpandProperty source)
- $target = (Get-ChildItem $source).target
-
- # If we find a symbolic link for dotnet, then we need to split the filename off the target.
- if ($target) {
- Write-Verbose -Verbose "Splitting target: $target"
- $target = Split-Path $target
- }
-
- Write-Verbose -Verbose "target is set as $target"
-
- $env:DOTNET_ROOT = (resolve-path -Path (Join-Path (split-path $source) $target)).ProviderPath
-
- Write-Verbose -Verbose "DOTNET_ROOT: $env:DOTNET_ROOT"
- Get-ChildItem $env:DOTNET_ROOT
-
- $versionFound = & $toolPath -c '$PSVersionTable.PSVersion.ToString()'
-
- if ( '$(PowerShellVersion)' -ne $versionFound)
- {
- throw "Expected version of global tool not found. Installed version is $versionFound"
- }
- else
- {
- write-verbose -verbose "Found expected version: $versionFound"
- }
-
- $dateYear = & $toolPath -c '(Get-Date).Year'
-
- if ( $dateYear -ne [DateTime]::Now.Year)
- {
- throw "Get-Date returned incorrect year: $dateYear"
- }
- else
- {
- write-verbose -verbose "Got expected year: $dateYear"
- }
- displayName: Basic validation
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
diff --git a/tools/releaseBuild/azureDevOps/templates/release-MakeContainerPublic.yml b/tools/releaseBuild/azureDevOps/templates/release-MakeContainerPublic.yml
deleted file mode 100644
index 65d5ea50191..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-MakeContainerPublic.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-steps:
-- download: none
-
-- template: release-SetReleaseTagAndContainerName.yml
-
-- pwsh: |
- az login --service-principal -u $(az_url) -p $(az_key) --tenant $(az_name)
- displayName: az login
-
-- pwsh: |
- az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion) --public-access blob
- displayName: Make container public
-
-- pwsh: |
- az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion)-gc --public-access blob
- displayName: Make guest configuration miminal package container public
-
-- pwsh: |
- az logout
- displayName: az logout
diff --git a/tools/releaseBuild/azureDevOps/templates/release-MsixBundle.yml b/tools/releaseBuild/azureDevOps/templates/release-MsixBundle.yml
deleted file mode 100644
index a9591b2d251..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-MsixBundle.yml
+++ /dev/null
@@ -1,81 +0,0 @@
-jobs:
-- job: CreateMSIXBundle
- displayName: Create .msixbundle file
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- variables:
- - group: msixTools
- - group: 'Azure Blob variable group'
-
- steps:
- - template: release-SetReleaseTagAndContainerName.yml
-
- - task: DownloadPipelineArtifact@2
- retryCountOnTaskFailure: 2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: finalResults
- patterns: '**/*.msix'
- path: '$(Pipeline.Workspace)\releasePipeline\msix'
-
- - pwsh: |
- $cmd = Get-Command makeappx.exe -ErrorAction Ignore
- if ($cmd) {
- Write-Verbose -Verbose 'makeappx available in PATH'
- $exePath = $cmd.Source
- } else {
- $toolsDir = '$(Pipeline.Workspace)\releasePipeline\tools'
- New-Item $toolsDir -Type Directory -Force > $null
- Invoke-RestMethod -Uri '$(makeappUrl)' -OutFile "$toolsDir\makeappx.zip"
- Expand-Archive "$toolsDir\makeappx.zip" -DestinationPath "$toolsDir\makeappx" -Force
- $exePath = "$toolsDir\makeappx\makeappx.exe"
-
- Write-Verbose -Verbose 'makeappx was installed:'
- Get-ChildItem -Path $toolsDir -Recurse
- }
-
- $vstsCommandString = "vso[task.setvariable variable=MakeAppxPath]$exePath"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- displayName: Install makeappx tool
- retryCountOnTaskFailure: 1
-
- - pwsh: |
- $sourceDir = '$(Pipeline.Workspace)\releasePipeline\msix'
- $file = Get-ChildItem $sourceDir | Select-Object -First 1
- $prefix = ($file.BaseName -split "-win")[0]
- $pkgName = "$prefix.msixbundle"
- Write-Verbose -Verbose "Creating $pkgName"
-
- $makeappx = '$(MakeAppxPath)'
- $outputDir = "$sourceDir\output"
- New-Item $outputDir -Type Directory -Force > $null
- & $makeappx bundle /d $sourceDir /p "$outputDir\$pkgName"
-
- Get-ChildItem -Path $sourceDir -Recurse
- $vstsCommandString = "vso[task.setvariable variable=BundleDir]$outputDir"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- displayName: Create MsixBundle
- retryCountOnTaskFailure: 1
-
- - task: AzureFileCopy@4
- displayName: 'Upload MSIX Bundle package to Az Blob'
- retryCountOnTaskFailure: 2
- inputs:
- SourcePath: '$(BundleDir)/*.msixbundle'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)-private'
- resourceGroup: '$(StorageResourceGroup)'
- condition: succeeded()
diff --git a/tools/releaseBuild/azureDevOps/templates/release-PublishPackageMsftCom.yml b/tools/releaseBuild/azureDevOps/templates/release-PublishPackageMsftCom.yml
deleted file mode 100644
index 861cf48c35a..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-PublishPackageMsftCom.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-parameters:
- - name: skipPublish
- default: false
- type: boolean
-
-steps:
-- template: release-SetReleaseTagAndContainerName.yml
-
-- pwsh: |
- $packageVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '^v',''
- $vstsCommandString = "vso[task.setvariable variable=packageVersion]$packageVersion"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- displayName: Set Package version
-
-- pwsh: |
- $branch = 'main-mirror'
- $gitArgs = "clone",
- "--verbose",
- "--branch",
- "$branch",
- "https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools",
- '$(Pipeline.Workspace)/tools'
- $gitArgs | Write-Verbose -Verbose
- git $gitArgs
- displayName: Clone Internal-PowerShellTeam-Tools from MSCodeHub
-
-- task: PipAuthenticate@1
- inputs:
- artifactFeeds: 'pmc'
- pythonDownloadServiceConnections: pmcDownload
-
-- pwsh: |
- pip install pmc-cli
-
- $newPath = (resolve-path '~/.local/bin').providerpath
- $vstsCommandString = "vso[task.setvariable variable=PATH]${env:PATH}:$newPath"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- displayName: Install pmc cli
-
-- pwsh: |
- $metadata = Get-Content -Path "$(Build.SourcesDirectory)/tools/metadata.json" -Raw | ConvertFrom-Json
- $params = @{
- ReleaseTag = "$(ReleaseTag)"
- AadClientId = "$(PmcCliClientID)"
- BlobFolderName = "$(AzureVersion)"
- LTS = $metadata.LTSRelease.Latest
- ForProduction = $true
- SkipPublish = $${{ parameters.skipPublish }}
- MappingFilePath = '$(System.DefaultWorkingDirectory)/tools/packages.microsoft.com/mapping.json'
- }
-
- $params | Out-String -width 9999 -Stream | write-Verbose -Verbose
-
- & '$(Pipeline.Workspace)/tools/packages.microsoft.com-v4/releaseLinuxPackages.ps1' @params
- displayName: Run release script
diff --git a/tools/releaseBuild/azureDevOps/templates/release-PublishSymbols.yml b/tools/releaseBuild/azureDevOps/templates/release-PublishSymbols.yml
deleted file mode 100644
index db2cc86e259..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-PublishSymbols.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-steps:
-- task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: results
- path: '$(Pipeline.Workspace)\results'
- itemPattern: |
- **/*
- !**/*signed.zip
-
-- pwsh: |
- Write-Verbose -Verbose "Enumerating $(Pipeline.Workspace)\results"
- $downloadedArtifacts = Get-ChildItem -Recurse "$(Pipeline.Workspace)\results"
- $downloadedArtifacts
- $expandedRoot = New-Item -Path "$(Pipeline.Workspace)/expanded" -ItemType Directory -Verbose
- $symbolsRoot = New-Item -Path "$(Pipeline.Workspace)/symbols" -ItemType Directory -Verbose
-
- $downloadedArtifacts | ForEach-Object {
- $destFolder = New-Item -Path "$expandedRoot/$($_.BaseName)/" -ItemType Directory -Verbose
- Expand-Archive -Path $_.FullName -DestinationPath $destFolder -Force
-
- $symbolsZipFile = Join-Path -Path $destFolder -ChildPath "symbols.zip"
- $symbolZipFileContents = New-Item -Path "$destFolder/Symbols-$($_.BaseName)" -ItemType Directory -Verbose
- Expand-Archive -Path $symbolsZipFile -DestinationPath $symbolZipFileContents -Force
-
- $symbolsToPublish = New-Item -Path "$symbolsRoot/$($_.BaseName)" -ItemType Directory -Verbose
-
- Get-ChildItem -Path $symbolZipFileContents -Recurse -Filter '*.pdb' | ForEach-Object {
- Copy-Item -Path $_.FullName -Destination $symbolsToPublish -Verbose
- }
- }
-
- Write-Verbose -Verbose "Enumerating $symbolsRoot"
- Get-ChildItem -Path $symbolsRoot -Recurse
- $vstsCommandString = "vso[task.setvariable variable=SymbolsPath]$symbolsRoot"
- Write-Verbose -Message "$vstsCommandString" -Verbose
- Write-Host -Object "##$vstsCommandString"
- displayName: Expand and capture symbols folders
-- task: PublishSymbols@2
- inputs:
- symbolsFolder: '$(SymbolsPath)'
- searchPattern: '**/*.pdb'
- indexSources: false
- publishSymbols: true
- symbolServerType: teamServices
- detailedLog: true
diff --git a/tools/releaseBuild/azureDevOps/templates/release-ReleaseToNuGet.yml b/tools/releaseBuild/azureDevOps/templates/release-ReleaseToNuGet.yml
deleted file mode 100644
index 33a72f56bbb..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-ReleaseToNuGet.yml
+++ /dev/null
@@ -1,56 +0,0 @@
-parameters:
- - name: skipPublish
- default: false
- type: boolean
-
-steps:
-- task: DownloadPipelineArtifact@2
- condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded())
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: finalResults
- patterns: '**/*.nupkg'
- path: '$(Pipeline.Workspace)/releasePipeline/finalResults'
-
-- task: DownloadPipelineArtifact@2
- condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded())
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: metadata
- path: '$(Pipeline.Workspace)/releasePipeline/metadata'
-
-- pwsh: |
- #Exclude all global tool packages. Their names start with 'PowerShell.'
- $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release"
- Copy-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose
-
- $releaseVersion = Get-Content "$ENV:PIPELINE_WORKSPACE/releasePipeline/metadata/release.json" | ConvertFrom-Json | Select-Object -ExpandProperty 'ReleaseVersion'
- $globalToolPath = "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults/PowerShell.$releaseVersion.nupkg"
-
- if ($releaseVersion -notlike '*-*') {
- # Copy the global tool package for stable releases
- Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release"
- }
-
- Get-ChildItem "$(Pipeline.Workspace)/release" -recurse
- displayName: Download and capture nupkgs
- condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded())
-
-- task: NuGetCommand@2
- displayName: 'NuGet push'
- condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded())
- inputs:
- command: push
- packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg'
- nuGetFeedType: external
- publishFeedCredentials: PowerShellNuGetOrgPush
diff --git a/tools/releaseBuild/azureDevOps/templates/release-SDKTests.yml b/tools/releaseBuild/azureDevOps/templates/release-SDKTests.yml
deleted file mode 100644
index 93fb0bf07cb..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-SDKTests.yml
+++ /dev/null
@@ -1,148 +0,0 @@
-parameters:
- jobName: ""
- displayName: ""
- imageName: ""
-
-jobs:
-- job: ${{ parameters.jobName }}
- displayName: ${{ parameters.displayName }}
- pool:
- # testing
- vmImage: ${{ parameters.imageName }}
- variables:
- - group: mscodehub-feed-read-general
- - group: mscodehub-feed-read-akv
- - group: DotNetPrivateBuildAccess
- steps:
- - checkout: self
- clean: true
-
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: finalResults
- patterns: '**/*.nupkg'
- path: '$(Pipeline.Workspace)/releasePipeline/finalResults'
-
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: metadata
- path: '$(Pipeline.Workspace)/releasePipeline/metadata'
-
- - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self
- parameters:
- repoRoot: $(Build.SourcesDirectory)
-
- - pwsh: |
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
-
- Write-Verbose -Verbose "Capture hosting folder files"
- Get-ChildItem '$(Build.SourcesDirectory)/test/hosting'
-
- # The above cmdlet creates a lower-case nuget.config. There also exists a NuGet.config which we needed to replace.
- # Hence the following workaround
-
- if (-not $IsWindows) {
- Move-Item -Path '$(Build.SourcesDirectory)/test/hosting/nuget.config' -Destination '$(Build.SourcesDirectory)/test/hosting/NuGet.Config' -Force -ErrorAction Continue
- Write-Verbose -Verbose "Capture hosting folder files after Move-Item"
- Get-ChildItem '$(Build.SourcesDirectory)/test/hosting'
- }
-
- if(-not (Test-Path "$(Build.SourcesDirectory)/test/hosting/NuGet.Config"))
- {
- throw "NuGet.Config is not created"
- }
- else
- {
- Write-Verbose -Verbose "Capture NuGet.Config contents"
- Get-Content "$(Build.SourcesDirectory)/test/hosting/NuGet.Config" -Raw
- }
- displayName: Insert internal nuget feed
-
- - pwsh: |
- $dotnetMetadataPath = "$(Build.SourcesDirectory)/DotnetRuntimeMetadata.json"
- $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json
-
- # Channel is like: $Channel = "5.0.1xx-preview2"
- $Channel = $dotnetMetadataJson.sdk.channel
-
- $sdkVersion = (Get-Content "$(Build.SourcesDirectory)/global.json" -Raw | ConvertFrom-Json).sdk.version
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
-
- Find-Dotnet
-
- if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue))
- {
- $nugetFeed = ([xml](Get-Content $(Build.SourcesDirectory)/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value
-
- if ($nugetFeed) {
- Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet
- Write-Verbose -Message "Register new package source 'dotnet'" -verbose
- }
- }
-
- ## Install latest version from the channel
- #Install-Dotnet -Channel "$Channel" -Version $sdkVersion
-
- Start-PSBootstrap
-
- Write-Verbose -Message "Installing .NET SDK completed." -Verbose
-
- displayName: Install .NET
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
- Start-PSBootstrap
-
- $localLocation = "$(Pipeline.Workspace)/releasePipeline/finalResults"
- $xmlElement = @"
-
-
-
- "@
-
- $releaseVersion = Get-Content "$(Pipeline.Workspace)/releasePipeline/metadata/release.json" | ConvertFrom-Json | Select-Object -ExpandProperty 'ReleaseVersion'
-
- Set-Location -Path $(Build.SourcesDirectory)/test/hosting
-
- Get-ChildItem
-
- ## register the packages download directory in the nuget file
- $nugetConfigContent = Get-Content ./NuGet.Config -Raw
- $updateNugetContent = $nugetConfigContent.Replace("", $xmlElement)
-
- $updateNugetContent | Out-File ./NuGet.Config -Encoding ascii
-
- Get-Content ./NuGet.Config
-
- # Add workaround to unblock xUnit testing see issue: https://github.com/dotnet/sdk/issues/26462
- $dotnetPath = if ($IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" }
- $env:DOTNET_ROOT = $dotnetPath
-
- dotnet --info
- dotnet restore
- dotnet test /property:RELEASE_VERSION=$releaseVersion --test-adapter-path:. "--logger:xunit;LogFilePath=$(System.DefaultWorkingDirectory)/test-hosting.xml"
-
- displayName: Restore and execute tests
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - task: PublishTestResults@2
- displayName: 'Publish Test Results **\test-hosting.xml'
- inputs:
- testResultsFormat: XUnit
- testResultsFiles: '**\test-hosting.xml'
diff --git a/tools/releaseBuild/azureDevOps/templates/release-SetReleaseTagAndContainerName.yml b/tools/releaseBuild/azureDevOps/templates/release-SetReleaseTagAndContainerName.yml
deleted file mode 100644
index 7e88624b45c..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-SetReleaseTagAndContainerName.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-steps:
-- pwsh: |
- $variable = 'releaseTag'
- $branch = $ENV:BUILD_SOURCEBRANCH
- if($branch -notmatch '^.*((release/|rebuild/.*rebuild))')
- {
- throw "Branch name is not in release format: '$branch'"
- }
-
- $releaseTag = $Branch -replace '^.*((release|rebuild)/)'
- $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag"
- Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose
- Write-Host -Object "##$vstsCommandString"
- displayName: Set Release Tag
-
-- pwsh: |
- $azureVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '\.', '-'
- $vstsCommandString = "vso[task.setvariable variable=AzureVersion]$azureVersion"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
-
- $version = '$(ReleaseTag)'.ToLowerInvariant().Substring(1)
- $vstsCommandString = "vso[task.setvariable variable=Version]$version"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- displayName: Set container name
diff --git a/tools/releaseBuild/azureDevOps/templates/release-UpdateDepsJson.yml b/tools/releaseBuild/azureDevOps/templates/release-UpdateDepsJson.yml
deleted file mode 100644
index fa42064602e..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-UpdateDepsJson.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-jobs:
-- job: UpdateDepsFiles
- displayName: Update deps files
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- variables:
- - group: 'Azure Blob variable group'
- steps:
- - checkout: self
- clean: true
-
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: finalResults
- patterns: '**/PowerShell*-win-x64.zip'
- path: '$(Pipeline.Workspace)/releasePipeline/finalResults'
-
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: BuildInfoJson
- path: '$(Pipeline.Workspace)/releasePipeline/BuildInfoJson'
-
- - pwsh: |
- $fileName = (Get-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/BuildInfoJson/*.json").BaseName
- if ($fileName -notin 'stable','preview')
- {
- throw "Unexpected fileName: $fileName"
- }
-
- $vstsCommand = "vso[task.setvariable variable=BlobPrefix]$fileName"
- Write-Verbose -Verbose $vstsCommand
- Write-Host "##$vstsCommand"
- displayName: Determine container name
-
- - pwsh: |
- $zipFile = Get-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults/PowerShell*-win-x64.zip" -Exclude *-symbols-*
- Write-Verbose -Verbose "zipFile: $zipFile"
- Expand-Archive -Path $zipFile -Destination "$ENV:PIPELINE_WORKSPACE/expanded"
-
- $pwshDepsFile = Get-Item "$ENV:PIPELINE_WORKSPACE/expanded/pwsh.deps.json"
- $vstsCommand = "vso[task.setvariable variable=FileToUpload]$pwshDepsFile"
- Write-Verbose -Verbose $vstsCommand
- Write-Host "##$vstsCommand"
- displayName: Determine file to upload
-
- - task: AzureFileCopy@4
- displayName: 'AzureBlob pwsh.deps.json file Copy'
- inputs:
- SourcePath: '$(FileToUpload)'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: ps-deps-json
- blobPrefix: '$(BlobPrefix)'
- retryCountOnTaskFailure: 2
diff --git a/tools/releaseBuild/azureDevOps/templates/release-ValidateFxdPackage.yml b/tools/releaseBuild/azureDevOps/templates/release-ValidateFxdPackage.yml
deleted file mode 100644
index 7f2c816a20f..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-ValidateFxdPackage.yml
+++ /dev/null
@@ -1,92 +0,0 @@
-parameters:
- jobName: ""
- displayName: ""
- imageName: ""
- packageNamePattern: ""
- use1ES: false
-
-jobs:
-- job: ${{ parameters.jobName }}
- displayName: ${{ parameters.displayName }}
- variables:
- - group: DotNetPrivateBuildAccess
- pool:
- ${{ if eq(parameters.use1ES, 'false') }}:
- vmImage: ${{ parameters.imageName }}
- ${{ else }}:
- name: 'PS-MSCodeHub-ARM' # add ImageOverride to select image
- steps:
- - checkout: self
- clean: true
-
- - task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: finalResults
- patterns: '${{ parameters.packageNamePattern }}'
- path: '$(Pipeline.Workspace)/releasePipeline/finalResults'
-
- - pwsh: |
- $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
- Start-PSBootstrap
- Write-Verbose -Message "Installing .NET SDK completed." -Verbose
- displayName: Install .NET
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- Get-ChildItem -Path '$(Pipeline.Workspace)/releasePipeline/finalResults' -Recurse
- displayName: Capture downloaded package
-
- - pwsh: |
- $destPath = New-Item '$(Pipeline.Workspace)/releasePipeline/finalResults/fxd' -ItemType Directory
- $packageNameFilter = '${{ parameters.packageNamePattern }}'
-
- if ($packageNameFilter.EndsWith('tar.gz')) {
- $package = @(Get-ChildItem -Path '$(Pipeline.Workspace)/releasePipeline/finalResults/*.tar.gz')
- Write-Verbose -Verbose "Package: $package"
- if ($package.Count -ne 1) {
- throw 'Only 1 package was expected.'
- }
- tar -xvf $package.FullName -C $destPath
- }
- else {
- $package = @(Get-ChildItem -Path '$(Pipeline.Workspace)/releasePipeline/finalResults/*.zip')
- Write-Verbose -Verbose "Package: $package"
- if ($package.Count -ne 1) {
- throw 'Only 1 package was expected.'
- }
- Expand-Archive -Path $package.FullName -Destination "$destPath" -Verbose
- }
- displayName: Expand fxd package
-
- - pwsh: |
- $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
- Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force
- Find-Dotnet -SetDotnetRoot
- Write-Verbose -Verbose "DOTNET_ROOT: $env:DOTNET_ROOT"
- Write-Verbose -Verbose "Check dotnet install"
- dotnet --info
- Write-Verbose -Verbose "Start test"
- $packageNameFilter = '${{ parameters.packageNamePattern }}'
- $pwshExeName = if ($packageNameFilter.EndsWith('tar.gz')) { 'pwsh' } else { 'pwsh.exe' }
- $pwshPath = Join-Path '$(Pipeline.Workspace)/releasePipeline/finalResults/fxd' $pwshExeName
-
- if ($IsLinux) {
- chmod u+x $pwshPath
- }
-
- $pwshDllPath = Join-Path '$(Pipeline.Workspace)/releasePipeline/finalResults/fxd' 'pwsh.dll'
-
- $actualOutput = & dotnet $pwshDllPath -c 'Start-ThreadJob -ScriptBlock { "1" } | Wait-Job | Receive-Job'
- Write-Verbose -Verbose "Actual output: $actualOutput"
- if ($actualOutput -ne 1) {
- throw "Actual output is not as expected"
- }
- displayName: Test package
diff --git a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageBOM.yml b/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageBOM.yml
deleted file mode 100644
index a7217968575..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageBOM.yml
+++ /dev/null
@@ -1,49 +0,0 @@
-steps:
-- checkout: self
- clean: true
-
-- pwsh: |
- Get-ChildItem ENV: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: Capture environment
-
-- template: release-SetReleaseTagAndContainerName.yml
-
-- pwsh: |
- $name = "{0}_{1:x}" -f '$(releaseTag)', (Get-Date).Ticks
- Write-Host $name
- Write-Host "##vso[build.updatebuildnumber]$name"
- displayName: Set Release Name
-
-- task: DownloadPipelineArtifact@2
- inputs:
- source: specific
- project: PowerShellCore
- pipeline: '696'
- preferTriggeringPipeline: true
- runVersion: latestFromBranch
- runBranch: '$(Build.SourceBranch)'
- artifact: finalResults
- path: $(System.ArtifactsDirectory)
-
-
-- pwsh: |
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name
- displayName: Capture Artifact Listing
-
-- pwsh: |
- Install-module Pester -Scope CurrentUser -Force -MaximumVersion 4.99
- displayName: Install Pester
- condition: succeededOrFailed()
-
-- pwsh: |
- Import-module './build.psm1'
- Import-module './tools/packaging'
- $env:PACKAGE_FOLDER = '$(System.ArtifactsDirectory)'
- $path = Join-Path -Path $pwd -ChildPath './packageReleaseTests.xml'
- $results = invoke-pester -Script './tools/packaging/releaseTests' -OutputFile $path -OutputFormat NUnitXml -PassThru
- Write-Host "##vso[results.publish type=NUnit;mergeResults=true;runTitle=Package Release Tests;publishRunAttachments=true;resultFiles=$path;]"
- if($results.TotalCount -eq 0 -or $results.FailedCount -gt 0)
- {
- throw "Package Release Tests failed"
- }
- displayName: Run packaging release tests
diff --git a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageNames.yml b/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageNames.yml
deleted file mode 100644
index 3a9aaa511f3..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageNames.yml
+++ /dev/null
@@ -1,93 +0,0 @@
-steps:
-- pwsh: |
- Get-ChildItem ENV: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: Capture environment
-
-- template: release-SetReleaseTagAndContainerName.yml
-
-- pwsh: |
- $name = "{0}_{1:x}" -f '$(releaseTag)', (Get-Date).Ticks
- Write-Host $name
- Write-Host "##vso[build.updatebuildnumber]$name"
- displayName: Set Release Name
-
-- pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1'
- $azcopy = Find-AzCopy
- Write-Verbose -Verbose "Found AzCopy: $azcopy"
-
- & $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/* $(System.ArtifactsDirectory) --recursive
-
- displayName: Download Azure Artifacts
- env:
- AZCOPY_AUTO_LOGIN_TYPE: MSI
-
-- pwsh: |
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name
- displayName: Capture Artifact Listing
-
-- pwsh: |
- $message = @()
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.rpm | ForEach-Object {
- if($_.Name -notmatch 'powershell\-(preview-|lts-)?\d+\.\d+\.\d+(_[a-z]*\.\d+)?-1.(rh|cm).(x86_64|aarch64)\.rpm')
- {
- $messageInstance = "$($_.Name) is not a valid package name"
- $message += $messageInstance
- Write-Warning $messageInstance
- }
- }
- if($message.count -gt 0){throw ($message | out-string)}
- displayName: Validate RPM package names
-
-- pwsh: |
- $message = @()
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.tar.gz | ForEach-Object {
- if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?(linux|osx|linux-musl)+\-(x64\-fxdependent|x64|arm32|arm64|x64\-musl-noopt\-fxdependent)\.(tar\.gz)')
- {
- $messageInstance = "$($_.Name) is not a valid package name"
- $message += $messageInstance
- Write-Warning $messageInstance
- }
- }
- if($message.count -gt 0){throw ($message | out-string)}
- displayName: Validate Tar.Gz Package Names
-
-- pwsh: |
- $message = @()
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.pkg | ForEach-Object {
- if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?osx(\.10\.12)?\-(x64|arm64)\.pkg')
- {
- $messageInstance = "$($_.Name) is not a valid package name"
- $message += $messageInstance
- Write-Warning $messageInstance
- }
- }
- if($message.count -gt 0){throw ($message | out-string)}
- displayName: Validate PKG Package Names
-
-- pwsh: |
- $message = @()
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object {
- if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}')
- {
- $messageInstance = "$($_.Name) is not a valid package name"
- $message += $messageInstance
- Write-Warning $messageInstance
- }
- }
-
- if($message.count -gt 0){throw ($message | out-string)}
- displayName: Validate Zip and MSI Package Names
-
-- pwsh: |
- $message = @()
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.deb | ForEach-Object {
- if($_.Name -notmatch 'powershell(-preview|-lts)?_\d+\.\d+\.\d+([\-~][a-z]*.\d+)?-\d\.deb_amd64\.deb')
- {
- $messageInstance = "$($_.Name) is not a valid package name"
- $message += $messageInstance
- Write-Warning $messageInstance
- }
- }
- if($message.count -gt 0){throw ($message | out-string)}
- displayName: Validate Deb Package Names
diff --git a/tools/releaseBuild/azureDevOps/templates/release/approvalJob.yml b/tools/releaseBuild/azureDevOps/templates/release/approvalJob.yml
deleted file mode 100644
index b34cc4c75b6..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/release/approvalJob.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-parameters:
- - name: displayName
- type: string
- - name: instructions
- type: string
- - name: jobName
- type: string
- default: approval
- - name: timeoutInMinutes
- type: number
- # 2 days
- default: 2880
- - name: onTimeout
- type: string
- default: 'reject'
- values:
- - resume
- - reject
- - name: dependsOnJob
- type: string
- default: ''
-
-jobs:
- - job: ${{ parameters.jobName }}
- dependsOn: ${{ parameters.dependsOnJob }}
- displayName: ${{ parameters.displayName }}
- pool: server
- timeoutInMinutes: 4320 # job times out in 3 days
- steps:
- - task: ManualValidation@0
- displayName: ${{ parameters.displayName }}
- timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
- inputs:
- instructions: ${{ parameters.instructions }}
- onTimeout: ${{ parameters.onTimeout }}
diff --git a/tools/releaseBuild/azureDevOps/templates/shouldSign.yml b/tools/releaseBuild/azureDevOps/templates/shouldSign.yml
deleted file mode 100644
index e3c38cb29d5..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/shouldSign.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-steps:
-- powershell: |
- $shouldSign = $true
- $authenticodeCert = 'CP-230012'
- $msixCert = 'CP-230012'
-
- if($env:IS_DAILY -eq 'true')
- {
- $authenticodeCert = 'CP-460906'
- }
-
- if($env:SKIP_SIGNING -eq 'Yes')
- {
- $shouldSign = $false
- }
-
- $vstsCommandString = "vso[task.setvariable variable=SHOULD_SIGN]$($shouldSign.ToString().ToLowerInvariant())"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
-
- $vstsCommandString = "vso[task.setvariable variable=MSIX_CERT]$($msixCert)"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
-
- $vstsCommandString = "vso[task.setvariable variable=AUTHENTICODE_CERT]$($authenticodeCert)"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
-
- displayName: 'Set SHOULD_SIGN Variable'
diff --git a/tools/releaseBuild/azureDevOps/templates/sign-build-file.yml b/tools/releaseBuild/azureDevOps/templates/sign-build-file.yml
deleted file mode 100644
index a584e15e27c..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/sign-build-file.yml
+++ /dev/null
@@ -1,328 +0,0 @@
-steps:
-- pwsh: |
- $platform = '$(runtime)' -match '^linux' ? 'linux' : 'windows'
- $vstsCommandString = "vso[task.setvariable variable=ArtifactPlatform]$platform"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- displayName: Set artifact platform
-
-- task: DownloadPipelineArtifact@2
- inputs:
- artifactName: '$(unsignedBuildArtifactContainer)'
- itemPattern: '$(unsignedBuildArtifactName)'
-
-- pwsh: |
- Get-ChildItem "$(Pipeline.Workspace)\*" -Recurse
- displayName: 'Capture Downloaded Artifacts'
- # Diagnostics is not critical it passes every time it runs
- continueOnError: true
-
-- checkout: self
- clean: true
- path: $(repoFolder)
-
-- template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
-- template: cloneToOfficialPath.yml
-
-- pwsh: |
- $zipFileFilter = '$(unsignedBuildArtifactName)'
- $zipFileFilter = $zipFileFilter.Replace('**/', '')
-
- Write-Verbose -Verbose -Message "zipFileFilter = $zipFileFilter"
-
- Write-Verbose -Verbose -Message "Looking for $(Pipeline.Workspace)\$(unsignedBuildArtifactName)"
-
- $zipFilePath = Get-ChildItem -Path '$(Pipeline.Workspace)\$(unsignedBuildArtifactName)' -recurse
-
- if (-not (Test-Path $zipFilePath))
- {
- throw "zip file not found: $zipfilePath"
- }
-
- if ($zipFilePath.Count -ne 1) {
- Write-Verbose "zip filename" -verbose
- $zipFilePath | Out-String | Write-Verbose -Verbose
- throw 'multiple zip files found when 1 was expected'
- }
-
- $expandedFolderName = [System.io.path]::GetFileNameWithoutExtension($zipfilePath)
- $expandedFolderPath = Join-Path '$(Pipeline.Workspace)' 'expanded' $expandedFolderName
-
- Write-Verbose -Verbose -Message "Expaning $zipFilePath to $expandedFolderPath"
-
- New-Item -Path $expandedFolderPath -ItemType Directory
- Expand-Archive -Path $zipFilePath -DestinationPath $expandedFolderPath
-
- if (-not (Test-Path $expandedFolderPath\pwsh.exe) ) {
- throw 'zip did not expand as expected'
- }
- else {
- $vstsCommandString = "vso[task.setvariable variable=BinPath]$expandedFolderPath"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- }
-
- displayName: Expand zip packages
- condition: eq(variables['ArtifactPlatform'], 'windows')
-
-- pwsh: |
- $tarPackageName = '$(unsignedBuildArtifactName)'
-
- Write-Verbose -Verbose -Message "tarPackageName = $tarPackageName"
-
- $tarPackagePath = Join-Path '$(Pipeline.Workspace)' $tarPackageName
-
- Write-Verbose -Verbose -Message "Looking for: $tarPackagePath"
-
- $expandedPathFolderName = $tarPackageName -replace '.tar.gz', ''
- $expandedFolderPath = Join-Path '$(Pipeline.Workspace)' 'expanded' $expandedPathFolderName
-
- if (-not (Test-Path $tarPackagePath))
- {
- throw "tar file not found: $tarPackagePath"
- }
-
- Write-Verbose -Verbose -Message "Expanding $tarPackagePath to $expandedFolderPath"
-
- New-Item -Path $expandedFolderPath -ItemType Directory
- tar -xf $tarPackagePath -C $expandedFolderPath
-
- if (-not (Test-Path $expandedFolderPath/pwsh) ) {
- throw 'tar.gz did not expand as expected'
- }
- else {
- $vstsCommandString = "vso[task.setvariable variable=BinPath]$expandedFolderPath"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- }
-
- Write-Verbose -Verbose "File permisions after expanding"
- Get-ChildItem -Path "$expandedFolderPath/pwsh" | Select-Object -Property 'unixmode', 'size', 'name'
- displayName: Expand tar.gz packages
- condition: eq(variables['ArtifactPlatform'], 'linux')
-
-- template: insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(PowerShellRoot)
-
-- pwsh: |
- Set-Location $env:POWERSHELLROOT
- import-module "$env:POWERSHELLROOT/build.psm1"
- Sync-PSTags -AddRemoteIfMissing
- displayName: SyncTags
- condition: and(succeeded(), ne(variables['SkipBuild'], 'true'))
-
-- checkout: ComplianceRepo
- clean: true
- path: $(complianceRepoFolder)
-
-- template: shouldSign.yml
-
-- pwsh: |
- $fullSymbolsFolder = '$(BinPath)'
- Write-Verbose -Verbose "fullSymbolsFolder == $fullSymbolsFolder"
-
- Get-ChildItem -Recurse $fullSymbolsFolder | out-string | Write-Verbose -Verbose
-
- $filesToSignDirectory = "$(System.ArtifactsDirectory)\toBeSigned"
-
- if ((Test-Path -Path $filesToSignDirectory)) {
- Remove-Item -Path $filesToSignDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force
-
- $signedFilesDirectory = "$(System.ArtifactsDirectory)\signed"
-
- if ((Test-Path -Path $signedFilesDirectory)) {
- Remove-Item -Path $signedFilesDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force
-
- $itemsToCopyWithRecurse = @(
- "$($fullSymbolsFolder)\*.ps1"
- "$($fullSymbolsFolder)\Microsoft.PowerShell*.dll"
- )
-
- $itemsToCopy = @{
- "$($fullSymbolsFolder)\*.ps1" = ""
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Host\Microsoft.PowerShell.Host.psd1" = "Modules\Microsoft.PowerShell.Host"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1" = "Modules\Microsoft.PowerShell.Management"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.psd1" = "Modules\Microsoft.PowerShell.Security"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" = "Modules\Microsoft.PowerShell.Utility"
- "$($fullSymbolsFolder)\pwsh.dll" = ""
- "$($fullSymbolsFolder)\System.Management.Automation.dll" = ""
- }
-
- ## Windows only modules
-
- if('$(ArtifactPlatform)' -eq 'windows') {
- $itemsToCopy += @{
- "$($fullSymbolsFolder)\pwsh.exe" = ""
- "$($fullSymbolsFolder)\Microsoft.Management.Infrastructure.CimCmdlets.dll" = ""
- "$($fullSymbolsFolder)\Microsoft.WSMan.*.dll" = ""
- "$($fullSymbolsFolder)\Modules\CimCmdlets\CimCmdlets.psd1" = "Modules\CimCmdlets"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Diagnostics.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Event.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\GetEvent.types.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Security.types.ps1xml" = "Modules\Microsoft.PowerShell.Security"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\Microsoft.WSMan.Management.psd1" = "Modules\Microsoft.WSMan.Management"
- "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\WSMan.format.ps1xml" = "Modules\Microsoft.WSMan.Management"
- "$($fullSymbolsFolder)\Modules\PSDiagnostics\PSDiagnostics.ps?1" = "Modules\PSDiagnostics"
- }
- }
- else {
- $itemsToCopy += @{
- "$($fullSymbolsFolder)\pwsh" = ""
- }
- }
-
- $itemsToExclude = @(
- # This package is retrieved from https://www.github.com/powershell/MarkdownRender
- "$($fullSymbolsFolder)\Microsoft.PowerShell.MarkdownRender.dll"
- )
-
- Write-Verbose -verbose "recusively copying $($itemsToCopyWithRecurse | out-string) to $filesToSignDirectory"
- Copy-Item -Path $itemsToCopyWithRecurse -Destination $filesToSignDirectory -Recurse -verbose -exclude $itemsToExclude
-
- foreach($pattern in $itemsToCopy.Keys) {
- $destinationFolder = Join-Path $filesToSignDirectory -ChildPath $itemsToCopy.$pattern
- $null = New-Item -ItemType Directory -Path $destinationFolder -Force
- Write-Verbose -verbose "copying $pattern to $destinationFolder"
- Copy-Item -Path $pattern -Destination $destinationFolder -Recurse -verbose
- }
- displayName: 'Prepare files to be signed'
-
-- template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\toBeSigned
- signOutputPath: $(System.ArtifactsDirectory)\signed
- certificateId: "$(AUTHENTICODE_CERT)"
- pattern: |
- **\*.dll
- **\*.psd1
- **\*.psm1
- **\*.ps1xml
- **\*.ps1
- **\*.exe
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Authenticode sign our binaries
-
-- pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
- $signedFilesPath = '$(System.ArtifactsDirectory)\signed\'
- $BuildPath = '$(BinPath)'
- Write-Verbose -Verbose -Message "BuildPath: $BuildPath"
-
- Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath
- $dlls = Get-ChildItem $BuildPath\*.dll, $BuildPath\*.exe -Recurse
- $signatures = $dlls | Get-AuthenticodeSignature
- $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path
-
- Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)"
-
- $filesToSignDirectory = "$(System.ArtifactsDirectory)\thirdPartyToBeSigned"
- if (Test-Path $filesToSignDirectory) {
- Remove-Item -Path $filesToSignDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force -Verbose
-
- $signedFilesDirectory = "$(System.ArtifactsDirectory)\thirdPartySigned"
- if (Test-Path $signedFilesDirectory) {
- Remove-Item -Path $signedFilesDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force -Verbose
-
- $missingSignatures | ForEach-Object {
- $pathWithoutLeaf = Split-Path $_
- $relativePath = $pathWithoutLeaf.replace($BuildPath,'')
- Write-Verbose -Verbose -Message "relativePath: $relativePath"
- $targetDirectory = Join-Path -Path $filesToSignDirectory -ChildPath $relativePath
- Write-Verbose -Verbose -Message "targetDirectory: $targetDirectory"
- if(!(Test-Path $targetDirectory))
- {
- $null = New-Item -ItemType Directory -Path $targetDirectory -Force -Verbose
- }
- Copy-Item -Path $_ -Destination $targetDirectory
- }
-
- displayName: Create ThirdParty Signing Folder
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
-- template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\thirdPartyToBeSigned
- signOutputPath: $(System.ArtifactsDirectory)\thirdPartySigned
- certificateId: "CP-231522"
- pattern: |
- **\*.dll
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign ThirdParty binaries
-
-- pwsh: |
- Get-ChildItem '$(System.ArtifactsDirectory)\thirdPartySigned\*'
- displayName: Capture ThirdParty Signed files
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
-- pwsh: |
- Import-Module '$(PowerShellRoot)/build.psm1' -Force
- Import-Module '$(PowerShellRoot)/tools/packaging' -Force
- $signedFilesPath = '$(System.ArtifactsDirectory)\thirdPartySigned'
- $BuildPath = '$(BinPath)'
-
- Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath
- if ($env:BuildConfiguration -eq 'minSize') {
- ## Remove XML files when making a min-size package.
- Remove-Item "$BuildPath/*.xml" -Force
- }
- displayName: Merge ThirdParty signed files with Build
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
-- pwsh: |
- $uploadFolder = '$(BinPath)'
- $containerName = '$(signedArtifactContainer)'
-
- Write-Verbose -Verbose "File permissions after signing"
- Get-ChildItem $uploadFolder\pwsh | Select-Object -Property 'unixmode', 'size', 'name'
-
- $uploadTarFilePath = Join-Path '$(System.ArtifactsDirectory)' '$(signedBuildArtifactName)'
- Write-Verbose -Verbose -Message "Creating tar.gz - $uploadTarFilePath"
- tar -czvf $uploadTarFilePath -C $uploadFolder *
-
- Get-ChildItem '$(System.ArtifactsDirectory)' | Out-String | Write-Verbose -Verbose
-
- Write-Host "##vso[artifact.upload containerfolder=$containerName;artifactname=$containerName]$uploadTarFilePath"
- displayName: Upload signed tar.gz files to artifacts
- condition: eq(variables['ArtifactPlatform'], 'linux')
- retryCountOnTaskFailure: 2
-
-
-- pwsh: |
- $uploadFolder = '$(BinPath)'
- $containerName = '$(signedArtifactContainer)'
-
- Get-ChildItem $uploadFolder -Recurse | Out-String | Write-Verbose -Verbose
-
- $uploadZipFilePath = Join-Path '$(System.ArtifactsDirectory)' 'PowerShell-$(Version)$(signedBuildArtifactName)'
- Write-Verbose -Verbose -Message "Creating zip - $uploadZipFilePath"
- Compress-Archive -Path $uploadFolder/* -DestinationPath $uploadZipFilePath -Verbose
-
- Get-ChildItem '$(System.ArtifactsDirectory)' | Out-String | Write-Verbose -Verbose
-
- Write-Host "##vso[artifact.upload containerfolder=$containerName;artifactname=$containerName]$uploadZipFilePath"
- displayName: Upload signed zip files to artifacts
- condition: eq(variables['ArtifactPlatform'], 'windows')
- retryCountOnTaskFailure: 2
-
-
-- template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml b/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml
deleted file mode 100644
index a7c7c640ce7..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml
+++ /dev/null
@@ -1,189 +0,0 @@
-parameters:
- binLocation: ''
- buildPrefixName: ''
- addWindowsModules: 'false'
-
-steps:
-- pwsh: |
- $fullSymbolsFolder = Join-Path $(System.ArtifactsDirectory) "${{ parameters.binLocation }}"
-
- Write-Verbose -Verbose "fullSymbolsFolder == $fullSymbolsFolder"
-
- Get-ChildItem -Recurse $fullSymbolsFolder | out-string | Write-Verbose -Verbose
-
- $filesToSignDirectory = "$(System.ArtifactsDirectory)\toBeSigned"
-
- if ((Test-Path -Path $filesToSignDirectory)) {
- Remove-Item -Path $filesToSignDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force
-
- $signedFilesDirectory = "$(System.ArtifactsDirectory)\signed"
-
- if ((Test-Path -Path $signedFilesDirectory)) {
- Remove-Item -Path $signedFilesDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force
-
- $itemsToCopyWithRecurse = @(
- "$($fullSymbolsFolder)\*.ps1"
- "$($fullSymbolsFolder)\Microsoft.PowerShell*.dll"
- )
-
- $itemsToCopy = @{
- "$($fullSymbolsFolder)\*.ps1" = ""
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Host\Microsoft.PowerShell.Host.psd1" = "Modules\Microsoft.PowerShell.Host"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1" = "Modules\Microsoft.PowerShell.Management"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.psd1" = "Modules\Microsoft.PowerShell.Security"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" = "Modules\Microsoft.PowerShell.Utility"
- "$($fullSymbolsFolder)\pwsh.dll" = ""
- "$($fullSymbolsFolder)\System.Management.Automation.dll" = ""
- }
-
- ## Windows only modules
-
- if('${{ parameters.addWindowsModules }}' -ne 'false') {
- $itemsToCopy += @{
- "$($fullSymbolsFolder)\pwsh.exe" = ""
- "$($fullSymbolsFolder)\Microsoft.Management.Infrastructure.CimCmdlets.dll" = ""
- "$($fullSymbolsFolder)\Microsoft.WSMan.*.dll" = ""
- "$($fullSymbolsFolder)\Modules\CimCmdlets\CimCmdlets.psd1" = "Modules\CimCmdlets"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Diagnostics.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Event.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\GetEvent.types.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Security.types.ps1xml" = "Modules\Microsoft.PowerShell.Security"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\Microsoft.WSMan.Management.psd1" = "Modules\Microsoft.WSMan.Management"
- "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\WSMan.format.ps1xml" = "Modules\Microsoft.WSMan.Management"
- "$($fullSymbolsFolder)\Modules\PSDiagnostics\PSDiagnostics.ps?1" = "Modules\PSDiagnostics"
- }
- }
- else {
- $itemsToCopy += @{
- "$($fullSymbolsFolder)\pwsh" = ""
- }
- }
-
- $itemsToExclude = @(
- # This package is retrieved from https://www.github.com/powershell/MarkdownRender
- "$($fullSymbolsFolder)\Microsoft.PowerShell.MarkdownRender.dll"
- )
-
- Write-Verbose -verbose "recusively copying $($itemsToCopyWithRecurse | out-string) to $filesToSignDirectory"
- Copy-Item -Path $itemsToCopyWithRecurse -Destination $filesToSignDirectory -Recurse -verbose -exclude $itemsToExclude
-
- foreach($pattern in $itemsToCopy.Keys) {
- $destinationFolder = Join-Path $filesToSignDirectory -ChildPath $itemsToCopy.$pattern
- $null = New-Item -ItemType Directory -Path $destinationFolder -Force
- Write-Verbose -verbose "copying $pattern to $destinationFolder"
- Copy-Item -Path $pattern -Destination $destinationFolder -Recurse -verbose
- }
- displayName: '${{ parameters.buildPrefixName }} - Prepare files to be signed'
-
-- template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\toBeSigned
- signOutputPath: $(System.ArtifactsDirectory)\signed
- certificateId: "$(AUTHENTICODE_CERT)"
- pattern: |
- **\*.dll
- **\*.psd1
- **\*.psm1
- **\*.ps1xml
- **\*.ps1
- **\*.exe
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: ${{ parameters.buildPrefixName }} - Authenticode
-
-- pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
- $signedFilesPath = '$(System.ArtifactsDirectory)\signed\'
- $BuildPath = Join-Path $(System.ArtifactsDirectory) '${{ parameters.binLocation }}'
- Write-Verbose -Verbose -Message "BuildPath: $BuildPath"
-
- Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath
- $dlls = Get-ChildItem $BuildPath\*.dll, $BuildPath\*.exe -Recurse
- $signatures = $dlls | Get-AuthenticodeSignature
- $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path
-
- Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)"
-
- $filesToSignDirectory = "$(System.ArtifactsDirectory)\thirdPartyToBeSigned"
- if (Test-Path $filesToSignDirectory) {
- Remove-Item -Path $filesToSignDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force -Verbose
-
- $signedFilesDirectory = "$(System.ArtifactsDirectory)\thirdPartySigned"
- if (Test-Path $signedFilesDirectory) {
- Remove-Item -Path $signedFilesDirectory -Recurse -Force
- }
-
- $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force -Verbose
-
- $missingSignatures | ForEach-Object {
- $pathWithoutLeaf = Split-Path $_
- $relativePath = $pathWithoutLeaf.replace($BuildPath,'')
- Write-Verbose -Verbose -Message "relativePath: $relativePath"
- $targetDirectory = Join-Path -Path $filesToSignDirectory -ChildPath $relativePath
- Write-Verbose -Verbose -Message "targetDirectory: $targetDirectory"
- if(!(Test-Path $targetDirectory))
- {
- $null = New-Item -ItemType Directory -Path $targetDirectory -Force -Verbose
- }
- Copy-Item -Path $_ -Destination $targetDirectory
- }
-
- displayName: ${{ parameters.buildPrefixName }} - Create ThirdParty Signing Folder
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
-- template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\thirdPartyToBeSigned
- signOutputPath: $(System.ArtifactsDirectory)\thirdPartySigned
- certificateId: "CP-231522"
- pattern: |
- **\*.dll
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign ThirdParty binaries
-
-- pwsh: |
- Get-ChildItem '$(System.ArtifactsDirectory)\thirdPartySigned\*'
- displayName: ${{ parameters.buildPrefixName }} - Capture ThirdParty Signed files
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
-- pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
- $signedFilesPath = '$(System.ArtifactsDirectory)\thirdPartySigned'
- $BuildPath = Join-Path $(System.ArtifactsDirectory) '${{ parameters.binLocation }}'
-
- Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath
- if ($env:BuildConfiguration -eq 'minSize') {
- ## Remove XML files when making a min-size package.
- Remove-Item "$BuildPath/*.xml" -Force
- }
- displayName: ${{ parameters.buildPrefixName }} - Merge ThirdParty signed files with Build
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
-- pwsh: |
- $uploadFolder = '$(System.ArtifactsDirectory)/${{ parameters.binLocation }}'
- $containerName = 'authenticode-signed'
-
- Write-Verbose -Verbose "File permissions after signing"
- Get-ChildItem $uploadFolder\pwsh | Select-Object -Property 'unixmode', 'size', 'name'
-
- $uploadTarFilePath = '$(System.ArtifactsDirectory)/${{ parameters.binLocation }}.tar.gz'
- Write-Verbose -Verbose -Message "Creating tar.gz - $uploadTarFilePath"
- tar -czvf $uploadTarFilePath -C $uploadFolder *
-
- Write-Host "##vso[artifact.upload containerfolder=$containerName;artifactname=$containerName]$uploadTarFilePath"
- displayName: ${{ parameters.buildPrefixName }} - Upload signed files to artifacts
- retryCountOnTaskFailure: 2
-
diff --git a/tools/releaseBuild/azureDevOps/templates/step/finalize.yml b/tools/releaseBuild/azureDevOps/templates/step/finalize.yml
deleted file mode 100644
index 72a677fec9a..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/step/finalize.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-steps:
- - pwsh: |
- throw "Jobs with an Issue will not work for release. Please fix the issue and try again."
- displayName: Check for SucceededWithIssues
- condition: eq(variables['Agent.JobStatus'],'SucceededWithIssues')
diff --git a/tools/releaseBuild/azureDevOps/templates/testartifacts.yml b/tools/releaseBuild/azureDevOps/templates/testartifacts.yml
deleted file mode 100644
index 43c09236da9..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/testartifacts.yml
+++ /dev/null
@@ -1,126 +0,0 @@
-jobs:
-- job: build_testartifacts_win
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: DotNetPrivateBuildAccess
- displayName: Build windows test artifacts
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- steps:
- - checkout: self
- clean: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(Build.SourcesDirectory)
-
- - pwsh: |
- Import-Module ./build.psm1
- Start-PSBootstrap
- displayName: Bootstrap
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- Import-Module ./build.psm1
-
- function BuildTestPackage([string] $runtime)
- {
- Write-Verbose -Verbose "Starting to build package for $runtime"
-
- New-TestPackage -Destination $(System.ArtifactsDirectory) -Runtime $runtime
-
- if (-not (Test-Path $(System.ArtifactsDirectory)/TestPackage.zip))
- {
- throw "Test Package was not found at: $(System.ArtifactsDirectory)"
- }
-
- switch ($runtime)
- {
- win7-x64 { $packageName = "TestPackage-win-x64.zip" }
- win7-x86 { $packageName = "TestPackage-win-x86.zip" }
- win-arm64 { $packageName = "TestPackage-win-arm64.zip" }
- }
-
- Rename-Item $(System.ArtifactsDirectory)/TestPackage.zip $packageName
- Write-Host "##vso[artifact.upload containerfolder=testArtifacts;artifactname=testArtifacts]$(System.ArtifactsDirectory)/$packageName"
- }
-
- BuildTestPackage -runtime win7-x64
- BuildTestPackage -runtime win7-x86
- BuildTestPackage -runtime win-arm64
-
- displayName: Build test package and upload
- retryCountOnTaskFailure: 1
-
-- job: build_testartifacts_nonwin
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - group: DotNetPrivateBuildAccess
- displayName: Build non-windows test artifacts
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMSUbuntu20.04-Secure
- steps:
- - checkout: self
- clean: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(Build.SourcesDirectory)
-
- - pwsh: |
- Import-Module ./build.psm1
- Start-PSBootstrap
- displayName: Bootstrap
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- Import-Module ./build.psm1
-
- function BuildTestPackage([string] $runtime)
- {
- Write-Verbose -Verbose "Starting to build package for $runtime"
-
- New-TestPackage -Destination $(System.ArtifactsDirectory) -Runtime $runtime
-
- if (-not (Test-Path $(System.ArtifactsDirectory)/TestPackage.zip))
- {
- throw "Test Package was not found at: $(System.ArtifactsDirectory)"
- }
-
- switch ($runtime)
- {
- linux-x64 { $packageName = "TestPackage-linux-x64.zip" }
- linux-arm { $packageName = "TestPackage-linux-arm.zip" }
- linux-arm64 { $packageName = "TestPackage-linux-arm64.zip" }
- osx-x64 { $packageName = "TestPackage-macOS.zip" }
- linux-musl-x64 { $packageName = "TestPackage-alpine-x64.zip"}
- }
-
- Rename-Item $(System.ArtifactsDirectory)/TestPackage.zip $packageName
- Write-Host "##vso[artifact.upload containerfolder=testArtifacts;artifactname=testArtifacts]$(System.ArtifactsDirectory)/$packageName"
- }
-
- BuildTestPackage -runtime linux-x64
- BuildTestPackage -runtime linux-arm
- BuildTestPackage -runtime linux-arm64
- BuildTestPackage -runtime osx-x64
- BuildTestPackage -runtime linux-musl-x64
-
- displayName: Build test package and upload
- retryCountOnTaskFailure: 1
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/upload-final-results.yml b/tools/releaseBuild/azureDevOps/templates/upload-final-results.yml
deleted file mode 100644
index 596b61fb6ed..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/upload-final-results.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-parameters:
- artifactPath:
- artifactFilter: '*'
- condition: succeeded()
- artifactName: finalResults
-
-steps:
- - powershell: |
- Get-ChildItem -Path '${{ parameters.artifactPath }}' -Recurse -File -filter '${{ parameters.artifactFilter }}' -ErrorAction SilentlyContinue |
- Select-Object -ExpandProperty FullName |
- ForEach-Object {
- Write-Host "##vso[artifact.upload containerfolder=${{ parameters.artifactName }};artifactname=${{ parameters.artifactName }}]$_"
- }
- displayName: Upload ${{ parameters.artifactName }} Artifacts ${{ parameters.artifactFilter }} from ${{ parameters.artifactPath }}
- condition: ${{ parameters.condition }}
- retryCountOnTaskFailure: 2
-
diff --git a/tools/releaseBuild/azureDevOps/templates/upload.yml b/tools/releaseBuild/azureDevOps/templates/upload.yml
deleted file mode 100644
index c745a02c2a4..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/upload.yml
+++ /dev/null
@@ -1,83 +0,0 @@
-parameters:
- architecture: x86
- version: 6.2.0
- msi: yes
- msix: yes
- pdb: no
-
-steps:
-- template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\signed
- artifactFilter: PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}*.zip
-
-- task: AzureFileCopy@4
- displayName: 'upload signed zip to Azure - ${{ parameters.architecture }}'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\signed\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.zip'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)'
- resourceGroup: '$(StorageResourceGroup)'
- condition: succeeded()
- retryCountOnTaskFailure: 2
-
-- task: AzureFileCopy@4
- displayName: 'upload signed min-size package (for Guest Config) to Azure - ${{ parameters.architecture }}'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\signed\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}-gc.zip'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)-gc'
- resourceGroup: '$(StorageResourceGroup)'
- condition: and(eq('${{ parameters.architecture }}', 'x64'), succeeded())
- retryCountOnTaskFailure: 2
-
-- template: upload-final-results.yml
- parameters:
- artifactPath: $(System.ArtifactsDirectory)\signedPackages
- artifactFilter: PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.exe
- condition: and(succeeded(), eq('${{ parameters.msi }}', 'yes'))
-
-- task: AzureFileCopy@4
- displayName: 'upload signed exe to Azure - ${{ parameters.architecture }}'
- inputs:
- SourcePath: '$(System.ArtifactsDirectory)\signedPackages\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.exe'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)-private'
- resourceGroup: '$(StorageResourceGroup)'
- condition: and(succeeded(), eq('${{ parameters.msi }}', 'yes'))
- retryCountOnTaskFailure: 2
-
-# Disable upload task as the symbols package is not currently used and we want to avoid publishing this in releases
-#- task: AzureFileCopy@4
-# displayName: 'upload pbd zip to Azure - ${{ parameters.architecture }}'
-# inputs:
-# SourcePath: '$(System.ArtifactsDirectory)\signed\PowerShell-Symbols-${{ parameters.version }}-win-${{ parameters.architecture }}.zip'
-# azureSubscription: '$(AzureFileCopySubscription)'
-# Destination: AzureBlob
-# storage: '$(StorageAccount)'
-# ContainerName: '$(AzureVersion)'
-# condition: and(succeeded(), eq('${{ parameters.pdb }}', 'yes'))
-
-- template: upload-final-results.yml
- parameters:
- artifactPath: $(Build.StagingDirectory)\signedPackages
- artifactFilter: PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.msix
- condition: and(succeeded(), eq('${{ parameters.msix }}', 'yes'))
-
-- task: AzureFileCopy@4
- displayName: 'upload signed msix to Azure - ${{ parameters.architecture }}'
- inputs:
- SourcePath: '$(Build.StagingDirectory)\signedPackages\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.msix'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)-private'
- resourceGroup: '$(StorageResourceGroup)'
- condition: and(succeeded(), eq('${{ parameters.msix }}', 'yes'), eq(variables['SHOULD_SIGN'], 'true'))
- retryCountOnTaskFailure: 2
diff --git a/tools/releaseBuild/azureDevOps/templates/vpackReleaseJob.yml b/tools/releaseBuild/azureDevOps/templates/vpackReleaseJob.yml
deleted file mode 100644
index 25517dae9c5..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/vpackReleaseJob.yml
+++ /dev/null
@@ -1,113 +0,0 @@
-parameters:
- architecture: x64
-
-jobs:
-- job: vpack_${{ parameters.architecture }}
- variables:
- - group: vPack
- - group: ReleasePipelineSecrets
-
- displayName: Build and Publish VPack - ${{ parameters.architecture }}
- condition: succeeded()
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- steps:
- - checkout: self
- clean: true
-
- - task: UseDotNet@2
- displayName: 'Use .NET Core sdk'
- inputs:
- packageType: sdk
- version: 3.1.x
- installationPath: $(Agent.ToolsDirectory)/dotnet
-
- - template: ./SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1'
- Install-AzCopy
- displayName: Install AzCopy
- retryCountOnTaskFailure: 2
-
- - pwsh: |
- Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1'
- $azcopy = Find-AzCopy
- Write-Verbose -Verbose "Found AzCopy: $azcopy"
-
- Write-Host "running: $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/PowerShell-$(Version)-win-${{ parameters.architecture }}.zip $(System.ArtifactsDirectory)"
-
- & $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/PowerShell-$(Version)-win-${{ parameters.architecture }}.zip $(System.ArtifactsDirectory)
- displayName: 'Download Azure Artifacts'
- retryCountOnTaskFailure: 2
- env:
- AZCOPY_AUTO_LOGIN_TYPE: MSI
-
- - pwsh: 'Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name'
- displayName: 'Capture Artifact Listing'
-
- - pwsh: |
- $message = @()
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object {
- if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}')
- {
- $messageInstance = "$($_.Name) is not a valid package name"
- $message += $messageInstance
- Write-Warning $messageInstance
- }
- }
-
- if($message.count -gt 0){throw ($message | out-string)}
- displayName: 'Validate Zip and MSI Package Names'
-
- - pwsh: |
- Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object {
- if($_.Name -match 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(${{ parameters.architecture }})\.(zip){1}')
- {
- $destDir = "$(System.ArtifactsDirectory)\vpack${{ parameters.architecture }}"
- $null = new-item -ItemType Directory -Path $destDir
- Expand-Archive -Path $_.FullName -DestinationPath $destDir
- $vstsCommandString = "vso[task.setvariable variable=vpackDir]$destDir"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- }
- }
- displayName: 'Extract Zip'
-
- - pwsh: |
- $vpackVersion = '$(version)'
-
- if('$(VPackPublishOverride)' -ne '' -and '$(VPackPublishOverride)' -ne 'None' )
- {
- Write-Host "Using VPackPublishOverride varabile"
- $vpackVersion = '$(VPackPublishOverride)'
- }
-
- $vstsCommandString = "vso[task.setvariable variable=vpackVersion]$vpackVersion"
- Write-Host "sending " + $vstsCommandString
- Write-Host "##$vstsCommandString"
- displayName: 'Set vpackVersion'
-
- - pwsh: |
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: Capture Environment
- condition: succeededOrFailed()
-
- - task: PkgESVPack@12
- displayName: 'Package ES - VPack '
- inputs:
- sourceDirectory: '$(vpackDir)'
- description: PowerShell ${{ parameters.architecture }} $(version)
- pushPkgName: 'PowerShell.${{ parameters.architecture }}'
- configurations: Release
- platforms: x64
- target: '$(System.ArtifactsDirectory)'
- owner: tplunk
- provData: true
- version: '$(vpackVersion)'
- vpackToken: $(vPackPat)
- condition: and(succeeded(), eq(variables['Build.Reason'], 'Manual'))
diff --git a/tools/releaseBuild/azureDevOps/templates/windows-component-governance.yml b/tools/releaseBuild/azureDevOps/templates/windows-component-governance.yml
deleted file mode 100644
index 53947655d90..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/windows-component-governance.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-
-jobs:
-- job: ComponentRegistrationJob
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- displayName: Component Registration
- condition: succeeded()
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: self
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - powershell: |
- docker container prune --force
- docker container ls --all --format '{{ json .ID }}' | ConvertFrom-Json | ForEach-Object {docker container rm --force --volumes $_}
- displayName: 'Remove all containers'
- # Cleanup is not critical it passes every time it runs
- continueOnError: true
-
- - powershell: |
- docker image ls --format '{{ json .}}'|ConvertFrom-Json| ForEach-Object {
- if($_.tag -eq '')
- {
- $formatString = 'yyyy-MM-dd HH:mm:ss zz00'
- $createdAtString = $_.CreatedAt.substring(0,$_.CreatedAt.Length -4)
- $createdAt = [DateTime]::ParseExact($createdAtString, $formatString,[System.Globalization.CultureInfo]::InvariantCulture)
- if($createdAt -lt (Get-Date).adddays(-1))
- {
- docker image rm $_.ID
- }
- }
- }
- exit 0
- displayName: 'Remove old images'
- # Cleanup is not critical it passes every time it runs
- continueOnError: true
-
- - powershell: |
- Write-verbose "--docker info---" -verbose
- docker info
- Write-verbose "--docker image ls---" -verbose
- docker image ls
- Write-verbose "--docker container ls --all---" -verbose
- docker container ls --all
- displayName: 'Capture Docker Info'
- # Diagnostics is not critical it passes every time it runs
- continueOnError: true
-
- - template: insert-nuget-config-azfeed.yml
-
- - powershell: |
- ./tools/releaseBuild/vstsbuild.ps1 -ReleaseTag $(ReleaseTagVar) -Name win-x64-component-registration
- displayName: 'Build Windows Universal - Component Registration'
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(componentregistration)'
- snapshotForceEnabled: true
diff --git a/tools/releaseBuild/azureDevOps/templates/windows-hosted-build.yml b/tools/releaseBuild/azureDevOps/templates/windows-hosted-build.yml
deleted file mode 100644
index 4b36f6f396e..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/windows-hosted-build.yml
+++ /dev/null
@@ -1,84 +0,0 @@
-parameters:
- - name: BuildConfiguration
- default: release
- - name: BuildPlatform
- default: any cpu
- - name: Architecture
- default: x64
- - name: parentJob
- default: ''
-
-jobs:
-- job: build_windows_${{ parameters.Architecture }}_${{ parameters.BuildConfiguration }}
- displayName: Build Windows - ${{ parameters.Architecture }} ${{ parameters.BuildConfiguration }}
- condition: succeeded()
- dependsOn: ${{ parameters.parentJob }}
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- variables:
- - name: runCodesignValidationInjection
- value: false
- - name: NugetSecurityAnalysisWarningLevel
- value: none
- - name: BuildConfiguration
- value: ${{ parameters.BuildConfiguration }}
- - name: BuildPlatform
- value: ${{ parameters.BuildPlatform }}
- - name: Architecture
- value: ${{ parameters.Architecture }}
- - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
- value: 1
- - group: DotNetPrivateBuildAccess
-
- steps:
-
- - checkout: self
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - template: cloneToOfficialPath.yml
-
- - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml
- parameters:
- repoRoot: $(PowerShellRoot)
-
- - pwsh: |
-
- $runtime = switch ($env:Architecture)
- {
- "x64" { "win7-x64" }
- "x86" { "win7-x86" }
- "arm64" { "win-arm64" }
- "fxdependent" { "fxdependent" }
- "fxdependentWinDesktop" { "fxdependent-win-desktop" }
- }
-
- $params = @{}
- if ($env:BuildConfiguration -eq 'minSize') {
- $params['ForMinimalSize'] = $true
- }
-
- tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 -location '$(PowerShellRoot)' -destination '$(Build.ArtifactStagingDirectory)/Symbols_$(Architecture)' -Runtime $runtime -ReleaseTag '$(ReleaseTagVar)' -Symbols @params
- displayName: 'Build Windows Universal - $(Architecture)-$(BuildConfiguration) Symbols zip'
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- $packageName = (Get-ChildItem '$(Build.ArtifactStagingDirectory)\Symbols_$(Architecture)').FullName
- $vstsCommandString = "vso[artifact.upload containerfolder=results;artifactname=results]$packageName"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- displayName: Upload symbols package
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(PowerShellRoot)\tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml b/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml
deleted file mode 100644
index 75153ce0592..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml
+++ /dev/null
@@ -1,132 +0,0 @@
-parameters:
- parentJobs: []
-
-jobs:
-- job: WinPackageSigningJob
- displayName: Windows Package signing and upload
- dependsOn:
- ${{ parameters.parentJobs }}
- condition: succeeded()
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- variables:
- - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
- value: 1
- - group: ESRP
- - name: repoFolder
- value: PowerShell
- - name: repoRoot
- value: $(Agent.BuildDirectory)\$(repoFolder)
- - name: complianceRepoFolder
- value: compliance
-
- steps:
- - checkout: self
- clean: true
- path: $(repoFolder)
-
- - checkout: ComplianceRepo
- clean: true
- path: $(complianceRepoFolder)
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - template: shouldSign.yml
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download artifacts'
- inputs:
- buildType: current
- downloadType: single
- artifactName: signed
- downloadPath: '$(System.ArtifactsDirectory)'
-
- - powershell: |
- dir "$(System.ArtifactsDirectory)\*" -Recurse
- displayName: 'Capture Downloaded Artifacts'
- # Diagnostics is not critical it passes every time it runs
- continueOnError: true
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\signed
- signOutputPath: $(Build.StagingDirectory)\signedPackages
- certificateId: $(MSIX_CERT)
- pattern: |
- **\*.msix
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign msix
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\signed
- signOutputPath: $(Build.StagingDirectory)\signedPackages
- certificateId: $(AUTHENTICODE_CERT)
- pattern: |
- **\*.exe
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign exe
-
- - powershell: |
- new-item -itemtype Directory -path '$(Build.StagingDirectory)\signedPackages'
- Get-ChildItem "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-*.msi*" | copy-item -Destination '$(Build.StagingDirectory)\signedPackages'
- displayName: 'Fake msi* Signing'
- condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true'))
-
- - pwsh: |
- Get-ChildItem "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-*.exe" | copy-item -Destination '$(Build.StagingDirectory)\signedPackages'
- displayName: 'Fake exe Signing'
- condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true'))
-
- - template: upload.yml
- parameters:
- architecture: x86
- version: $(version)
-
- - template: upload.yml
- parameters:
- architecture: x64
- version: $(version)
- pdb: yes
-
- - template: upload.yml
- parameters:
- architecture: arm64
- version: $(version)
- msi: yes
-
- - template: upload.yml
- parameters:
- architecture: fxdependent
- version: $(version)
- msi: no
- msix: no
-
- - template: upload.yml
- parameters:
- architecture: fxdependentWinDesktop
- version: $(version)
- msi: no
- msix: no
-
- - template: EsrpScan.yml@ComplianceRepo
- parameters:
- scanPath: $(Build.StagingDirectory)
- pattern: |
- **\*.msix
- **\*.msi
- **\*.zip
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(repoRoot)\tools'
- snapshotForceEnabled: true
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/templates/windows-packaging.yml b/tools/releaseBuild/azureDevOps/templates/windows-packaging.yml
deleted file mode 100644
index 915db9301ac..00000000000
--- a/tools/releaseBuild/azureDevOps/templates/windows-packaging.yml
+++ /dev/null
@@ -1,369 +0,0 @@
-parameters:
- - name: BuildConfiguration
- default: release
- - name: BuildPlatform
- default: any cpu
- - name: Architecture
- default: x64
- - name: parentJob
- default: ''
-
-jobs:
-- job: sign_windows_${{ parameters.Architecture }}_${{ parameters.BuildConfiguration }}
- displayName: Package Windows - ${{ parameters.Architecture }} ${{ parameters.BuildConfiguration }}
- condition: succeeded()
- pool:
- name: $(windowsPool)
- demands:
- - ImageOverride -equals PSMMS2019-Secure
- variables:
- - name: BuildConfiguration
- value: ${{ parameters.BuildConfiguration }}
- - name: BuildPlatform
- value: ${{ parameters.BuildPlatform }}
- - name: Architecture
- value: ${{ parameters.Architecture }}
- - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
- value: 1
- - group: ESRP
- - group: DotNetPrivateBuildAccess
-
- steps:
-
- - checkout: self
- clean: true
-
- - checkout: ComplianceRepo
- clean: true
-
- - template: SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
-
- - template: shouldSign.yml
-
- - pwsh: |
- $pkgFilter = '$(Architecture)'
- if ($env:BuildConfiguration -eq 'minSize') { $pkgFilter += '-gc' }
-
- $vstsCommandString = "vso[task.setvariable variable=PkgFilter]$pkgFilter"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- displayName: Set packageName variable
-
- - task: DownloadBuildArtifacts@0
- inputs:
- artifactName: 'results'
- itemPattern: '**/*$(PkgFilter).zip'
- downloadPath: '$(System.ArtifactsDirectory)\Symbols'
-
- - template: cloneToOfficialPath.yml
-
- - pwsh: |
- $zipPathString = '$(System.ArtifactsDirectory)\Symbols\results\*$(PkgFilter).zip'
- Write-Verbose -Verbose "Zip Path: $zipPathString"
- $zipPath = Get-Item $zipPathString
- if(@($zipPath).Count -eq 0) {
- throw "No files found at '$zipPathString'"
- }
- elseif(@($zipPath).Count -ne 1) {
- $names = $zipPath.Name -join "', '"
- throw "multiple files '${names}' found with '${zipPathString}'"
- }
-
- $expandedFolder = $zipPath.BaseName
- Write-Host "sending.. vso[task.setvariable variable=SymbolsFolder]$expandedFolder"
- Write-Host "##vso[task.setvariable variable=SymbolsFolder]$expandedFolder"
-
- Expand-Archive -Path $zipPath -Destination "$(System.ArtifactsDirectory)\$expandedFolder" -Force
- displayName: Expand symbols zip
-
- - pwsh: |
- $fullSymbolsFolder = "$(System.ArtifactsDirectory)\$($env:SYMBOLSFOLDER)"
-
- $filesToSignDirectory = "$(System.ArtifactsDirectory)\toBeSigned"
- $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force
-
- $signedFilesDirectory = "$(System.ArtifactsDirectory)\signed"
- $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force
-
- $itemsToCopyWithRecurse = @(
- "$($fullSymbolsFolder)\*.ps1"
- "$($fullSymbolsFolder)\Microsoft.PowerShell*.dll"
- )
-
- $itemsToCopy = @{
- "$($fullSymbolsFolder)\*.ps1" = ""
- "$($fullSymbolsFolder)\Microsoft.Management.Infrastructure.CimCmdlets.dll" = ""
- "$($fullSymbolsFolder)\Microsoft.WSMan.*.dll" = ""
- "$($fullSymbolsFolder)\Modules\CimCmdlets\CimCmdlets.psd1" = "Modules\CimCmdlets"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Diagnostics.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Event.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\GetEvent.types.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1" = "Modules\Microsoft.PowerShell.Diagnostics"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Host\Microsoft.PowerShell.Host.psd1" = "Modules\Microsoft.PowerShell.Host"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1" = "Modules\Microsoft.PowerShell.Management"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.psd1" = "Modules\Microsoft.PowerShell.Security"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Security.types.ps1xml" = "Modules\Microsoft.PowerShell.Security"
- "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" = "Modules\Microsoft.PowerShell.Utility"
- "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\Microsoft.WSMan.Management.psd1" = "Modules\Microsoft.WSMan.Management"
- "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\WSMan.format.ps1xml" = "Modules\Microsoft.WSMan.Management"
- "$($fullSymbolsFolder)\Modules\PSDiagnostics\PSDiagnostics.ps?1" = "Modules\PSDiagnostics"
- "$($fullSymbolsFolder)\pwsh.dll" = ""
- "$($fullSymbolsFolder)\System.Management.Automation.dll" = ""
- "$($fullSymbolsFolder)\pwsh.exe" = ""
- }
-
- $itemsToExclude = @(
- # This package is retrieved from https://www.github.com/powershell/MarkdownRender
- "$($fullSymbolsFolder)\Microsoft.PowerShell.MarkdownRender.dll"
- )
-
- Write-Verbose -verbose "recusively copying $($itemsToCopyWithRecurse | out-string) to $filesToSignDirectory"
- Copy-Item -Path $itemsToCopyWithRecurse -Destination $filesToSignDirectory -Recurse -verbose -exclude $itemsToExclude
-
- foreach($pattern in $itemsToCopy.Keys) {
- $destinationFolder = Join-Path $filesToSignDirectory -ChildPath $itemsToCopy.$pattern
- $null = New-Item -ItemType Directory -Path $destinationFolder -Force
- Write-Verbose -verbose "copying $pattern to $destinationFolder"
- Copy-Item -Path $pattern -Destination $destinationFolder -Recurse -verbose
- }
- displayName: 'Prepare files to be signed'
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\toBeSigned
- signOutputPath: $(System.ArtifactsDirectory)\signed
- certificateId: "$(AUTHENTICODE_CERT)"
- pattern: |
- **\*.dll
- **\*.psd1
- **\*.psm1
- **\*.ps1xml
- **\*.ps1
- **\*.exe
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign our binaries
-
- - pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
- $signedFilesPath = '$(System.ArtifactsDirectory)\signed\'
- $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)'
-
- Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath
- $dlls = Get-ChildItem $BuildPath\*.dll, $BuildPath\*.exe -Recurse
- $signatures = $dlls | Get-AuthenticodeSignature
- $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path
-
- Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)"
-
- $filesToSignDirectory = "$(System.ArtifactsDirectory)\thirdPartyToBeSigned"
- $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force
-
- $signedFilesDirectory = "$(System.ArtifactsDirectory)\thirdPartySigned"
- $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force
-
- $missingSignatures | ForEach-Object {
- $pathWithoutLeaf = Split-Path $_
- $relativePath = $pathWithoutLeaf.replace($BuildPath,'')
- $targetDirectory = Join-Path -Path $filesToSignDirectory -ChildPath $relativePath
- if(!(Test-Path $targetDirectory))
- {
- $null = New-Item -ItemType Directory -Path $targetDirectory -Force
- }
- Copy-Item -Path $_ -Destination $targetDirectory
- }
-
- displayName: Create ThirdParty Signing Folder
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\thirdPartyToBeSigned
- signOutputPath: $(System.ArtifactsDirectory)\thirdPartySigned
- certificateId: "CP-231522"
- pattern: |
- **\*.dll
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign ThirdParty binaries
-
- - pwsh: |
- Get-ChildItem '$(System.ArtifactsDirectory)\thirdPartySigned\*'
- displayName: Capture ThirdParty Signed files
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
- $signedFilesPath = '$(System.ArtifactsDirectory)\thirdPartySigned'
- $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)'
-
- Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath
- if ($env:BuildConfiguration -eq 'minSize') {
- ## Remove XML files when making a min-size package.
- Remove-Item "$BuildPath/*.xml" -Force
- }
- displayName: Merge ThirdParty signed files with Build
- condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
-
- - template: Sbom.yml@ComplianceRepo
- parameters:
- BuildDropPath: '$(System.ArtifactsDirectory)\$(SymbolsFolder)'
- Build_Repository_Uri: $(Github_Build_Repository_Uri)
- PackageName: PowerShell Windows ${{ parameters.Architecture }} ${{ parameters.BuildConfiguration }}
- PackageVersion: $(Version)
- sourceScanPath: '$(PowerShellRoot)\tools'
-
- - pwsh: |
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
-
- $destFolder = '$(System.ArtifactsDirectory)\signedZip'
- $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)'
-
- New-Item -ItemType Directory -Path $destFolder -Force
-
- $BuildPackagePath = New-PSBuildZip -BuildPath $BuildPath -DestinationFolder $destFolder
-
- Write-Verbose -Verbose "New-PSSignedBuildZip returned `$BuildPackagePath as: $BuildPackagePath"
- Write-Host "##vso[artifact.upload containerfolder=results;artifactname=results]$BuildPackagePath"
-
- $vstsCommandString = "vso[task.setvariable variable=BuildPackagePath]$BuildPackagePath"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- displayName: Compress signed files
- retryCountOnTaskFailure: 2
-
-
- - pwsh: |
- $runtime = switch ($env:Architecture)
- {
- "x64" { "win7-x64" }
- "x86" { "win7-x86" }
- "arm64" { "win-arm64" }
- "fxdependent" { "fxdependent" }
- "fxdependentWinDesktop" { "fxdependent-win-desktop" }
- }
-
- $signedPkg = "$(BuildPackagePath)"
- Write-Verbose -Verbose -Message "signedPkg = $signedPkg"
-
- $params = @{}
- if ($env:BuildConfiguration -eq 'minSize') {
- $params['ForMinimalSize'] = $true
- }
-
- $(PowerShellRoot)/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 -BuildZip $signedPkg -location '$(PowerShellRoot)' -destination '$(System.ArtifactsDirectory)\pkgSigned' -Runtime $runtime -ReleaseTag '$(ReleaseTagVar)' @params
- displayName: 'Build Windows Universal - $(Architecture) Package'
- env:
- __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
-
- - pwsh: |
- Get-ChildItem '$(System.ArtifactsDirectory)\pkgSigned' | ForEach-Object {
- $packagePath = $_.FullName
- Write-Host "Uploading $packagePath"
- Write-Host "##vso[artifact.upload containerfolder=signed;artifactname=signed]$packagePath"
- }
- displayName: Upload unsigned packages
- retryCountOnTaskFailure: 2
-
- - ${{ if and(ne(variables['BuildConfiguration'],'minSize'), in(variables['Architecture'], 'x64', 'x86', 'arm64')) }}:
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\pkgSigned
- signOutputPath: $(Build.StagingDirectory)\signedPackages
- certificateId: "$(AUTHENTICODE_CERT)"
- pattern: |
- **\*.msi
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign MSI
- alwaysCopy: true
-
- - pwsh: |
- Get-ChildItem '$(System.ArtifactsDirectory)\signedPackages' | ForEach-Object {
- $packagePath = $_.FullName
- Write-Host "Uploading $packagePath"
- Write-Host "##vso[artifact.upload containerfolder=finalResults;artifactname=finalResults]$packagePath"
- }
- displayName: Upload signed MSI to finalResults
- retryCountOnTaskFailure: 2
-
- - task: AzureFileCopy@4
- displayName: 'upload signed msi to Azure - ${{ parameters.architecture }}'
- inputs:
- SourcePath: '$(Build.StagingDirectory)\signedPackages\PowerShell-$(version)-win-${{ parameters.architecture }}.msi'
- azureSubscription: '$(AzureFileCopySubscription)'
- Destination: AzureBlob
- storage: '$(StorageAccount)'
- ContainerName: '$(AzureVersion)'
- resourceGroup: '$(StorageResourceGroup)'
- retryCountOnTaskFailure: 2
-
- - pwsh: |
- cd $(PowerShellRoot)
- Import-Module $(PowerShellRoot)/build.psm1 -Force
- Import-Module $(PowerShellRoot)/tools/packaging -Force
-
- $msiPath = '$(Build.StagingDirectory)\signedPackages\PowerShell-$(version)-win-${{ parameters.architecture }}.msi'
-
- New-ExePackage -ProductVersion '$(version)' -MsiLocationPath $msiPath -ProductTargetArchitecture ${{ parameters.architecture }}
- $exePath = Get-ChildItem '.\PowerShell-*.exe' | Select-Object -First 1 -ExpandProperty fullname
- $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe
- # Expand Burn Engine so we can sign it.
- Expand-ExePackageEngine -ExePath $exePath -EnginePath $enginePath
- displayName: Create exe wrapper
-
- - template: EsrpSign.yml@ComplianceRepo
- parameters:
- buildOutputPath: $(System.ArtifactsDirectory)\unsignedEngine
- signOutputPath: $(System.ArtifactsDirectory)\signedEngine
- certificateId: "$(AUTHENTICODE_CERT)"
- pattern: |
- **\*.exe
- useMinimatch: true
- shouldSign: $(SHOULD_SIGN)
- displayName: Sign Burn Engine
- alwaysCopy: true
-
- - pwsh: |
- cd '$(PowerShellRoot)'
- Import-Module '$(PowerShellRoot)/build.psm1' -Force
- Import-Module '$(PowerShellRoot)/tools/packaging' -Force
-
- $exePath = Get-ChildItem '.\PowerShell-*.exe' | Select-Object -First 1 -ExpandProperty fullname
- $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\signedEngine' -ChildPath engine.exe
- $enginePath | Get-AuthenticodeSignature | out-string | Write-Verbose -verbose
- Compress-ExePackageEngine -ExePath $exePath -EnginePath $enginePath
- displayName: Re-attach the signed Burn engine in exe wrapper
-
- - pwsh: |
- cd '$(PowerShellRoot)'
- Get-ChildItem '.\PowerShell-*.exe' | ForEach-Object {
- $packagePath = $_.FullName
- Write-Host "Uploading $packagePath"
- Write-Host "##vso[artifact.upload containerfolder=signed;artifactname=signed]$packagePath"
- }
- displayName: Upload unsigned exe
- retryCountOnTaskFailure: 2
-
- - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
- displayName: 'Component Detection'
- inputs:
- sourceScanPath: '$(PowerShellRoot)\tools'
- snapshotForceEnabled: true
-
- - pwsh: |
- if ((Test-Path "\PowerShell")) {
- Remove-Item -Path "\PowerShell" -Force -Recurse -Verbose
- }
- else {
- Write-Verbose -Verbose -Message "No cleanup required."
- }
- displayName: Clean up local Clone
- condition: always()
-
- - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml
diff --git a/tools/releaseBuild/azureDevOps/vpackRelease.yml b/tools/releaseBuild/azureDevOps/vpackRelease.yml
deleted file mode 100644
index 14368ffb8f8..00000000000
--- a/tools/releaseBuild/azureDevOps/vpackRelease.yml
+++ /dev/null
@@ -1,72 +0,0 @@
-name: vpack-$(Build.BuildId)
-trigger:
- branches:
- include:
- - master
- - release*
-pr:
- branches:
- include:
- - master
- - release*
-
-variables:
- - name: DOTNET_CLI_TELEMETRY_OPTOUT
- value: 1
- - name: POWERSHELL_TELEMETRY_OPTOUT
- value: 1
- - name: nugetMultiFeedWarnLevel
- value: none
-
- - group: Azure Blob variable group
- # adds the pat to publish the vPack
- # instructions to create are in the description of the library
- - group: vPack
-
-stages:
-- stage: prep
- displayName: Create buildInfo and name the Pipeline
- jobs:
- - job: rename
- displayName: Name the build
- condition: succeeded()
-
- pool:
- name: PowerShell1ES
- demands:
- - ImageOverride -equals PSMMS2019-Secure
-
- steps:
- - checkout: self
- clean: true
-
- - template: ./templates/SetVersionVariables.yml
- parameters:
- ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
-
- - powershell: |
- if($env:RELEASETAGVAR -match '-') {
- throw "Don't release a preview build without coordinating with Windows Engineering Build Tools Team"
- }
- displayName: Stop any preview release
-
- - powershell: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhss"))"
- displayName: Set Build Name for Non-PR
- condition: ne(variables['Build.Reason'], 'PullRequest')
-
-- stage: release
- displayName: Release
- jobs:
- - template: ./templates/vpackReleaseJob.yml
- parameters:
- architecture: x64
-
- - template: ./templates/vpackReleaseJob.yml
- parameters:
- architecture: x86
-
- - template: ./templates/vpackReleaseJob.yml
- parameters:
- architecture: arm64
diff --git a/tools/releaseBuild/build.json b/tools/releaseBuild/build.json
deleted file mode 100644
index fe2f9d96f17..00000000000
--- a/tools/releaseBuild/build.json
+++ /dev/null
@@ -1,336 +0,0 @@
-{
- "Windows": [
- {
- "Name": "win7-x64",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\DockerFile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "release",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win7-x86",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x86 -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "release",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-x64-component-registration",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_ -ComponentRegistration",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "results",
- "ArtifactsExpected": 1,
- "VariableForExtractedBinariesPath": "componentregistration",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-x64-symbols",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_ -Symbols",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "results",
- "ArtifactsExpected": 1,
- "VariableForExtractedBinariesPath": "Symbols_x64",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-x86-symbols",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x86 -ReleaseTag _ReleaseTag_ -Symbols",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "results",
- "ArtifactsExpected": 1,
- "VariableForExtractedBinariesPath": "Symbols_x86",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-arm-symbols",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm -ReleaseTag _ReleaseTag_ -Symbols",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "results",
- "ArtifactsExpected": 1,
- "VariableForExtractedBinariesPath": "Symbols_arm",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-arm64-symbols",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm64 -ReleaseTag _ReleaseTag_ -Symbols",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "results",
- "ArtifactsExpected": 1,
- "VariableForExtractedBinariesPath": "Symbols_arm64",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-x64-package",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "signed",
- "ArtifactsExpected": 4,
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-x86-package",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x86 -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "signed",
- "ArtifactsExpected": 4,
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-arm-package",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "signed",
- "ArtifactsExpected": 2,
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-arm64-package",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm64 -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "signed",
- "ArtifactsExpected": 2,
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-fxdependent-symbols",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent -ReleaseTag _ReleaseTag_ -Symbols",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "results",
- "ArtifactsExpected": 1,
- "VariableForExtractedBinariesPath": "Symbols_fxdependent",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-fxdependent-package",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "signed",
- "ArtifactsExpected": 1,
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-fxdependentWinDesktop-symbols",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent-win-desktop -ReleaseTag _ReleaseTag_ -Symbols",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "results",
- "ArtifactsExpected": 1,
- "VariableForExtractedBinariesPath": "Symbols_fxdependentWinDesktop",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "win-fxdependentWinDesktop-package",
- "RepoDestinationPath": "C:\\PowerShell",
- "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent-win-desktop -ReleaseTag _ReleaseTag_",
- "BuildDockerOptions": [
- "-m",
- "3968m"
- ],
- "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile",
- "AdditionalContextFiles" :[
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1",
- ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1"
- ],
- "DockerImageName": "ps-winsrvcore",
- "BinaryBucket": "signed",
- "ArtifactsExpected": 1,
- "EnableFeature": [ "ArtifactAsFolder" ]
- }
- ],
- "Linux": [
- {
- "Name": "deb",
- "RepoDestinationPath": "/PowerShell",
- "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_ -TarX64 -TarArm -TarArm64 -TarMinSize",
- "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_ubuntu18.04/Dockerfile",
- "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"],
- "DockerImageName": "ps-ubunutu-18-04",
- "BinaryBucket": "release",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "rpm",
- "RepoDestinationPath": "/PowerShell",
- "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_",
- "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"],
- "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_centos7/Dockerfile",
- "DockerImageName": "ps-centos-7",
- "BinaryBucket": "release",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "alpine",
- "RepoDestinationPath": "/PowerShell",
- "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_ -Alpine",
- "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"],
- "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_alpine3/Dockerfile",
- "DockerImageName": "ps-alpine-3",
- "BinaryBucket": "release",
- "EnableFeature": [ "ArtifactAsFolder" ]
- },
- {
- "Name": "fxdependent",
- "RepoDestinationPath": "/PowerShell",
- "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_ -FxDependent",
- "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"],
- "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_centos7/Dockerfile",
- "DockerImageName": "ps-centos-7",
- "BinaryBucket": "release",
- "EnableFeature": [ "ArtifactAsFolder" ]
- }
- ]
-}
diff --git a/tools/releaseBuild/createComplianceFolder.ps1 b/tools/releaseBuild/createComplianceFolder.ps1
deleted file mode 100644
index c462a09ebdb..00000000000
--- a/tools/releaseBuild/createComplianceFolder.ps1
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-param(
- [Parameter(HelpMessage="Artifact folder to find compliance files in.")]
- [string[]]
- $ArtifactFolder,
- [Parameter(HelpMessage="VSTS Variable to set path to complinance Files.")]
- [string]
- $VSTSVariableName
-)
-
-$compliancePath = $null
-foreach($folder in $ArtifactFolder)
-{
- # Find Symbols zip which contains compliance files
- Write-Host "ArtifactFolder: $folder"
- $filename = Join-Path -Path $folder -ChildPath 'symbols.zip'
-
- $parentName = Split-Path -Path $folder -Leaf
-
- # Use simplified names because some of the compliance tools didn't like the full names
- # decided not to use hashes because the names need to be consistent otherwise the tool also has issues
- # which is another problem with the full name, it includes version.
- if ($parentName -match 'x64' -or $parentName -match 'amd64')
- {
- $name = 'x64'
- }
- elseif ($parentName -match 'x86') {
- $name = 'x86'
- }
- elseif ($parentName -match 'fxdependent') {
- $name = 'fxd'
- }
- else
- {
- throw "$parentName could not be classified as x86 or x64"
- }
-
- # Throw is compliance zip does not exist
- if (!(Test-Path $filename))
- {
- throw "symbols.zip for $VSTSVariableName does not exist"
- }
-
- # make sure we have a single parent for everything
- if (!$compliancePath)
- {
- $parent = Split-Path -Path $folder
- $compliancePath = Join-Path -Path $parent -ChildPath 'compliance'
- }
-
- # Extract complance files to individual folder to avoid overwriting files.
- $unzipPath = Join-Path -Path $compliancePath -ChildPath $name
- Write-Host "Symbols-zip: $filename ; unzipPath: $unzipPath"
- Expand-Archive -Path $fileName -DestinationPath $unzipPath
-}
-
-# set VSTS variable with path to compliance files
-Write-Host "##vso[task.setvariable variable=$VSTSVariableName]$unzipPath"
diff --git a/tools/releaseBuild/generatePackgeSigning.ps1 b/tools/releaseBuild/generatePackgeSigning.ps1
deleted file mode 100644
index ff848892097..00000000000
--- a/tools/releaseBuild/generatePackgeSigning.ps1
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-param(
- [Parameter(Mandatory)]
- [string] $Path,
- [string[]] $AuthenticodeDualFiles,
- [string[]] $AuthenticodeFiles,
- [string[]] $NuPkgFiles,
- [string[]] $MacDeveloperFiles,
- [string[]] $LinuxFiles,
- [string[]] $ThirdPartyFiles,
- [string[]] $MsixFiles,
- [ValidateSet('release','preview')]
- [string] $MsixCertType = 'preview'
-)
-
-if ((!$AuthenticodeDualFiles -or $AuthenticodeDualFiles.Count -eq 0) -and
- (!$AuthenticodeFiles -or $AuthenticodeFiles.Count -eq 0) -and
- (!$NuPkgFiles -or $NuPkgFiles.Count -eq 0) -and
- (!$MacDeveloperFiles -or $MacDeveloperFiles.Count -eq 0) -and
- (!$LinuxFiles -or $LinuxFiles.Count -eq 0) -and
- (!$MsixFiles -or $MsixFiles.Count -eq 0) -and
- (!$ThirdPartyFiles -or $ThirdPartyFiles.Count -eq 0))
-{
- throw "At least one file must be specified"
-}
-
-function New-Attribute
-{
- param(
- [Parameter(Mandatory)]
- [string]$Name,
- [Parameter(Mandatory)]
- [object]$Value,
- [Parameter(Mandatory)]
- [System.Xml.XmlElement]$Element
- )
-
- $attribute = $signingXml.CreateAttribute($Name)
- $attribute.Value = $value
- $null = $fileElement.Attributes.Append($attribute)
-}
-
-function New-FileElement
-{
- param(
- [Parameter(Mandatory)]
- [string]$File,
- [Parameter(Mandatory)]
- [string]$SignType,
- [Parameter(Mandatory)]
- [System.Xml.XmlDocument]$XmlDoc,
- [Parameter(Mandatory)]
- [System.Xml.XmlElement]$Job
- )
-
- if(Test-Path -Path $file)
- {
- $name = Split-Path -Leaf -Path $File
- $fileElement = $XmlDoc.CreateElement("file")
- New-Attribute -Name 'src' -value $file -Element $fileElement
- New-Attribute -Name 'signType' -value $SignType -Element $fileElement
- New-Attribute -Name 'dest' -value "__OUTPATHROOT__\$name" -Element $fileElement
- $null = $job.AppendChild($fileElement)
- }
- else
- {
- Write-Warning -Message "Skipping $SignType; $File because it does not exist"
- }
-}
-
-[xml]$signingXml = Get-Content (Join-Path -Path $PSScriptRoot -ChildPath 'packagesigning.xml')
-$job = $signingXml.SignConfigXML.job
-
-foreach($file in $AuthenticodeDualFiles)
-{
- New-FileElement -File $file -SignType 'AuthenticodeDual' -XmlDoc $signingXml -Job $job
-}
-
-foreach($file in $AuthenticodeFiles)
-{
- New-FileElement -File $file -SignType 'AuthenticodeFormer' -XmlDoc $signingXml -Job $job
-}
-
-foreach($file in $NuPkgFiles)
-{
- New-FileElement -File $file -SignType 'NuGet' -XmlDoc $signingXml -Job $job
-}
-
-foreach ($file in $MacDeveloperFiles) {
- New-FileElement -File $file -SignType 'MacDeveloper' -XmlDoc $signingXml -Job $job
-}
-
-foreach ($file in $LinuxFiles) {
- New-FileElement -File $file -SignType 'LinuxPack' -XmlDoc $signingXml -Job $job
-}
-
-foreach ($file in $ThirdPartyFiles) {
- New-FileElement -File $file -SignType 'ThirdParty' -XmlDoc $signingXml -Job $job
-}
-
-foreach ($file in $MsixFiles) {
- # 'CP-459155' is supposed to work for the store
- # AuthenticodeFormer works for sideloading and via a workaround, through the store
- # ----------------------------------------------
- # update releasePublisher in packaging.psm1 when this is changed
- New-FileElement -File $file -SignType 'AuthenticodeFormer' -XmlDoc $signingXml -Job $job
-}
-
-$signingXml.Save($path)
-$updateScriptPath = Join-Path -Path $PSScriptRoot -ChildPath 'updateSigning.ps1'
-& $updateScriptPath -SigningXmlPath $path
diff --git a/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 b/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1
deleted file mode 100644
index acedbdd3388..00000000000
--- a/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-
-# PowerShell Script to build and package PowerShell from specified form and branch
-# Script is intented to use in Docker containers
-# Ensure PowerShell is available in the provided image
-
-param (
- # Set default location to where VSTS cloned the repository locally.
- [string] $location = $env:BUILD_REPOSITORY_LOCALPATH,
-
- # Destination location of the package on docker host
- [Parameter(Mandatory, ParameterSetName = 'packageSigned')]
- [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')]
- [Parameter(Mandatory, ParameterSetName = 'Build')]
- [string] $destination = '/mnt',
-
- [Parameter(Mandatory, ParameterSetName = 'packageSigned')]
- [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')]
- [Parameter(Mandatory, ParameterSetName = 'Build')]
- [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")]
- [ValidateNotNullOrEmpty()]
- [string]$ReleaseTag,
-
- [Parameter(ParameterSetName = 'packageSigned')]
- [Parameter(ParameterSetName = 'IncludeSymbols')]
- [Parameter(ParameterSetName = 'Build')]
- [ValidateSet("zip", "tar")]
- [string[]]$ExtraPackage,
-
- [Parameter(Mandatory, ParameterSetName = 'Bootstrap')]
- [switch] $BootStrap,
-
- [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')]
- [Parameter(Mandatory, ParameterSetName = 'Build')]
- [switch] $Build,
-
- [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')]
- [switch] $Symbols,
-
- [Parameter(Mandatory, ParameterSetName = 'packageSigned')]
- [ValidatePattern("-signed.zip$")]
- [string]$BuildZip,
-
- [Parameter(Mandatory, ParameterSetName = 'packageSigned')]
- [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')]
- [Parameter(Mandatory, ParameterSetName = 'Build')]
- [ValidateSet('osx-x64', 'osx-arm64')]
- [string]$Runtime,
-
- [string]$ArtifactName = 'result',
-
- [switch]$SkipReleaseChecks
-)
-
-$repoRoot = $location
-
-if ($Build -or $PSCmdlet.ParameterSetName -eq 'packageSigned') {
- $releaseTagParam = @{}
- if ($ReleaseTag) {
- $releaseTagParam['ReleaseTag'] = $ReleaseTag
-
- #Remove the initial 'v' from the ReleaseTag
- $version = $ReleaseTag -replace '^v'
- $semVersion = [System.Management.Automation.SemanticVersion] $version
-
- $metadata = Get-Content "$location/tools/metadata.json" -Raw | ConvertFrom-Json
-
- $LTS = $metadata.LTSRelease.Package
-
- Write-Verbose -Verbose -Message "LTS is set to: $LTS"
- }
-}
-
-Push-Location
-try {
- $pspackageParams = @{ SkipReleaseChecks = $SkipReleaseChecks; MacOSRuntime = $Runtime }
- Write-Verbose -Message "Init..." -Verbose
- Set-Location $repoRoot
- Import-Module "$repoRoot/build.psm1"
- Import-Module "$repoRoot/tools/packaging"
- Sync-PSTags -AddRemoteIfMissing
-
- if ($BootStrap) {
- Start-PSBootstrap -Package
- }
-
- if ($PSCmdlet.ParameterSetName -eq 'packageSigned') {
- Write-Verbose "Expanding signed build $BuildZip ..." -Verbose
- Expand-PSSignedBuild -BuildZip $BuildZip
-
- Remove-Item -Path $BuildZip
-
- Start-PSPackage @pspackageParams @releaseTagParam
- switch ($ExtraPackage) {
- "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam }
- }
-
- if ($LTS) {
- Start-PSPackage @pspackageParams @releaseTagParam -LTS
- switch ($ExtraPackage) {
- "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam -LTS }
- }
- }
- }
-
- if ($Build) {
- if ($Symbols) {
- Start-PSBuild -Clean -Configuration 'Release' -NoPSModuleRestore @releaseTagParam -Runtime $Runtime
- $pspackageParams['Type']='zip'
- $pspackageParams['IncludeSymbols']=$Symbols.IsPresent
- Write-Verbose "Starting powershell packaging(zip)..." -Verbose
- Start-PSPackage @pspackageParams @releaseTagParam
- } else {
- Start-PSBuild -Configuration 'Release' -PSModuleRestore @releaseTagParam -Runtime $Runtime
- Start-PSPackage @pspackageParams @releaseTagParam
- switch ($ExtraPackage) {
- "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam }
- }
-
- if ($LTS) {
- Start-PSPackage @releaseTagParam -LTS
- switch ($ExtraPackage) {
- "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam -LTS }
- }
- }
- }
- }
-} finally {
- Pop-Location
-}
-
-if ($Build -or $PSCmdlet.ParameterSetName -eq 'packageSigned') {
- $macPackages = Get-ChildItem "$repoRoot/powershell*" -Include *.pkg, *.tar.gz, *.zip
- foreach ($macPackage in $macPackages) {
- $filePath = $macPackage.FullName
- $extension = (Split-Path -Extension -Path $filePath).Replace('.', '')
- Write-Verbose "Copying $filePath to $destination" -Verbose
- Write-Host "##vso[artifact.upload containerfolder=$ArtifactName;artifactname=$ArtifactName]$filePath"
- Write-Host "##vso[task.setvariable variable=Package-$extension]$filePath"
- Copy-Item -Path $filePath -Destination $destination -Force
- }
-}
diff --git a/tools/releaseBuild/macOS/PowerShellPackageVsts.sh b/tools/releaseBuild/macOS/PowerShellPackageVsts.sh
deleted file mode 100644
index b7bfa7315d8..00000000000
--- a/tools/releaseBuild/macOS/PowerShellPackageVsts.sh
+++ /dev/null
@@ -1 +0,0 @@
-pwsh -command ".\PowerShellPackageVsts.ps1 $*"
diff --git a/tools/releaseBuild/macOS/createPowerShell.sh b/tools/releaseBuild/macOS/createPowerShell.sh
deleted file mode 100644
index 5b0b681716c..00000000000
--- a/tools/releaseBuild/macOS/createPowerShell.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-# print version for diags
-sw_vers -productVersion
-
-# create folder
-sudo mkdir /PowerShell
-
-# make the current user the owner
-sudo chown $USER /PowerShell
diff --git a/tools/releaseBuild/packagesigning.xml b/tools/releaseBuild/packagesigning.xml
deleted file mode 100644
index a243e5fbd98..00000000000
--- a/tools/releaseBuild/packagesigning.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/tools/releaseBuild/signing.xml b/tools/releaseBuild/signing.xml
deleted file mode 100644
index a6b19f6a07a..00000000000
--- a/tools/releaseBuild/signing.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tools/releaseBuild/updateSigning.ps1 b/tools/releaseBuild/updateSigning.ps1
deleted file mode 100644
index bace3aec2b7..00000000000
--- a/tools/releaseBuild/updateSigning.ps1
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-param(
- [string] $SigningXmlPath = (Join-Path -Path $PSScriptRoot -ChildPath 'signing.xml'),
- [switch] $SkipPwshExe
-)
-# Script for use in VSTS to update signing.xml
-
-if ($SkipPwshExe) {
- ## This is required for fxdependent package as no .exe is generated.
- $xmlContent = Get-Content $SigningXmlPath | Where-Object { $_ -notmatch '__INPATHROOT__\\pwsh.exe' }
-} else {
- ## We skip the global tool shim assembly for regular builds.
- $xmlContent = Get-Content $signingXmlPath | Where-Object { $_ -notmatch '__INPATHROOT__\\Microsoft.PowerShell.GlobalTool.Shim.dll' }
-}
-
-# Parse the signing xml
-$signingXml = [xml] $xmlContent
-
-# Get any variables to updating 'signType' in the XML
-# Define a varabile named `SignType' in VSTS to updating that signing type
-# Example: $env:AuthenticodeSignType='newvalue'
-# will cause all files with the 'Authenticode' signtype to be updated with the 'newvalue' signtype
-$signTypes = @{}
-Get-ChildItem -Path env:/*SignType | ForEach-Object -Process {
- $signType = $_.Name.ToUpperInvariant().Replace('SIGNTYPE','')
- Write-Host "Found SigningType $signType with value $($_.value)"
- $signTypes[$signType] = $_.Value
-}
-
-# examine each job in the xml
-$signingXml.SignConfigXML.job | ForEach-Object -Process {
- # examine each file in the job
- $_.file | ForEach-Object -Process {
- # if the sign type is one of the variables we found, update it to the new value
- $signType = $_.SignType.ToUpperInvariant()
- if($signTypes.ContainsKey($signType))
- {
- $newSignType = $signTypes[$signType]
- Write-Host "Updating $($_.src) to $newSignType"
- $_.signType = $newSignType
- }
- }
-}
-
-$signingXml.Save($signingXmlPath)
diff --git a/tools/releaseBuild/vstsbuild.ps1 b/tools/releaseBuild/vstsbuild.ps1
deleted file mode 100644
index 1c2d740c418..00000000000
--- a/tools/releaseBuild/vstsbuild.ps1
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-[cmdletbinding(DefaultParameterSetName='Build')]
-param(
- [Parameter(ParameterSetName='packageSigned')]
- [Parameter(ParameterSetName='Build')]
- [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")]
- [string]$ReleaseTag,
-
- # full paths to files to add to container to run the build
- [Parameter(Mandatory,ParameterSetName='packageSigned')]
- [string]
- $BuildPath,
-
- [Parameter(Mandatory,ParameterSetName='packageSigned')]
- [string]
- $SignedFilesPath
-)
-
-DynamicParam {
- # Add a dynamic parameter '-Name' which specifies the name of the build to run
-
- # Get the names of the builds.
- $buildJsonPath = (Join-Path -Path $PSScriptRoot -ChildPath 'build.json')
- $build = Get-Content -Path $buildJsonPath | ConvertFrom-Json
- $names = @($build.Windows.Name)
- foreach($name in $build.Linux.Name)
- {
- $names += $name
- }
-
- # Create the parameter attributs
- $ParameterAttr = New-Object "System.Management.Automation.ParameterAttribute"
- $ValidateSetAttr = New-Object "System.Management.Automation.ValidateSetAttribute" -ArgumentList $names
- $Attributes = New-Object "System.Collections.ObjectModel.Collection``1[System.Attribute]"
- $Attributes.Add($ParameterAttr) > $null
- $Attributes.Add($ValidateSetAttr) > $null
-
- # Create the parameter
- $Parameter = New-Object "System.Management.Automation.RuntimeDefinedParameter" -ArgumentList ("Name", [string], $Attributes)
- $Dict = New-Object "System.Management.Automation.RuntimeDefinedParameterDictionary"
- $Dict.Add("Name", $Parameter) > $null
- return $Dict
-}
-
-Begin {
- $Name = $PSBoundParameters['Name']
-}
-
-End {
- $ErrorActionPreference = 'Stop'
-
- $additionalFiles = @()
- $buildPackageName = $null
- # If specified, Add package file to container
- if ($BuildPath)
- {
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\..\build.psm1')
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\packaging')
-
- # Use temp as destination if not running in VSTS
- $destFolder = $env:temp
- if($env:BUILD_STAGINGDIRECTORY)
- {
- # Use artifact staging if running in VSTS
- $destFolder = $env:BUILD_STAGINGDIRECTORY
- }
-
- $BuildPackagePath = New-PSSignedBuildZip -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath -DestinationFolder $destFolder
- Write-Verbose -Verbose "New-PSSignedBuildZip returned `$BuildPackagePath as: $BuildPackagePath"
- Write-Host "##vso[artifact.upload containerfolder=results;artifactname=results]$BuildPackagePath"
- $buildPackageName = Split-Path -Path $BuildPackagePath -Leaf
- $additionalFiles += $BuildPackagePath
- }
-
- $psReleaseBranch = 'master'
- $psReleaseFork = 'PowerShell'
- $location = Join-Path -Path $PSScriptRoot -ChildPath 'PSRelease'
- if(Test-Path $location)
- {
- Remove-Item -Path $location -Recurse -Force
- }
-
- $gitBinFullPath = (Get-Command -Name git).Source
- if (-not $gitBinFullPath)
- {
- throw "Git is required to proceed. Install from 'https://git-scm.com/download/win'"
- }
-
- Write-Verbose "cloning -b $psReleaseBranch --quiet https://github.com/$psReleaseFork/PSRelease.git" -Verbose
- & $gitBinFullPath clone -b $psReleaseBranch --quiet https://github.com/$psReleaseFork/PSRelease.git $location
-
- Push-Location -Path $PWD.Path
-
- $unresolvedRepoRoot = Join-Path -Path $PSScriptRoot '../..'
- $resolvedRepoRoot = (Resolve-Path -Path $unresolvedRepoRoot).ProviderPath
-
- try
- {
- Write-Verbose "Starting build at $resolvedRepoRoot ..." -Verbose
- Import-Module "$location/vstsBuild" -Force
- Import-Module "$location/dockerBasedBuild" -Force
- Clear-VstsTaskState
-
- $buildParameters = @{
- ReleaseTag = $ReleaseTag
- BuildPackageName = $buildPackageName
- }
-
- Invoke-Build -RepoPath $resolvedRepoRoot -BuildJsonPath './tools/releaseBuild/build.json' -Name $Name -Parameters $buildParameters -AdditionalFiles $AdditionalFiles
- }
- catch
- {
- Write-VstsError -Error $_
- }
- finally{
- Write-VstsTaskState
- exit 0
- }
-}
diff --git a/tools/releaseBuild/vstsbuild.sh b/tools/releaseBuild/vstsbuild.sh
deleted file mode 100644
index d7d0363745f..00000000000
--- a/tools/releaseBuild/vstsbuild.sh
+++ /dev/null
@@ -1 +0,0 @@
-pwsh -command ".\vstsbuild.ps1 $*"
diff --git a/tools/releaseTools.psm1 b/tools/releaseTools.psm1
index 1a7cd955210..b034e2863dd 100644
--- a/tools/releaseTools.psm1
+++ b/tools/releaseTools.psm1
@@ -151,13 +151,20 @@ function Get-ChangeLog
[Parameter(Mandatory = $true)]
[string]$ThisReleaseTag,
- [Parameter(Mandatory)]
+ [Parameter(Mandatory = $false)]
[string]$Token,
[Parameter()]
[switch]$HasCherryPick
)
+ if(-not $Token) {
+ $Token = Get-GHDefaultAuthToken
+ if(-not $Token) {
+ throw "No GitHub Auth Token provided"
+ }
+ }
+
$tag_hash = git rev-parse "$LastReleaseTag^0"
$format = '%H||%P||%aN||%aE||%s'
$header = @{"Authorization"="token $Token"}
@@ -361,6 +368,29 @@ function Get-ChangeLog
Write-Output "[${version}]: https://github.com/PowerShell/PowerShell/compare/${LastReleaseTag}...${ThisReleaseTag}`n"
}
+function Get-GHDefaultAuthToken {
+ $IsGHCLIInstalled = $false
+ if (Get-command -CommandType Application -Name gh -ErrorAction SilentlyContinue) {
+ $IsGHCLIInstalled = $true
+ } else {
+ Write-Error -Message "GitHub CLI is not installed. Please install it from https://cli.github.com/" -ErrorAction Stop
+ }
+
+ if ($IsGHCLIInstalled) {
+ try {
+ $Token = & gh auth token
+ } catch {
+ Write-Error -Message "Please login to GitHub CLI using 'gh auth login'"
+ }
+ }
+
+ if (-not $Token) {
+ $Token = Read-Host -Prompt "Enter GitHub Auth Token"
+ }
+
+ return $Token
+}
+
function PrintChangeLog($clSection, $sectionTitle, [switch] $Compress) {
if ($clSection.Count -gt 0) {
"### $sectionTitle`n"