Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions eng/pipelines/common/templates/jobs/publish-packages-job.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#################################################################################
# Licensed to the .NET Foundation under one or more agreements. #
# The .NET Foundation licenses this file to you under the MIT license. #
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
# Approval aliases for manual validation before publishing packages
- name: approvalAliases
type: string
default: '[ADO.Net]\\SqlClient Admins'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should be locked down. In what situation would we want to allow non-admins to approve?


# Where to publish the packages: 'Internal' or 'Public' feed
- name: publishDestination
type: string

# Boolean value to indicate whether to perform a dry run or actual publish
- name: dryRun
type: boolean

# Boolean value to indicate if the build is a preview release build
- name: isPreview
type: boolean

# Internal feed source URL for publishing packages to Azure DevOps Feed
- name: internalFeedSource
type: string

# Public NuGet source URL for publishing packages to public feed
- name: publicNuGetSource
type: string

# Boolean value to indicate whether to publish symbols
- name: publishSymbols
type: boolean

# Name of the folder containing the packages to be published
- name: packageFolderName
type: string

# NuGet package version to be published
- name: nugetPackageVersion
type: string

# Product name associated with the packages
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
- name: product
type: string

jobs:
- job: AwaitApproval
displayName: 'Await Release Approval'
pool: server
steps:
- task: ManualValidation@0
displayName: 'Manual Approval'
timeoutInMinutes: 4320 # 3 days
inputs:
notifyUsers: ${{ parameters.approvalAliases }}
instructions: |
Release Checklist:
* Destination: ${{ parameters.publishDestination }}
* Preview build: ${{ parameters.isPreview }}
* Dry run: ${{ parameters.dryRun }}
* Symbols: ${{ parameters.publishSymbols }}
* NuGet package version: ${{ parameters.nugetPackageVersion }}
* Product: ${{ parameters.product }}
Approve to continue or Reject to abort.

