diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 36bee13a0c7..ca6b79335dd 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 @@ -365,10 +365,12 @@ extends: This is typically done by the community 1-2 days after the release. - stage: PublishMsix - dependsOn: PushGitTagAndMakeDraftPublic + dependsOn: + - setReleaseTagAndChangelog + - PushGitTagAndMakeDraftPublic displayName: Publish MSIX to store variables: - ob_release_environment: Production + ob_release_environment: ${{ variables.releaseEnvironment }} jobs: - template: /.pipelines/templates/release-MSIX-Publish.yml@self parameters: 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/channelSelection.yml b/.pipelines/templates/channelSelection.yml index 0e352ef7558..3d1f445c559 100644 --- a/.pipelines/templates/channelSelection.yml +++ b/.pipelines/templates/channelSelection.yml @@ -1,7 +1,7 @@ steps: - pwsh: | # Determine LTS, Preview, or Stable - $metadata = Get-Content "$repoRoot/tools/metadata.json" -Raw | ConvertFrom-Json + $metadata = Get-Content "$(Build.SourcesDirectory)/PowerShell/tools/metadata.json" -Raw | ConvertFrom-Json $LTS = $metadata.LTSRelease.Latest $Stable = $metadata.StableRelease.Latest $isPreview = '$(OutputReleaseTag.releaseTag)' -match '-' diff --git a/.pipelines/templates/package-create-msix.yml b/.pipelines/templates/package-create-msix.yml index 37a66362119..31621698f23 100644 --- a/.pipelines/templates/package-create-msix.yml +++ b/.pipelines/templates/package-create-msix.yml @@ -8,6 +8,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' @@ -137,16 +141,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" } } @@ -171,16 +178,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 @@ -198,20 +210,21 @@ 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 } Write-Host "##vso[task.setvariable variable=ServiceConnection]$($config.ServiceEndpoint)" - Write-Host "##vso[task.setvariable variable=SBConfigPath]$($config.SBConfigPath)" + Write-Host "##vso[task.setvariable variable=SBConfigPath]$($sbConfigPath)" name: UpdateConfigs displayName: Update PDPs and SBConfig.json - task: MS-RDX-MRO.windows-store-publish-dev.package-task.store-package@3 displayName: 'Create StoreBroker Package' inputs: - serviceEndpoint: '$(ServiceConnection)' + serviceEndpoint: 'StoreAppPublish-Private' sbConfigPath: '$(SBConfigPath)' sourceFolder: '$(BundleDir)' contents: '*.msixBundle' @@ -219,6 +232,12 @@ jobs: 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" $jsonFile = "$submissionPackageDir/PowerShellStorePackage.json" diff --git a/.pipelines/templates/release-MSIX-Publish.yml b/.pipelines/templates/release-MSIX-Publish.yml index 9a0dba8833f..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,14 +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\.]','' + $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" @@ -63,25 +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 + # Determine the current channel for logging purposes $currentChannel = if ($IsLTS) { 'LTS' } elseif ($IsStable) { 'Stable' } elseif ($IsPreview) { 'Preview' } @@ -90,26 +82,50 @@ jobs: exit 1 } - $config = $channelConfigs[$currentChannel] 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 LTS StoreBroker Package' - condition: ne('${{ parameters.skipMSIXPublish }}', 'true') + condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['LTS'], 'true')) inputs: - serviceEndpoint: '$(SelectedServiceEndpoint)' - appId: '$(SelectedAppId)' + serviceEndpoint: 'StoreAppPublish-Private' + appId: '$(AppID-LTS)' 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 Stable StoreBroker Package' + condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['STABLE'], 'true')) + inputs: + 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 a8a874619a4..5f67ce6a9e4 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 4a7d23c8b4b..8c2031d5cc9 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 4089d54e51b..3b0442f65d6 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -51,6 +51,9 @@ jobs: - pwsh: | $repoRoot = "$(Build.SourcesDirectory)" + Import-Module "$repoRoot/build.psm1" -Force -Verbose + Start-PSBootstrap -Scenario Dotnet + $env:DOTNET_NOLOGO=1 $localLocation = "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg"