Skip to content

Conversation

@cheenamalhotra
Copy link
Member

@cheenamalhotra cheenamalhotra commented Nov 13, 2025

Description

Adds a manual, parameter‑gated release stage to the signing pipeline enabling:

  • Internal or public NuGet publish (publishDestination)
  • Dry run preview (dryRun)
  • Optional symbol publishing (MDS only)
  • Human approval checklist (destination, preview, dry run, symbols, version, product)

Next Steps:

  • Run Dryrun and Approval workflow to validate changes ensuring configuration is up-to-date.
  • Make an attempt to publish MDS packages to internal feed.
  • Validate workflows for all 3 packages: MDS, MSS, AKV

Investigate:

  • Can symbols be published using the same "compound-publish-symbols-step" for AKV and MSS packages?

@cheenamalhotra cheenamalhotra requested a review from a team as a code owner November 13, 2025 00:29
Copilot AI review requested due to automatic review settings November 13, 2025 00:29
Copy link
Contributor

Copilot AI left a 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

Copilot AI review requested due to automatic review settings November 13, 2025 05:01
Copy link
Contributor

Copilot AI left a 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.

@paulmedynski paulmedynski self-assigned this Nov 13, 2025
Copilot AI review requested due to automatic review settings December 11, 2025 07:24
Copy link
Contributor

Copilot AI left a 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.

Copilot AI review requested due to automatic review settings December 11, 2025 07:39
Copy link
Contributor

Copilot AI left a 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.

Copilot AI review requested due to automatic review settings December 11, 2025 08:00
@cheenamalhotra cheenamalhotra added this to the 7.0.0-preview4 milestone Dec 11, 2025
Copy link
Contributor

Copilot AI left a 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.

Copilot AI review requested due to automatic review settings December 11, 2025 08:34
Copy link
Contributor

Copilot AI left a 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.

Copy link
Contributor

Copilot AI left a 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
Copy link

Copilot AI Dec 11, 2025

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.

Suggested change
# Date: 10-12-2025
# Date: 12-Dec-2025

Copilot uses AI. Check for mistakes.
- task: PowerShell@2
displayName: Publish to Internal Feed
pwsh: true
filePath: /tools/scripts/publishPackagesToFeed.ps1
Copy link

Copilot AI Dec 11, 2025

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.

Suggested change
filePath: /tools/scripts/publishPackagesToFeed.ps1
filePath: $(Build.SourcesDirectory)/tools/scripts/publishPackagesToFeed.ps1

Copilot uses AI. Check for mistakes.
parameters:
publishSymbols: ${{ parameters.publishSymbols }}
symbolsArtifactName: ${{ parameters.product }}_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_${{ parameters.nugetPackageVersion }}_$(System.TimelineId)
product: ${{ parameters.product }}
Copy link

Copilot AI Dec 11, 2025

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.

Suggested change
product: ${{ parameters.product }}
product: ${{ parameters.product }}
referenceType: 'branch'

Copilot uses AI. Check for mistakes.
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)) }}:
Copy link

Copilot AI Dec 11, 2025

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)).

Suggested change
- ${{ if and(parameters.publishSymbols, not(parameters.dryRun)) }}:
- ${{ if and(eq(parameters.publishSymbols, true), not(eq(parameters.dryRun, true))) }}:

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +100
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))
Copy link

Copilot AI Dec 11, 2025

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.

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +100
condition: and(succeeded(), eq(parameters.publishSymbols, true))
- task: AzureCLI@2
displayName: "Publish MDS symbols"
condition: and(succeeded(), eq(parameters.publishSymbols, true))
Copy link

Copilot AI Dec 11, 2025

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.

Suggested change
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"

Copilot uses AI. Check for mistakes.
type: string

stages:
- stage: Release ${{ parameters.product }}
Copy link

Copilot AI Dec 11, 2025

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.

Suggested change
- stage: Release ${{ parameters.product }}
- stage: Release_${{ parameters.product }}

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +31
pwsh: true
filePath: /tools/scripts/publishPackagesToFeed.ps1
arguments: >
-dryRun ${{ parameters.dryRun }}
-internalFeedSource '${{ parameters.internalFeedSource }}'
-packagesGlob '${{ parameters.packagesGlob }}'
Copy link

Copilot AI Dec 11, 2025

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.

Suggested change
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 }}'

Copilot uses AI. Check for mistakes.
- task: PowerShell@2
displayName: Publish to Internal Feed
pwsh: true
filePath: /tools/scripts/publishPackagesToFeed.ps1
Copy link

Copilot AI Dec 11, 2025

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".

Suggested change
filePath: /tools/scripts/publishPackagesToFeed.ps1
filePath: /tools/scripts/publishPackagesToAzDOFeed.ps1

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants