Skip to content

Publish NuGet Packages #12

Publish NuGet Packages

Publish NuGet Packages #12

Workflow file for this run

name: Publish NuGet Packages
on:
workflow_dispatch:
inputs:
version:
description: "Full NuGet package version to produce, for example 4.0.0-preview.1"
required: true
type: string
publish:
description: "Push packages to the configured NuGet source"
required: true
default: false
type: boolean
nuget_user:
description: "NuGet.org username/profile name. Uses repository variable NUGET_USER when omitted."
required: false
default: ""
type: string
skip_duplicate:
description: "Pass --skip-duplicate to dotnet nuget push"
required: true
default: true
type: boolean
permissions:
contents: read
concurrency:
group: publish-nuget-${{ github.ref_name }}
cancel-in-progress: false
env:
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
jobs:
pack:
name: Pack all NuGet packages
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7.0.1
- name: Setup .NET
uses: actions/setup-dotnet@v6.0.0
with:
dotnet-version: 10.0.x
- name: Validate requested version
shell: bash
env:
PACKAGE_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if [[ ! "$PACKAGE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z][0-9A-Za-z.-]*)?(\+[0-9A-Za-z][0-9A-Za-z.-]*)?$ ]]; then
echo "Package version must be a SemVer value such as 3.0.8-preview.1 or 4.0.0-preview.1." >&2
exit 1
fi
case "$GITHUB_REF_NAME" in
release/3.0)
if [[ "$PACKAGE_VERSION" != 3.0.* ]]; then
echo "release/3.0 publishes the 3.0.x package line; got '$PACKAGE_VERSION'." >&2
exit 1
fi
;;
main)
if [[ "$PACKAGE_VERSION" != 4.* ]]; then
echo "main publishes the 4.x package line; got '$PACKAGE_VERSION'." >&2
exit 1
fi
;;
esac
- name: Restore
run: dotnet restore PdfBoxNet.slnx
- name: Build
run: dotnet build PdfBoxNet.slnx --configuration Release --no-restore
- name: Test
run: dotnet test PdfBoxNet.slnx --configuration Release --no-build --nologo
- name: Pack
shell: bash
env:
PACKAGE_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
rm -rf artifacts/packages
dotnet pack PdfBoxNet.slnx \
--configuration Release \
--no-build \
--output artifacts/packages \
-p:ContinuousIntegrationBuild=true \
-p:Version="$PACKAGE_VERSION"
- name: Verify package output
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
packages=(artifacts/packages/*.nupkg)
if [ "${#packages[@]}" -eq 0 ]; then
echo "No NuGet packages were produced." >&2
exit 1
fi
printf '%s\n' "${packages[@]}" | sort
{
echo "### NuGet packages"
echo
for package in "${packages[@]}"; do
echo "- `$(basename "$package")`"
done | sort
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload package artifacts
uses: actions/upload-artifact@v7.0.1
with:
name: nuget-packages-${{ inputs.version }}
path: artifacts/packages/*.nupkg
if-no-files-found: error
publish:
name: Publish packages
runs-on: ubuntu-latest
needs: pack
if: ${{ inputs.publish }}
environment: nuget.org
permissions:
actions: read
contents: write
id-token: write
steps:
- name: Ref safety check
shell: bash
run: |
set -euo pipefail
case "$GITHUB_REF_NAME" in
main|release/3.0)
;;
*)
echo "Publishing is only allowed from main or release/3.0; current ref is '$GITHUB_REF_NAME'." >&2
exit 1
;;
esac
- name: Setup .NET
uses: actions/setup-dotnet@v6.0.0
with:
dotnet-version: 10.0.x
- name: Download package artifacts
uses: actions/download-artifact@v8.0.1
with:
name: nuget-packages-${{ inputs.version }}
path: artifacts/packages
- name: Resolve NuGet trusted publishing user
id: nuget_user
shell: bash
env:
INPUT_NUGET_USER: ${{ inputs.nuget_user }}
VAR_NUGET_USER: ${{ vars.NUGET_USER }}
run: |
set -euo pipefail
user="${INPUT_NUGET_USER:-$VAR_NUGET_USER}"
if [ -z "$user" ]; then
echo "Set the NUGET_USER repository/environment variable or provide the nuget_user workflow input." >&2
echo "Use the nuget.org username/profile name, not an email address." >&2
exit 1
fi
echo "user=$user" >> "$GITHUB_OUTPUT"
- name: NuGet login via trusted publishing
id: nuget_login
uses: NuGet/login@v1.2.0
with:
user: ${{ steps.nuget_user.outputs.user }}
- name: Push packages
shell: bash
env:
NUGET_API_KEY: ${{ steps.nuget_login.outputs.NUGET_API_KEY }}
NUGET_SOURCE: https://api.nuget.org/v3/index.json
SKIP_DUPLICATE: ${{ inputs.skip_duplicate }}
run: |
set -euo pipefail
if [ -z "${NUGET_API_KEY:-}" ]; then
echo "NuGet trusted publishing did not return a temporary API key." >&2
exit 1
fi
args=(dotnet nuget push artifacts/packages/*.nupkg --source "$NUGET_SOURCE" --api-key "$NUGET_API_KEY")
if [ "$SKIP_DUPLICATE" = "true" ]; then
args+=(--skip-duplicate)
fi
"${args[@]}"
- name: Create GitHub release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
PACKAGE_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
shopt -s nullglob
tag="v${PACKAGE_VERSION}"
title="PdfBox.Net ${PACKAGE_VERSION}"
packages=(artifacts/packages/*.nupkg)
if [ "${#packages[@]}" -eq 0 ]; then
echo "No NuGet packages were found to attach to the GitHub release." >&2
exit 1
fi
if gh release view "$tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "GitHub release $tag already exists; refreshing package assets."
gh release upload "$tag" "${packages[@]}" --repo "$GITHUB_REPOSITORY" --clobber
else
gh release create "$tag" "${packages[@]}" \
--repo "$GITHUB_REPOSITORY" \
--target "$GITHUB_SHA" \
--title "$title" \
--generate-notes
fi
release_url="$(gh release view "$tag" --repo "$GITHUB_REPOSITORY" --json url --jq .url)"
{
echo "### GitHub release"
echo
echo "- [$tag]($release_url)"
} >> "$GITHUB_STEP_SUMMARY"