- job: PublishPackages
displayName: 'Publish Packages'
variables:
- targetDownloadPath: '$(Pipeline.Workspace)/release/packages'
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
dependsOn: AwaitApproval
Comment thread
paulmedynski marked this conversation as resolved.
Outdated
condition: succeeded()
pool:
vmImage: 'ubuntu-latest'
steps:
- task: DownloadPipelineArtifact@2
displayName: 'Download Signed Packages'
inputs:
buildType: current
artifactName: ${{ parameters.packageFolderName }}
targetPath: ${{ variables.targetDownloadPath }}
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
- script: |
Comment thread
paulmedynski marked this conversation as resolved.
Outdated
echo "NuGet Package Version: ${{ parameters.nugetPackageVersion }}"
echo "Downloaded signed packages to: ${{ variables.targetDownloadPath }}"
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
displayName: 'Echo NuGet Package Version'
# Push to Internal Feed if publishDestination is not 'Public'
- ${{ if ne(parameters.publishDestination, 'Public') }}:
- template: ../steps/publish-internal-feed-step.yml
parameters:
dryRun: ${{ parameters.dryRun }}
internalFeedSource: ${{ parameters.internalFeedSource }}
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
packagesGlob: ${{ variables.targetDownloadPath }}/*.nupkg
# Push to Public NuGet Feed if publishDestination is 'Public'
- ${{ if eq(parameters.publishDestination, 'Public') }}:
Comment thread
paulmedynski marked this conversation as resolved.
Outdated
- template: ../steps/publish-public-nuget-step.yml
parameters:
dryRun: ${{ parameters.dryRun }}
publicNuGetSource: ${{ parameters.publicNuGetSource }}
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
packagesGlob: ${{ variables.targetDownloadPath }}/*.nupkg
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
# Publish Symbols if publishSymbols is true and is not a dry run
- ${{ if and(parameters.publishSymbols, ne(parameters.dryRun, true)) }}:
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
- template: ../steps/publish-symbols-step.yml
parameters:
publishSymbols: ${{ parameters.publishSymbols }}
symbolsArtifactName: ${{ parameters.product }}_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_${{ parameters.nugetPackageVersion }}_$(System.TimelineId)
product: ${{ parameters.product }}
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
71 changes: 71 additions & 0 deletions eng/pipelines/common/templates/stages/release-stage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#################################################################################
# Licensed to the .NET Foundation under one or more agreements. #
# The .NET Foundation licenses this file to you under the MIT license. #
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
# Boolean value to indicate whether to run the release stage
- name: runRelease
type: boolean
default: false

# Where to publish the packages: 'Internal' or 'Public' feed
- name: publishDestination
type: string

# Boolean value to indicate whether to perform a dry run or actual publish
- name: dryRun
type: boolean
default: true

# Approval aliases for manual validation before publishing packages
- name: approvalAliases
type: string

# Internal feed source URL for publishing packages to Azure DevOps Feed
- name: internalFeedSource
type: string

# Public NuGet source URL for publishing packages to public feed
- name: publicNuGetSource
type: string

# Boolean value to indicate whether to publish symbols
- name: publishSymbols
type: boolean
default: false

# Boolean value to indicate if the build is a preview release build
- name: isPreview
type: boolean

# Product name associated with the packages
- name: product
type: string

# NuGet package version to be published
- name: nugetPackageVersion
type: string

# Name of the folder containing the packages to be published
- name: packageFolderName
type: string

stages:
- stage: releaseMDS
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
displayName: 'Release (Manual)'
condition: and(succeeded(), eq(variables['Build.Reason'],'Manual'), eq(${{ parameters.runRelease }}, true))
jobs:
- template: ../jobs/publish-packages-job.yml
parameters:
approvalAliases: ${{ parameters.approvalAliases }}
publishDestination: ${{ parameters.publishDestination }}
dryRun: ${{ parameters.dryRun }}
isPreview: ${{ parameters.isPreview }}
internalFeedSource: ${{ parameters.internalFeedSource }}
publicNuGetSource: ${{ parameters.publicNuGetSource }}
publishSymbols: ${{ parameters.publishSymbols }}
packageFolderName: ${{ parameters.packageFolderName }}
nugetPackageVersion: ${{ parameters.nugetPackageVersion }}
product: ${{ parameters.product }}

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#################################################################################
# Licensed to the .NET Foundation under one or more agreements. #
# The .NET Foundation licenses this file to you under the MIT license. #
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
- name: dryRun
type: boolean
Comment thread
cheenamalhotra marked this conversation as resolved.
default: true

- name: internalFeedSource
type: string

- name: packagesGlob
type: string

steps:
- script: |
Comment thread
paulmedynski marked this conversation as resolved.
Outdated
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
pwsh ./tools/scripts/publishPackagesToFeed.ps1 `
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
-dryRun ${{ parameters.dryRun }} `
-internalFeedSource '${{ parameters.internalFeedSource }}' `
-packagesGlob '${{ parameters.packagesGlob }}'
displayName: 'Publish to Internal Feed'
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#################################################################################
# Licensed to the .NET Foundation under one or more agreements. #
# The .NET Foundation licenses this file to you under the MIT license. #
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
- name: dryRun
type: boolean
Comment thread
cheenamalhotra marked this conversation as resolved.
default: true

- name: publicNuGetSource
type: string

- name: nugetServiceConnection
type: string
default: 'ADO Nuget Org Connection'

- name: packagesGlob
type: string

steps:
- task: NuGetToolInstaller@1
Comment thread
paulmedynski marked this conversation as resolved.
Outdated
displayName: 'Install Latest Nuget'
inputs:
checkLatest: true
- script: |
echo "[DRY RUN] Listing packages targeted for push to: ${{ parameters.publicNuGetSource }}"
echo "Using glob pattern: ${{ parameters.packagesGlob }}"
# Derive directory and filename pattern from the glob for a precise find (handles nested patterns minimally)
glob='${{ parameters.packagesGlob }}'
dir="${glob%/*}"
name="${glob##*/}"
echo "Resolved directory: $dir"
echo "Filename pattern: $name"
if [ -d "$dir" ]; then
echo "Matched files:" || true
# Print all matched files to identify what would be pushed
find "$dir" -type f -name "$name" -print || true
else
echo "Directory does not exist yet: $dir"
fi
displayName: 'Dry Run - List Packages'
condition: and(succeeded(), eq(${{ parameters.dryRun }}, true))
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated

- task: NuGetCommand@2
displayName: 'Push to Nuget.org'
condition: and(succeeded(), eq(${{ parameters.dryRun }}, false))
Comment thread
cheenamalhotra marked this conversation as resolved.
Outdated
inputs:
command: push
packagesToPush: '${{ parameters.packagesGlob }}'
nuGetFeedType: external
publishFeedCredentials: '${{ parameters.nugetServiceConnection }}'
Loading
Loading