From e817cf8b3cddc28121b0d9f1b6a303981b2fbdcb Mon Sep 17 00:00:00 2001 From: Justin Chung Date: Wed, 17 Jun 2026 14:30:43 -0500 Subject: [PATCH 1/3] Separate NuGet publish into its own stage after pushing the git tag Applies the intent of PowerShell/PowerShell#27316 (closed due to merge conflicts) on top of current master. - Extract NuGet publishing into a dedicated template release-Nuget.yml. - Rename release-githubNuget.yml to release-github.yml; it now only creates the GitHub release draft. - Rename stage PublishGitHubReleaseAndNuget to PublishGitHubRelease and point PushGitTagAndMakeDraftPublic at it. - Add a new PublishNugetRelease stage that runs after PushGitTagAndMakeDraftPublic so NuGet packages publish only after the git tag is pushed and the draft is made public. - Depend the NuGet stage directly on setReleaseTagAndChangelog so the OutputVersion.Version stageDependencies output variable resolves (Azure DevOps only exposes output variables to directly dependent stages); also fixed the template reference casing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .pipelines/templates/release-Nuget.yml | 59 +++++++++++++++++++ ...ase-githubNuget.yml => release-github.yml} | 55 ----------------- .../stages/PowerShell-Release-Stages.yml | 21 +++++-- 3 files changed, 76 insertions(+), 59 deletions(-) create mode 100644 .pipelines/templates/release-Nuget.yml rename .pipelines/templates/{release-githubNuget.yml => release-github.yml} (76%) diff --git a/.pipelines/templates/release-Nuget.yml b/.pipelines/templates/release-Nuget.yml new file mode 100644 index 00000000000..84866ebaddb --- /dev/null +++ b/.pipelines/templates/release-Nuget.yml @@ -0,0 +1,59 @@ +parameters: + - name: skipPublish + type: boolean + +jobs: +- job: NuGetPublish + displayName: Publish to NuGet + condition: succeeded() + pool: + type: release + os: windows + templateContext: + inputs: + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_upload_upload_packages + variables: + - template: ./variables/release-shared.yml@self + parameters: + VERSION: $[ stageDependencies.setReleaseTagAndChangelog.SetTagAndChangelog.outputs['OutputVersion.Version'] ] + + steps: + - task: PowerShell@2 + inputs: + targetType: inline + script: | + Write-Verbose -Verbose "Version: $(Version)" + Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + displayName: 'Capture Environment Variables' + + - task: PowerShell@2 + inputs: + targetType: inline + script: | + #Exclude all global tool packages. Their names start with 'PowerShell.' + $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" + Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose + + $releaseVersion = '$(Version)' + $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" + + if ($releaseVersion -notlike '*-*') { + # Copy the global tool package for stable releases + Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" + } + + Write-Verbose -Verbose "The .nupkgs below will be pushed:" + Get-ChildItem "$(Pipeline.Workspace)/release" -recurse + displayName: Download and capture nupkgs + condition: and(ne('${{ parameters.skipPublish }}', 'true'), succeeded()) + + - task: NuGetCommand@2 + displayName: 'NuGet push' + condition: and(ne('${{ parameters.skipPublish }}', 'true'), succeeded()) + inputs: + command: push + packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg' + nuGetFeedType: external + publishFeedCredentials: PowerShellNuGetOrgPush diff --git a/.pipelines/templates/release-githubNuget.yml b/.pipelines/templates/release-github.yml similarity index 76% rename from .pipelines/templates/release-githubNuget.yml rename to .pipelines/templates/release-github.yml index 27a358c7e75..424367fbf21 100644 --- a/.pipelines/templates/release-githubNuget.yml +++ b/.pipelines/templates/release-github.yml @@ -171,58 +171,3 @@ jobs: action: 'create' releaseNotesFilePath: '$(ReleaseNotesFilePath)' isPrerelease: '$(IsPreRelease)' - -- job: NuGetPublish - displayName: Publish to NuGet - condition: succeeded() - pool: - type: release - os: windows - templateContext: - inputs: - - input: pipelineArtifact - pipeline: PSPackagesOfficial - artifactName: drop_upload_upload_packages - variables: - - template: ./variables/release-shared.yml@self - parameters: - VERSION: $[ stageDependencies.setReleaseTagAndChangelog.SetTagAndChangelog.outputs['OutputVersion.Version'] ] - - steps: - - task: PowerShell@2 - inputs: - targetType: inline - script: | - Write-Verbose -Verbose "Version: $(Version)" - Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose - displayName: 'Capture Environment Variables' - - - task: PowerShell@2 - inputs: - targetType: inline - script: | - #Exclude all global tool packages. Their names start with 'PowerShell.' - $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" - Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose - - $releaseVersion = '$(Version)' - $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" - - if ($releaseVersion -notlike '*-*') { - # Copy the global tool package for stable releases - Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" - } - - Write-Verbose -Verbose "The .nupkgs below will be pushed:" - Get-ChildItem "$(Pipeline.Workspace)/release" -recurse - displayName: Download and capture nupkgs - condition: and(ne('${{ parameters.skipPublish }}', 'true'), succeeded()) - - - task: NuGetCommand@2 - displayName: 'NuGet push' - condition: and(ne('${{ parameters.skipPublish }}', 'true'), succeeded()) - inputs: - command: push - packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg' - nuGetFeedType: external - publishFeedCredentials: PowerShellNuGetOrgPush diff --git a/.pipelines/templates/stages/PowerShell-Release-Stages.yml b/.pipelines/templates/stages/PowerShell-Release-Stages.yml index 52ce428a663..06fabe1a165 100644 --- a/.pipelines/templates/stages/PowerShell-Release-Stages.yml +++ b/.pipelines/templates/stages/PowerShell-Release-Stages.yml @@ -159,21 +159,21 @@ stages: Update and merge the changelog for the release. This step is required for creating GitHub draft release. -- stage: PublishGitHubReleaseAndNuget - displayName: Publish GitHub and Nuget Release +- stage: PublishGitHubRelease + displayName: Publish GitHub dependsOn: - setReleaseTagAndChangelog - UpdateChangeLog variables: ob_release_environment: ${{ parameters.releaseEnvironment }} jobs: - - template: /.pipelines/templates/release-githubNuget.yml@self + - template: /.pipelines/templates/release-github.yml@self parameters: skipPublish: ${{ parameters.SkipPublish }} - stage: PushGitTagAndMakeDraftPublic displayName: Push Git Tag and Make Draft Public - dependsOn: PublishGitHubReleaseAndNuget + dependsOn: PublishGitHubRelease jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: @@ -190,6 +190,19 @@ stages: instructions: | Make the GitHub Release Draft Public +- stage: PublishNugetRelease + displayName: Publish Nuget Release + dependsOn: + - setReleaseTagAndChangelog + - PushGitTagAndMakeDraftPublic + - UpdateChangeLog + variables: + ob_release_environment: ${{ parameters.releaseEnvironment }} + jobs: + - template: /.pipelines/templates/release-Nuget.yml@self + parameters: + skipPublish: ${{ parameters.SkipPublish }} + - stage: BlobPublic displayName: Make Blob Public dependsOn: From 23ab58f1e79988296adc69c3476d447a94f8b73f Mon Sep 17 00:00:00 2001 From: Justin Chung Date: Wed, 17 Jun 2026 15:31:55 -0500 Subject: [PATCH 2/3] Remove Windows check --- .pipelines/templates/stages/PowerShell-Release-Stages.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.pipelines/templates/stages/PowerShell-Release-Stages.yml b/.pipelines/templates/stages/PowerShell-Release-Stages.yml index 06fabe1a165..d55463c4b07 100644 --- a/.pipelines/templates/stages/PowerShell-Release-Stages.yml +++ b/.pipelines/templates/stages/PowerShell-Release-Stages.yml @@ -100,13 +100,6 @@ stages: dependsOn: [] displayName: Manual Validation jobs: - - template: /.pipelines/templates/approvalJob.yml@self - parameters: - displayName: Validate Windows Packages - jobName: ValidateWinPkg - instructions: | - Validate zip package on windows - - template: /.pipelines/templates/approvalJob.yml@self parameters: displayName: Validate OSX Packages From ec1b1cc6272c70c202c524e7ba9908391cda5251 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:22:03 -0500 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .pipelines/templates/release-Nuget.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/templates/release-Nuget.yml b/.pipelines/templates/release-Nuget.yml index 84866ebaddb..c6ffb67e6a4 100644 --- a/.pipelines/templates/release-Nuget.yml +++ b/.pipelines/templates/release-Nuget.yml @@ -17,7 +17,7 @@ jobs: variables: - template: ./variables/release-shared.yml@self parameters: - VERSION: $[ stageDependencies.setReleaseTagAndChangelog.SetTagAndChangelog.outputs['OutputVersion.Version'] ] + VERSION: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['OutputVersion.Version'] ] steps: - task: PowerShell@2