Skip to content
Open
47 changes: 47 additions & 0 deletions eng/pipelines/common/templates/jobs/approval-job.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#################################################################################
# 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: approvalAliases
type: string
default: '[ADO.Net]\\SqlClient Admins'

- name: publishDestination
type: string

- name: dryRun
type: boolean

- name: isPreview
type: boolean

- name: publishSymbols
type: boolean

- name: nugetPackageVersion
type: string

- 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.
65 changes: 65 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,65 @@
#################################################################################
# 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: publishDestination
type: string

- name: dryRun
type: boolean

- name: internalFeedSource
type: string

- name: publicNuGetSource
type: string

- name: publishSymbols
type: boolean

- name: packageFolderName
type: string

- name: nugetPackageVersion
type: string

- name: product
type: string

jobs:
- job: PublishPackages
displayName: 'Publish Packages'
dependsOn: AwaitApproval
condition: succeeded()
pool:
vmImage: 'ubuntu-latest'
steps:
- task: DownloadPipelineArtifact@2
displayName: 'Download Signed Packages'
inputs:
buildType: current
artifactName: ${{ parameters.packageFolderName }}
targetPath: $(Pipeline.Workspace)/release/packages
- script: |
echo "NuGet Package Version: ${{ parameters.nugetPackageVersion }}"
displayName: 'Echo NuGet Package Version'
- ${{ if ne(parameters.publishDestination, 'Public') }}:
- template: ../steps/publish-internal-feed-step.yml
parameters:
dryRun: ${{ parameters.dryRun }}
internalFeedSource: ${{ parameters.internalFeedSource }}
packagesGlob: $(System.DefaultWorkingDirectory)/_dotnet-sqlclient-Official/drop_buildMDS_build_signed_package/*.nupkg
- ${{ if eq(parameters.publishDestination, 'Public') }}:
- template: ../steps/publish-public-nuget-step.yml
parameters:
dryRun: ${{ parameters.dryRun }}
publicNuGetSource: ${{ parameters.publicNuGetSource }}
packagesGlob: $(System.DefaultWorkingDirectory)/_dotnet-sqlclient-Official/drop_buildMDS_build_signed_package/*.nupkg
- ${{ if and(parameters.publishSymbols, ne(parameters.dryRun, true)) }}:
- 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 }}
66 changes: 66 additions & 0 deletions eng/pipelines/common/templates/stages/release-stage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#################################################################################
# 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: runRelease
type: boolean
default: false

- name: publishDestination
type: string

- name: dryRun
type: boolean
default: false

- name: approvalAliases
type: string

- name: internalFeedSource
type: string

- name: publicNuGetSource
type: string

- name: publishSymbols
type: boolean
default: false

- name: isPreview
type: boolean

- name: product
type: string

- name: nugetPackageVersion
type: string

- name: packageFolderName
type: string

stages:
- stage: releaseMDS
displayName: 'Release (Manual)'
condition: and(succeeded(), eq(variables['Build.Reason'],'Manual'), eq(${{ parameters.runRelease }}, true))
jobs:
- template: ../jobs/approval-job.yml
parameters:
approvalAliases: ${{ parameters.approvalAliases }}
publishDestination: ${{ parameters.publishDestination }}
dryRun: ${{ parameters.dryRun }}
isPreview: ${{ parameters.isPreview }}
publishSymbols: ${{ parameters.publishSymbols }}
nugetPackageVersion: ${{ parameters.nugetPackageVersion }}
product: ${{ parameters.product }}
- template: ../jobs/publish-packages-job.yml
parameters:
publishDestination: ${{ parameters.publishDestination }}
dryRun: ${{ parameters.dryRun }}
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,46 @@
#################################################################################
# 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

- name: internalFeedSource
type: string

- name: packagesGlob
type: string
default: '$(System.DefaultWorkingDirectory)/_dotnet-sqlclient-Official/drop_buildMDS_build_signed_package/*.nupkg'

steps:
- script: |
set -e
SRC='${{ parameters.internalFeedSource }}'
if [ -z "$SRC" ]; then
echo "Internal feed source parameter not set."
exit 1
fi
if [ "${{ parameters.dryRun }}" = "true" ]; then
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
fi
for f in $(find "${{ parameters.packagesGlob }}" -name "*.nupkg"); do
echo "Push $f"
dotnet nuget push --source "$SRC" --api-key az "$f"
done
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

- name: publicNuGetSource
type: string

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

- name: packagesGlob
type: string
default: '$(System.DefaultWorkingDirectory)/_dotnet-sqlclient-Official/drop_buildMDS_build_signed_package/*.nupkg'

steps:
- task: NuGetToolInstaller@1
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))

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