-
Notifications
You must be signed in to change notification settings - Fork 317
Add Manual OneBranch Release Stage & Publish Support (Internal/Public) #3761
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a manual release stage to the OneBranch signing pipeline, enabling controlled NuGet package publishing with approval gates. The implementation supports both internal and public publishing destinations, includes dry-run capability for testing, and integrates symbol publishing for the MDS product.
Key Changes:
- Adds manual release parameters (destination, dry run, product) to the signing pipeline
- Implements approval workflow with human validation before package publication
- Creates templated release infrastructure supporting multiple products (MDS, MSS, AKV)
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| eng/pipelines/dotnet-sqlclient-signing-pipeline.yml | Adds release parameters and invokes new release-stage template |
| eng/pipelines/common/templates/stages/release-stage.yml | Defines manual release stage with approval and publish jobs |
| eng/pipelines/common/templates/jobs/approval-job.yml | Implements manual validation job with release checklist |
| eng/pipelines/common/templates/jobs/publish-packages-job.yml | Orchestrates package download and conditional publishing to internal/public feeds |
| eng/pipelines/common/templates/steps/publish-internal-feed-step.yml | Handles internal feed publishing with dry-run support |
| eng/pipelines/common/templates/steps/publish-public-nuget-step.yml | Handles NuGet.org publishing with dry-run support |
| eng/pipelines/common/templates/steps/list-packages-step.yml | Lists packages for verification before publishing |
| eng/pipelines/common/templates/steps/publish-symbols-step.yml | Updates symbol publishing to use boolean type and add AKV product support |
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-public-nuget-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-public-nuget-step.yml
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 11 comments.
eng/pipelines/common/templates/steps/publish-public-nuget-step.yml
Outdated
Show resolved
Hide resolved
eng/pipelines/common/templates/steps/publish-public-nuget-step.yml
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
eng/pipelines/common/templates/steps/publish-internal-feed-step.yml
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.
| # See the LICENSE file in the project root for more information. | ||
|
|
||
| # Script: publishPackagesToAzDOFeed.ps1 | ||
| # Date: 10-12-2025 |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The date format is inconsistent with the existing codebase convention. The file downloadLatestNuget.ps1 uses the format "07-Dec-2018" (DD-MMM-YYYY), but this file uses "10-12-2025" (MM-DD-YYYY). Use the established format for consistency.
| # Date: 10-12-2025 | |
| # Date: 12-Dec-2025 |
| - task: PowerShell@2 | ||
| displayName: Publish to Internal Feed | ||
| pwsh: true | ||
| filePath: /tools/scripts/publishPackagesToFeed.ps1 |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The script path uses an absolute path "/tools/scripts/publishPackagesToFeed.ps1" which will fail. The path should be relative to the repository root, such as "$(Build.SourcesDirectory)/tools/scripts/publishPackagesToAzDOFeed.ps1" or use a relative path.
| filePath: /tools/scripts/publishPackagesToFeed.ps1 | |
| filePath: $(Build.SourcesDirectory)/tools/scripts/publishPackagesToFeed.ps1 |
| parameters: | ||
| publishSymbols: ${{ parameters.publishSymbols }} | ||
| symbolsArtifactName: ${{ parameters.product }}_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_${{ parameters.nugetPackageVersion }}_$(System.TimelineId) | ||
| product: ${{ parameters.product }} |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a required parameter in the publish-symbols-step template. According to the template definition, "referenceType" is a required parameter but it's not being passed in this invocation. Add the referenceType parameter to match the expected interface.
| product: ${{ parameters.product }} | |
| product: ${{ parameters.product }} | |
| referenceType: 'branch' |
| internalFeedSource: ${{ parameters.internalFeedSource }} | ||
| packagesGlob: ${{ variables.targetDownloadPath }}/*.nupkg | ||
| # Publish Symbols if publishSymbols is true and is not a dry run | ||
| - ${{ if and(parameters.publishSymbols, not(parameters.dryRun)) }}: |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition on line 103 uses not(parameters.dryRun) which will be evaluated at compile time. However, dryRun is a pipeline parameter that could be set at queue time. The condition should use runtime variable evaluation: not(eq(${{ parameters.dryRun }}, true)).
| - ${{ if and(parameters.publishSymbols, not(parameters.dryRun)) }}: | |
| - ${{ if and(eq(parameters.publishSymbols, true), not(eq(parameters.dryRun, true))) }}: |
| condition: and(succeeded(), eq(parameters.publishSymbols, true)) | ||
|
|
||
| - ${{ if and(eq(parameters.publishSymbols, true), eq(parameters.product, 'MDS')) }}: | ||
| - task: PublishSymbols@2 | ||
| displayName: "Upload MDS symbols to ${{parameters.SymAccount }} org" | ||
| inputs: | ||
| SymbolsFolder: '$(Build.SourcesDirectory)\artifacts\${{parameters.referenceType }}\bin' | ||
| SearchPattern: | | ||
| Windows_NT/${{ parameters.buildConfiguration }}.AnyCPU/**/Microsoft.Data.SqlClient.pdb | ||
| Unix/${{ parameters.buildConfiguration }}.AnyCPU/**/Microsoft.Data.SqlClient.pdb | ||
| IndexSources: false | ||
| SymbolServerType: TeamServices | ||
| SymbolsMaximumWaitTime: 60 | ||
| SymbolExpirationInDays: 1825 # 5 years | ||
| SymbolsProduct: Microsoft.Data.SqlClient | ||
| SymbolsVersion: ${{parameters.symbolsVersion }} | ||
| SymbolsArtifactName: ${{parameters.symbolsArtifactName }} | ||
| Pat: $(System.AccessToken) | ||
| condition: and(succeeded(), eq(parameters.publishSymbols, true)) | ||
| - task: AzureCLI@2 | ||
| displayName: "Publish MDS symbols" | ||
| condition: and(succeeded(), eq(parameters.publishSymbols, true)) |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition syntax is inconsistent. Line 79 uses string comparison with quotes eq(parameters.publishSymbols, true), but line 97 and 100 use the same format. For boolean parameters, the condition should use eq(${{ parameters.publishSymbols }}, true) without the $ prefix when already in a compile-time expression context, or simply use the boolean directly.
| condition: and(succeeded(), eq(parameters.publishSymbols, true)) | ||
| - task: AzureCLI@2 | ||
| displayName: "Publish MDS symbols" | ||
| condition: and(succeeded(), eq(parameters.publishSymbols, true)) |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compile-time conditional on line 81 checks both publishSymbols and product, but the nested tasks on lines 97 and 100 have runtime conditions that check publishSymbols again. This is redundant since the tasks are already inside a compile-time conditional that ensures publishSymbols is true. Remove the redundant runtime conditions on lines 97 and 100.
| condition: and(succeeded(), eq(parameters.publishSymbols, true)) | |
| - task: AzureCLI@2 | |
| displayName: "Publish MDS symbols" | |
| condition: and(succeeded(), eq(parameters.publishSymbols, true)) | |
| - task: AzureCLI@2 | |
| displayName: "Publish MDS symbols" |
| type: string | ||
|
|
||
| stages: | ||
| - stage: Release ${{ parameters.product }} |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stage name contains a space which may cause issues with Azure DevOps pipeline stage identification. Stage names should use underscores or be quoted. Change to "Release_${{ parameters.product }}" or wrap in quotes.
| - stage: Release ${{ parameters.product }} | |
| - stage: Release_${{ parameters.product }} |
| pwsh: true | ||
| filePath: /tools/scripts/publishPackagesToFeed.ps1 | ||
| arguments: > | ||
| -dryRun ${{ parameters.dryRun }} | ||
| -internalFeedSource '${{ parameters.internalFeedSource }}' | ||
| -packagesGlob '${{ parameters.packagesGlob }}' |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The task property "pwsh" should be under "inputs", not as a sibling to "displayName". The correct structure for PowerShell@2 task is to set "pwsh: true" within the inputs section or use "scriptType" parameter.
| pwsh: true | |
| filePath: /tools/scripts/publishPackagesToFeed.ps1 | |
| arguments: > | |
| -dryRun ${{ parameters.dryRun }} | |
| -internalFeedSource '${{ parameters.internalFeedSource }}' | |
| -packagesGlob '${{ parameters.packagesGlob }}' | |
| inputs: | |
| pwsh: true | |
| filePath: /tools/scripts/publishPackagesToFeed.ps1 | |
| arguments: > | |
| -dryRun ${{ parameters.dryRun }} | |
| -internalFeedSource '${{ parameters.internalFeedSource }}' | |
| -packagesGlob '${{ parameters.packagesGlob }}' |
| - task: PowerShell@2 | ||
| displayName: Publish to Internal Feed | ||
| pwsh: true | ||
| filePath: /tools/scripts/publishPackagesToFeed.ps1 |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filename referenced in the filePath does not match the actual filename. The filePath points to "publishPackagesToFeed.ps1" but the actual file created in this PR is "publishPackagesToAzDOFeed.ps1".
| filePath: /tools/scripts/publishPackagesToFeed.ps1 | |
| filePath: /tools/scripts/publishPackagesToAzDOFeed.ps1 |
Description
Adds a manual, parameter‑gated release stage to the signing pipeline enabling:
Next Steps:
Investigate: