Skip to content

Bump the nuget group across 1 directory with 5 updates #1510

Bump the nuget group across 1 directory with 5 updates

Bump the nuget group across 1 directory with 5 updates #1510

Workflow file for this run

name: NuGet publish
on:
workflow_dispatch:
inputs:
nuget-package-workflow-run-id:
description: 'NuGet package workflow run id: the run id of the workflow that contains the NuGet package artifact to publish. The action that creates the NuGet packages is named "Build, test and package"'
required: true
nuget-id:
description: 'NuGet id: the id of the NuGet to publish.'
required: true
nuget-version:
description: 'NuGet version: the version of the NuGet to publish.'
required: true
generate-github-release-notes:
description: 'Generate GitHub release notes: set to "true" to auto generate release notes, set to "false" otherwise.'
required: true
pull_request:
branches: [ main ]
types: [ closed ]
defaults:
run:
shell: pwsh
jobs:
workflow-args:
name: Process workflow input data
if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'nuget-release'))
permissions:
contents: read
runs-on: ubuntu-latest
env:
CUSTOM_RELEASE_NOTES_FILEPATH: './nuget-release-notes.md'
CUSTOM_RELEASE_NOTES_ARTIFACT_NAME: 'nuget-release-notes'
outputs:
issue-number: ${{ steps.nuget-publish-info.outputs.issue-number }}
nuget-package-run-id: ${{ steps.nuget-publish-info.outputs.nuget-package-run-id }}
nuget-id: ${{ steps.nuget-publish-info.outputs.nuget-id }}
nuget-version: ${{ steps.nuget-publish-info.outputs.nuget-version }}
github-release-sha: ${{ steps.nuget-publish-info.outputs.github-release-sha }}
auto-generate-release-notes: ${{ steps.nuget-publish-info.outputs.auto-generate-release-notes }}
custom-release-notes-artifact-name: ${{ env.CUSTOM_RELEASE_NOTES_ARTIFACT_NAME }}
steps:
- name: Dump github context for debug purposes
env:
GITHUB_CONTEXT: ${{ toJSON(github) }}
run: $env:GITHUB_CONTEXT
- name: Checkout repository
uses: actions/checkout@v4
- name: Get release info run id from PR
id: release-info
if: github.event_name == 'pull_request'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# This step only works if no extra commits are pushed to the release PR
# The problem is that the status that is carrying the NuGet release info is only added to the commit that opens the PR.
# This status is added by the NuGet Release workflow, see nuget-release.yml at the step with description 'Set PR status'
#
# If more commits are pushed to the NuGet release PR then this step will fail to find the status because it looks only
# at ${{ github.event.pull_request.head.sha }}, not the original commit.
#
# Passing information to the PR by means of adding a status to it is not ideal and I should rethink how this is done to properly
# fix this step
#
$statuses = gh api repos/${{ github.repository }}/commits/${{ github.event.pull_request.head.sha }}/statuses | ConvertFrom-Json
Write-Output $statuses
$nugetReleaseInfoStatus = $statuses | Where-Object {$_.context.startsWith("NuGet release / NuGet release info")}
$nugetReleaseInfoWorkflowUrl = $nugetReleaseInfoStatus.target_url
$runId = $nugetReleaseInfoWorkflowUrl.Split("/")[-1]
Write-Output "run-id=$runId"
Write-Output "run-id=$runId" >> $env:GITHUB_OUTPUT
- name: Download NuGet release info artifact from PR
uses: dawidd6/action-download-artifact@v6
if: github.event_name == 'pull_request'
with:
name: nuget-release-info
run_id: ${{ steps.release-info.outputs.run-id }}
- name: Download NuGet release notes artifact from PR
id: download-release-notes
if: github.event_name == 'pull_request'
uses: dawidd6/action-download-artifact@v6
with:
name: ${{ env.CUSTOM_RELEASE_NOTES_ARTIFACT_NAME }}
run_id: ${{ steps.release-info.outputs.run-id }}
- name: Prepare NuGet publish info
id: nuget-publish-info
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$isPullRequest = "${{ github.event_name }}" -eq 'pull_request'
if($isPullRequest) {
$nugetInfoPath = './nuget-release-info.md'
$nugetInfoJson = Get-Content $nugetInfoPath
$nugetInfo = $nugetInfoJson | ConvertFrom-Json
$issueNumber = $nugetInfo.issueNumber
$nugetId = $nugetInfo.nugetId
$nugetVersion = $nugetInfo.nugetVersion
$autoGenerateReleaseNotes = $nugetInfo.autoGenerateReleaseNotes.ToString().ToLower() # otherwise the ncipollo/release-action@v1 receives "True" and process it as false. Must be "true"
$githubReleaseSha = '${{ github.event.pull_request.merge_commit_sha }}'
# get the workflow run id that was executed for the PR
$prBranch = '${{ github.event.pull_request.head.ref }}'
$workflowId = 'build-test-package.yml'
$workflowRuns = gh api repos/${{ github.repository }}/actions/workflows/$workflowId/runs?event=pull_request`&branch=$prBranch | ConvertFrom-Json
$prHeadSha = '${{ github.event.pull_request.head.sha }}'
$nugetPackageRunId = $workflowRuns.workflow_runs.where{$_.head_sha -eq $prHeadSha}.id
if([string]::IsNullOrWhiteSpace($nugetPackageRunId)) {
Write-Output "::error::Couldn't find workflow run id for branch '$prBranch' and head commit '$prHeadSha'."
Exit 1
}
}
else { # on workflow_dispatch event
$nugetId = '${{ github.event.inputs.nuget-id }}'
$nugetVersion = '${{ github.event.inputs.nuget-version }}'
$autoGenerateReleaseNotes = '${{ github.event.inputs.generate-github-release-notes }}'.ToLower() # otherwise the ncipollo/release-action@v1 receives "True" and process it as false. Must be "true"
$nugetPackageRunId = '${{ github.event.inputs.nuget-package-workflow-run-id }}'
# there's no NuGet release issue when using workflow dispatch
$issueNumber = ''
# create empty custom release notes
New-Item -Name ${{ env.CUSTOM_RELEASE_NOTES_FILEPATH }} -ItemType File
# get GitHub release sha from workflow run id
$workflowRun = gh api repos/${{ github.repository }}/actions/runs/$nugetPackageRunId | ConvertFrom-Json
$headBranch = $workflowRun.head_branch
if($headBranch -ne 'main') {
Write-Output "::error::Invalid head branch: $headBranch. Workflow dispatch events for this workflow cannot use a NuGet package workflow run id that is not from the main branch."
Exit 1
}
$githubReleaseSha = $workflowRun.head_sha
}
if($nugetId -ne 'dotnet-sdk-extensions' -and $nugetId -ne 'dotnet-sdk-extensions-testing') {
Write-Output "::error::Invalid NuGet ID: $nugetId. Valid options are: dotnet-sdk-extensions or dotnet-sdk-extensions-testing"
Exit 1
}
Write-Output "issue-number=$issueNumber" >> $env:GITHUB_OUTPUT
Write-Output "nuget-id=$nugetId" >> $env:GITHUB_OUTPUT
Write-Output "nuget-version=$nugetVersion" >> $env:GITHUB_OUTPUT
Write-Output "auto-generate-release-notes=$autoGenerateReleaseNotes" >> $env:GITHUB_OUTPUT
Write-Output "nuget-package-run-id=$nugetPackageRunId" >> $env:GITHUB_OUTPUT
Write-Output "github-release-sha=$githubReleaseSha" >> $env:GITHUB_OUTPUT
- name: Dump outputs from previous step
env:
STEP_OUTPUT: ${{ toJSON(steps.nuget-publish-info.outputs) }}
run: $env:STEP_OUTPUT
- name: Upload custom release notes
uses: actions/upload-artifact@v4
with:
name: ${{ env.CUSTOM_RELEASE_NOTES_ARTIFACT_NAME }}
path: ${{ env.CUSTOM_RELEASE_NOTES_FILEPATH }}
publish-nuget:
name: Publish NuGet package and symbols
needs: [workflow-args]
permissions:
contents: write
runs-on: ubuntu-latest
outputs:
github-release-url: ${{ steps.create-gh-release.outputs.html_url }}
env:
EXTENSIONS_NUGET_BIN_FOLDER : ${{ github.workspace }}/DotNet.Sdk.Extensions/bin/Release
TESTING_EXTENSIONS_NUGET_BIN_FOLDER : ${{ github.workspace }}/DotNet.Sdk.Extensions.Testing/bin/Release
steps:
- name: Download NuGet package artifact
uses: dawidd6/action-download-artifact@v6
with:
name: nuget-packages-and-symbols
run_id: ${{ needs.workflow-args.outputs.nuget-package-run-id }}
- name: Download custom release notes artifact
uses: actions/download-artifact@v4
with:
name: ${{ needs.workflow-args.outputs.custom-release-notes-artifact-name }}
- name: Create release notes file
id: create-release-notes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$autoGenerateReleaseNotes = [System.Convert]::ToBoolean('${{ needs.workflow-args.outputs.auto-generate-release-notes }}')
$customReleaseNotes = Get-Content './nuget-release-notes.md'
$finalReleaseNotes = $customReleaseNotes
$finalNuGetReleaseNotesFilepath = "./final-nuget-release-notes.md"
if($autoGenerateReleaseNotes)
{
# first find the latest release for this nuget id and get its tag
$nugetId = '${{ needs.workflow-args.outputs.nuget-id }}'
$nugetVersion = '${{ needs.workflow-args.outputs.nuget-version }}'
$releases = gh api repos/${{ github.repository }}/releases | ConvertFrom-Json
$lastRelease = $releases | where-Object {$_.tag_name -match "^$nugetId-\d+"} | Select-Object -First 1
$lastReleaseTag = $lastRelease.tag_name
# now call the generate release notes endpoint with the new and previous tags
$generateReleaseNotesBody = [PSCustomObject]@{
tag_name = "$nugetId-$nugetVersion"
target_commitish = 'main'
previous_tag_name = "$lastReleaseTag"
}
$generateReleaseNotesBody | ConvertTo-Json -Compress > generateReleaseNotesBody.json
cat generateReleaseNotesBody.json
$generatedReleaseNotes = gh api repos/${{ github.repository }}/releases/generate-notes --input ./generateReleaseNotesBody.json | ConvertFrom-Json
# finally, concatenate the auto generated release notes with custom release notes
if($finalReleaseNotes -ne '')
{
$finalReleaseNotes += "`n"; # add new line between custom notes and generated notes
}
$finalReleaseNotes += $generatedReleaseNotes.body
}
$finalReleaseNotes > $finalNuGetReleaseNotesFilepath
Write-Output "nuget-release-notes-file-path=$finalNuGetReleaseNotesFilepath" >> $env:GITHUB_OUTPUT
Write-Output "nuget-release-name=$($generatedReleaseNotes.name)" >> $env:GITHUB_OUTPUT
- name: Prepare NuGet publish info
id: nuget-publish-info
run: |
$nugetId = '${{ needs.workflow-args.outputs.nuget-id }}'
if($nugetId -eq 'dotnet-sdk-extensions') {
$baseDir = '${{ env.EXTENSIONS_NUGET_BIN_FOLDER }}'
}
elseif($nugetId -eq "dotnet-sdk-extensions-testing") {
$baseDir = '${{ env.TESTING_EXTENSIONS_NUGET_BIN_FOLDER }}'
}
$nugetPushWorkingDir = $baseDir
$nugetPackage = Get-ChildItem $baseDir | Where-Object {$_.Extension -eq '.nupkg' } | Select-Object -First 1
$nugetSymbols = Get-ChildItem $baseDir | Where-Object {$_.Extension -eq '.snupkg' } | Select-Object -First 1
$nugetArtifacts = "$nugetPackage,$nugetSymbols"
Write-Output "nuget-gh-release-artifacts=$nugetArtifacts" >> $env:GITHUB_OUTPUT
Write-Output "nuget-package=$nugetPackage" >> $env:GITHUB_OUTPUT
Write-Output "nuget-symbols=$nugetSymbols" >> $env:GITHUB_OUTPUT
- name: Create GitHub release
id: create-gh-release
uses: ncipollo/release-action@v1
with:
commit: ${{ needs.workflow-args.outputs.github-release-sha }}
tag: ${{ needs.workflow-args.outputs.nuget-id }}-${{ needs.workflow-args.outputs.nuget-version }}
artifacts: '${{ steps.nuget-publish-info.outputs.nuget-gh-release-artifacts }}'
bodyFile: ${{ steps.create-release-notes.outputs.nuget-release-notes-file-path }}
generateReleaseNotes: false # I'm already generating and concatenating the notes on the create-release-notes step
token: ${{ secrets.GITHUB_TOKEN }}
- name: Publish NuGet and symbols
id: nuget-push
uses: edumserrano/nuget-push@v1
with:
api-key: ${{ secrets.NUGET_PUSH_API_KEY }}
nuget-package: '${{ steps.nuget-publish-info.outputs.nuget-package }}'
symbols-package: '${{ steps.nuget-publish-info.outputs.nuget-symbols }}'
- name: Log NuGet push info
if: steps.nuget-push.conclusion != 'skipped' && always()
run: |
$nugetId = '${{ needs.workflow-args.outputs.nuget-id }}'
$nugetUrl = "https://www.nuget.org/packages/$nugetId"
$nugetPushResult = '${{ steps.nuget-push.outputs.push-result }}' | ConvertFrom-Json
$package = $nugetPushResult.packages[0] # we are only using the nuget push action to push one package so I don't need to iterate the packages list, I can just get the first
if($package.status -eq 'ok') {
Write-Output "::notice title=$nugetId NuGet::Successfully pushed $nugetId NuGet and symbols to nuget.org. You can find the package at: $nugetUrl."
}
elseif($package.status -eq 'nuget-already-exists') {
Write-Output "::notice title=$nugetId NuGet::$nugetId NuGet was NOT published to nuget.org because the version to be pushed already exists."
}
elseif($package.status -eq 'nuget-push-failed') {
Write-Output "::error title=$nugetIdNuGet::Failed to push NuGet $nugetId."
}
elseif($package.status -eq 'symbols-push-failed') {
Write-Output "::error title=$nugetIdNuGet::Failed to push symbols for $nugetId."
}
else{
Write-Output "::error title=$nugetIdNuGet::Unexpected nuget push result status: $($package.status)."
}
output-artifacts:
name: Create output artifacts
needs: [workflow-args, publish-nuget]
if: always() && needs.publish-nuget.result != 'skipped'
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup NuGet release flow info
id: set-nuget-release-flow-info
run: |
$workflowResult = '${{ needs.publish-nuget.result }}'
if($workflowResult -eq 'success') {
$workflowStatus = "ok"
$releaseStatus = "completed"
$releaseBadgeColor = "green"
}
else {
$workflowStatus = "error"
$releaseStatus = "failed"
$releaseBadgeColor = "red"
}
Write-Output "nuget-release-status=$releaseStatus" >> $env:GITHUB_OUTPUT
Write-Output "nuget-release-badge-color=$releaseBadgeColor" >> $env:GITHUB_OUTPUT
Write-Output "publish-nuget-node-status=$workflowStatus" >> $env:GITHUB_OUTPUT
- name: Upload NuGet release flow info artifact
uses: ./.github/actions/create-nuget-release-flow-info-artifact
with:
issue-number: '${{ needs.workflow-args.outputs.issue-number }}'
nuget-release-status: '${{ steps.set-nuget-release-flow-info.outputs.nuget-release-status }}'
nuget-release-badge-color: '${{ steps.set-nuget-release-flow-info.outputs.nuget-release-badge-color }}'
publish-nuget-node-status: '${{ steps.set-nuget-release-flow-info.outputs.publish-nuget-node-status }}'
publish-nuget-url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
- name: Save GitHub release info to file
shell: pwsh
run: |
$githubRelease = @{
issueNumber = '${{ needs.workflow-args.outputs.issue-number }}'
nugetId = '${{ needs.workflow-args.outputs.nuget-id }}'
nugetVersion = '${{ needs.workflow-args.outputs.nuget-version }}'
githubReleaseUrl = '${{ needs.publish-nuget.outputs.github-release-url }}'
}
$githubReleaseAsJson = $githubRelease | ConvertTo-Json
$githubReleaseAsJson | Out-File github-release-info.md
Get-Content github-release-info.md
- name: Upload GitHub release info
uses: actions/upload-artifact@v4
with:
name: github-release-info
path: github-release-info.md