diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index cefb49abbee..62b6a78ff19 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -156,7 +156,7 @@ extends: parameters: jobName: "LinuxSDK" displayName: "Linux SDK Validation" - imageName: PSMMSUbuntu20.04-Secure + imageName: PSMMSUbuntu22.04-Secure poolName: $(ubuntuPool) - stage: gbltool @@ -358,7 +358,7 @@ extends: This is typically done by the community 1-2 days after the release. - stage: PublishMsix - dependsOn: + dependsOn: - setReleaseTagAndChangelog - PushGitTagAndMakeDraftPublic displayName: Publish MSIX to store @@ -440,4 +440,4 @@ extends: displayName: Delete release branch jobName: DeleteBranch instructions: | - Delete release + Delete release \ No newline at end of file diff --git a/.pipelines/store/SBConfig.json b/.pipelines/store/SBConfig.json index 002333cba1d..a52d60b045f 100644 --- a/.pipelines/store/SBConfig.json +++ b/.pipelines/store/SBConfig.json @@ -4,7 +4,9 @@ "packageParameters": { "PDPRootPath": "", "Release": "", - "PDPInclude": [], + "PDPInclude": [ + "PDP.xml" + ], "PDPExclude": [], "LanguageExclude": [ "default", @@ -21,7 +23,7 @@ }, "appSubmission": { "productId": "", - "targetPublishMode": "NotSet", + "targetPublishMode": "Immediate", "targetPublishDate": null, "visibility": "NotSet", "pricing": { diff --git a/.pipelines/templates/package-create-msix.yml b/.pipelines/templates/package-create-msix.yml index 3448faaec51..4b3b79b65ee 100644 --- a/.pipelines/templates/package-create-msix.yml +++ b/.pipelines/templates/package-create-msix.yml @@ -13,6 +13,10 @@ jobs: - group: msixTools - group: 'Azure Blob variable group' - group: 'Store Publish Variables' + - name: ob_sdl_credscan_suppressionsFile + value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' @@ -145,16 +149,19 @@ jobs: 'LTS' = @{ AppStoreName = 'PowerShell-LTS' ProductId = '$(productId-LTS)' + AppId = '$(AppID-LTS)' ServiceEndpoint = "StoreAppPublish-Stable" } 'Stable' = @{ AppStoreName = 'PowerShell' ProductId = '$(productId-Stable)' + AppId = '$(AppID-Stable)' ServiceEndpoint = "StoreAppPublish-Stable" } 'Preview' = @{ AppStoreName = 'PowerShell (Preview)' ProductId = '$(productId-Preview)' + AppId = '$(AppID-Preview)' ServiceEndpoint = "StoreAppPublish-Preview" } } @@ -179,16 +186,21 @@ jobs: [xml]$pdpXml = Get-Content $pdpPath -Raw - $appStoreNameElement = $pdpXml.SelectSingleNode("//AppStoreName[@_locID]") + # Create namespace manager for XML with default namespace + $nsManager = New-Object System.Xml.XmlNamespaceManager($pdpXml.NameTable) + $nsManager.AddNamespace("pd", "http://schemas.microsoft.com/appx/2012/ProductDescription") + + $appStoreNameElement = $pdpXml.SelectSingleNode("//pd:AppStoreName", $nsManager) if ($appStoreNameElement) { - $appStoreNameElement.InnerText = $config.AppStoreName - Write-Verbose -Verbose "Updated AppStoreName to: $($config.AppStoreName)" + $appStoreNameElement.SetAttribute("_locID", $config.AppStoreName) + Write-Verbose -Verbose "Updated AppStoreName _locID to: $($config.AppStoreName)" } else { Write-Warning "AppStoreName element not found in PDP file" } $pdpXml.Save($pdpPath) Write-Verbose -Verbose "PDP file updated successfully" + Get-Content -Path $pdpPath | Write-Verbose -Verbose } else { Write-Error "PDP file not found: $pdpPath" exit 1 @@ -206,6 +218,7 @@ jobs: $sbConfigJson | ConvertTo-Json -Depth 100 | Set-Content $sbConfigPath -Encoding UTF8 Write-Verbose -Verbose "SBConfig file updated successfully" + Get-Content -Path $sbConfigPath | Write-Verbose -Verbose } else { Write-Error "SBConfig file not found: $sbConfigPath" exit 1 @@ -213,55 +226,24 @@ jobs: Write-Host "##vso[task.setvariable variable=ServiceConnection]$($config.ServiceEndpoint)" Write-Host "##vso[task.setvariable variable=SBConfigPath]$($sbConfigPath)" - - # These variables are used in the next tasks to determine which ServiceEndpoint to use - $ltsValue = $IsLTS.ToString().ToLower() - $stableValue = $IsStable.ToString().ToLower() - $previewValue = $IsPreview.ToString().ToLower() - - Write-Verbose -Verbose "About to set variables:" - Write-Verbose -Verbose " LTS=$ltsValue" - Write-Verbose -Verbose " STABLE=$stableValue" - Write-Verbose -Verbose " PREVIEW=$previewValue" - - Write-Host "##vso[task.setvariable variable=LTS]$ltsValue" - Write-Host "##vso[task.setvariable variable=STABLE]$stableValue" - Write-Host "##vso[task.setvariable variable=PREVIEW]$previewValue" - - Write-Verbose -Verbose "Variables set successfully" name: UpdateConfigs displayName: Update PDPs and SBConfig.json - - pwsh: | - Write-Verbose -Verbose "Checking variables after UpdateConfigs:" - Write-Verbose -Verbose "LTS=$(LTS)" - Write-Verbose -Verbose "STABLE=$(STABLE)" - Write-Verbose -Verbose "PREVIEW=$(PREVIEW)" - displayName: Debug - Check Variables - - task: MS-RDX-MRO.windows-store-publish.package-task.store-package@3 - displayName: 'Create StoreBroker Package (Preview)' - condition: eq(variables['PREVIEW'], 'true') + displayName: 'Create StoreBroker Package' inputs: - serviceEndpoint: 'StoreAppPublish-Preview' + serviceEndpoint: 'StoreAppPublish-Private' sbConfigPath: '$(SBConfigPath)' sourceFolder: '$(BundleDir)' contents: '*.msixBundle' outSBName: 'PowerShellStorePackage' - pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP' pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media' - - task: MS-RDX-MRO.windows-store-publish.package-task.store-package@3 - displayName: 'Create StoreBroker Package (Stable/LTS)' - condition: or(eq(variables['STABLE'], 'true'), eq(variables['LTS'], 'true')) - inputs: - serviceEndpoint: 'StoreAppPublish-Stable' - sbConfigPath: '$(SBConfigPath)' - sourceFolder: '$(BundleDir)' - contents: '*.msixBundle' - outSBName: 'PowerShellStorePackage' - pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP' - pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media' + - pwsh: | + Get-Item -Path "$(System.DefaultWorkingDirectory)/SBLog.txt" -ErrorAction SilentlyContinue | + Copy-Item -Destination "$(ob_outputDirectory)" -Verbose + displayName: Upload Store Failure Log + condition: failed() - pwsh: | $submissionPackageDir = "$(System.DefaultWorkingDirectory)/SBOutDir" @@ -279,4 +261,4 @@ jobs: else { Write-Error "Required files not found in $submissionPackageDir" } - displayName: 'Upload StoreBroker Package' + displayName: 'Upload StoreBroker Package' \ No newline at end of file diff --git a/.pipelines/templates/release-MSIX-Publish.yml b/.pipelines/templates/release-MSIX-Publish.yml index eb51584d9b9..4d3e0cb41c8 100644 --- a/.pipelines/templates/release-MSIX-Publish.yml +++ b/.pipelines/templates/release-MSIX-Publish.yml @@ -15,12 +15,15 @@ jobs: artifactName: drop_msixbundle_CreateMSIXBundle variables: - group: 'Store Publish Variables' + - name: LTS + value: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsLTS'] ] + - name: STABLE + value: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsStable'] ] + - name: PREVIEW + value: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsPreview'] ] - template: ./variable/release-shared.yml@self parameters: RELEASETAG: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['OutputReleaseTag.releaseTag'] ] - LTS: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsLTS'] ] - STABLE: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsStable'] ] - PREVIEW: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsPreview'] ] steps: - task: PowerShell@2 inputs: @@ -40,15 +43,14 @@ jobs: } $middleURL = '' $tagString = "$(ReleaseTag)" - if ($tagString -match '-') { + if ($tagString -match '-preview') { $middleURL = "preview" } elseif ($tagString -match '(\d+\.\d+)') { $middleURL = $matches[1] } - - $endURL = $tagString -replace '^v','' -replace '\.','' + $endURL = $tagString -replace '^v|\.', '' $message = "Changelog: https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL" Write-Verbose -Verbose "Release Notes for the Store:" Write-Verbose -Verbose "$message" @@ -64,24 +66,14 @@ jobs: inputs: targetType: inline script: | - Write-Verbose -Verbose "Channel Selection - LTS: $(LTS), Stable: $(Stable), Preview: $(Preview)" + # Convert ADO variables to PowerShell boolean variables + $IsLTS = '$(LTS)' -eq 'true' + $IsStable = '$(STABLE)' -eq 'true' + $IsPreview = '$(PREVIEW)' -eq 'true' - # Define app configurations for each channel using secret variables - $channelConfigs = @{ - 'LTS' = @{ - AppId = '$(AppID-LTS)' - ServiceEndpoint = 'StoreAppPublish-Stable' - } - 'Stable' = @{ - AppId = '$(AppID-Stable)' - ServiceEndpoint = 'StoreAppPublish-Stable' - } - 'Preview' = @{ - AppId = '$(AppID-Preview)' - ServiceEndpoint = 'StoreAppPublish-Preview' - } - } + Write-Verbose -Verbose "Channel Selection - LTS: $(LTS), Stable: $(STABLE), Preview: $(PREVIEW)" + # Determine the current channel for logging purposes $currentChannel = if ($IsLTS) { 'LTS' } elseif ($IsStable) { 'Stable' } elseif ($IsPreview) { 'Preview' } @@ -89,36 +81,17 @@ jobs: Write-Error "No valid channel detected" exit 1 } - - # Assign AppID for Store-Publish Task - $appID = $null - if ($IsLTS) { - $appID = '$(AppID-LTS)' - } - elseif ($IsStable) { - $appID = '$(AppID-Stable)' - } - else { - $appID = '$(AppID-Preview)' - } - - Write-Host "##vso[task.setvariable variable=AppID]$appID" + Write-Verbose -Verbose "Selected channel: $currentChannel" - Write-Verbose -Verbose "App ID: $($config.AppId)" - Write-Verbose -Verbose "Service Endpoint: $($config.ServiceEndpoint)" - - # Set pipeline variables for use in the store-publish task - Write-Host "##vso[task.setvariable variable=SelectedAppId]$($config.AppId)" - Write-Host "##vso[task.setvariable variable=SelectedServiceEndpoint]$($config.ServiceEndpoint)" - Write-Host "##vso[task.setvariable variable=SelectedChannel]$currentChannel" - displayName: 'Set StoreBroker Configurations' + Write-Verbose -Verbose "Conditional tasks will handle the publishing based on channel variables" + displayName: 'Validate Channel Selection' - task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3 - displayName: 'Publish StoreBroker Package (Stable/LTS)' - condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), or(eq('$(STABLE)', 'true'), eq('$(LTS)', 'true'))) + displayName: 'Publish LTS StoreBroker Package' + condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['LTS'], 'true')) inputs: - serviceEndpoint: 'StoreAppPublish-Stable' - appId: '$(AppID)' + serviceEndpoint: 'StoreAppPublish-Private' + appId: '$(AppID-LTS)' inputMethod: JsonAndZip jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json' zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip' @@ -127,14 +100,32 @@ jobs: targetPublishMode: 'Immediate' - task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3 - displayName: 'Publish StoreBroker Package (Preview)' - condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq('$(PREVIEW)', 'true')) + displayName: 'Publish Stable StoreBroker Package' + condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['STABLE'], 'true')) inputs: - serviceEndpoint: 'StoreAppPublish-Preview' - appId: '$(AppID)' + serviceEndpoint: 'StoreAppPublish-Private' + appId: '$(AppID-Stable)' inputMethod: JsonAndZip jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json' zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip' numberOfPackagesToKeep: 2 jsonZipUpdateMetadata: true targetPublishMode: 'Immediate' + + - task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3 + displayName: 'Publish Preview StoreBroker Package' + condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['PREVIEW'], 'true')) + inputs: + serviceEndpoint: 'StoreAppPublish-Private' + appId: '$(AppID-Preview)' + inputMethod: JsonAndZip + jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json' + zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip' + numberOfPackagesToKeep: 2 + jsonZipUpdateMetadata: true + targetPublishMode: 'Immediate' + + - pwsh: | + Get-Content -Path "$(System.DefaultWorkingDirectory)/SBLog.txt" -ErrorAction SilentlyContinue + displayName: Upload Store Failure Log + condition: failed() diff --git a/.pipelines/templates/release-githubNuget.yml b/.pipelines/templates/release-githubNuget.yml index 5a053514d6b..348afe66c7b 100644 --- a/.pipelines/templates/release-githubNuget.yml +++ b/.pipelines/templates/release-githubNuget.yml @@ -121,13 +121,13 @@ jobs: $middleURL = '' $tagString = "$(ReleaseTag)" Write-Verbose -Verbose "Use the following command to push the tag:" - if ($tagString -match '-') { + if ($tagString -match '-preview') { $middleURL = "preview" } elseif ($tagString -match '(\d+\.\d+)') { $middleURL = $matches[1] } - $endURL = $tagString -replace '[v\.]','' + $endURL = $tagString -replace '^v|\.', '' $message = "https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL" Write-Verbose -Verbose "git tag -a $(ReleaseTag) $env:BUILD_SOURCEVERSION -m $message" displayName: Git Push Tag Command diff --git a/.pipelines/templates/release-validate-globaltools.yml b/.pipelines/templates/release-validate-globaltools.yml index 11e124e33d6..4234087c1b1 100644 --- a/.pipelines/templates/release-validate-globaltools.yml +++ b/.pipelines/templates/release-validate-globaltools.yml @@ -43,6 +43,9 @@ jobs: - pwsh: | $repoRoot = "$(Build.SourcesDirectory)/PowerShell" + Import-Module "$repoRoot/build.psm1" -Force -Verbose + Start-PSBootstrap -Scenario Dotnet + $toolPath = New-Item -ItemType Directory "$(System.DefaultWorkingDirectory)/toolPath" | Select-Object -ExpandProperty FullName Write-Verbose -Verbose "dotnet tool list -g" @@ -75,6 +78,9 @@ jobs: - pwsh: | $repoRoot = "$(Build.SourcesDirectory)/PowerShell" + Import-Module "$repoRoot/build.psm1" -Force -Verbose + Start-PSBootstrap -Scenario Dotnet + $exeName = if ($IsWindows) { "pwsh.exe" } else { "pwsh" } $toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}" diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index 3e58101f7e3..b90dbb71d05 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -51,7 +51,10 @@ jobs: - pwsh: | $repoRoot = "$(Build.SourcesDirectory)" - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 + Import-Module "$repoRoot/build.psm1" -Force -Verbose + Start-PSBootstrap -Scenario Dotnet + + $env:DOTNET_NOLOGO=1 $localLocation = "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" $xmlElement = @" diff --git a/.pipelines/templates/windows-hosted-build.yml b/.pipelines/templates/windows-hosted-build.yml index e21d2253887..b6d64d7a96d 100644 --- a/.pipelines/templates/windows-hosted-build.yml +++ b/.pipelines/templates/windows-hosted-build.yml @@ -268,7 +268,7 @@ jobs: 'Microsoft.PowerShell.PSResourceGet' 'Microsoft.PowerShell.Archive' 'PSReadLine' - 'ThreadJob' + 'Microsoft.PowerShell.ThreadJob' ) $sourceModulePath = Join-Path '$(GlobalToolArtifactPath)' 'publish' 'PowerShell.Windows.x64' 'release' 'Modules'