Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
105 changes: 92 additions & 13 deletions .github/actions/push-nuget-packages/action.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,128 @@
name: Push NuGet Packages
description: Downloads .nupkg release assets and publishes them to a NuGet feed using OIDC trusted publishing
description: Downloads .nupkg release assets and publishes them to a NuGet feed using OIDC trusted publishing or a static API key
inputs:
version:
required: true
description: Release tag to download package assets from
description: >
Release to download package assets from.
release-state:
required: true
description: Whether version identifies a 'published' release (by tag) or a 'draft' release (by name). One of 'published' or 'draft'
exclude-package-pattern:
required: false
default: ''
description: Glob pattern of package filenames to exclude from the push
nuget-user:
publish-mode:
required: true
description: NuGet trusted publishing user
nuget-source-domain:
description: How to authenticate the push. One of 'trusted-publishing' or 'api-key'
nuget-user:
required: false
default: ''
description: NuGet trusted publishing user (required when publish-mode is trusted-publishing)
feed-url:
required: true
description: NuGet feed domain used for both the trusted-publishing token service and the package source
description: >
NuGet package source URL, used as the push source. For publish-mode
'trusted-publishing' its domain also extracted to build the token
service URL and audience.
api-key:
required: false
default: ''
description: API key used to authenticate the push (required when publish-mode is api-key)
runs:
using: composite
steps:
- name: Validate inputs
shell: pwsh
run: |
$publishMode = "${{ inputs.publish-mode }}"
$validModes = @('trusted-publishing', 'api-key')
if ($validModes -notcontains $publishMode) {
throw "publish-mode must be one of: $($validModes -join ', '). Got '$publishMode'."
}
$releaseState = "${{ inputs.release-state }}"
$validReleaseStates = @('published', 'draft')
if ($validReleaseStates -notcontains $releaseState) {
throw "release-state must be one of: $($validReleaseStates -join ', '). Got '$releaseState'."
}
if ($publishMode -eq 'trusted-publishing' -and -not "${{ inputs.nuget-user }}") {
throw "nuget-user is required when publish-mode is 'trusted-publishing'."
}
if ($publishMode -eq 'trusted-publishing' -and "${{ inputs.api-key }}") {
throw "api-key must not be set when publish-mode is 'trusted-publishing'."
}
if ($publishMode -eq 'api-key' -and -not "${{ inputs.api-key }}") {
throw "api-key is required when publish-mode is 'api-key'."
}
$feedUrl = "${{ inputs.feed-url }}"
$parsedUri = $null
if (-not [Uri]::TryCreate($feedUrl, [UriKind]::Absolute, [ref]$parsedUri)) {
throw "feed-url must be a valid absolute URL. Got '$feedUrl'."
}
- name: Setup .NET SDK
uses: actions/setup-dotnet@v6
with:
dotnet-version: 'latest'
- name: Download assets from release
- name: Download assets from published release
if: inputs.release-state == 'published'
shell: pwsh
run: |
$version = "${{ inputs.version }}"
gh release download $version --repo "${{ github.repository }}" --pattern "*.nupkg" --dir nugets
if ($LASTEXITCODE -ne 0) {
throw "Failed to download release assets for tag '$version'"
}
env:
GH_TOKEN: ${{ github.token }}
- name: Download assets from draft release
if: inputs.release-state == 'draft'
shell: pwsh
run: |
gh release download "${{ inputs.version }}" --repo "${{ github.repository }}" --pattern "*.nupkg" --dir nugets
$name = "${{ inputs.version }}"
$releases = gh api "repos/${{ github.repository }}/releases" | ConvertFrom-Json
$release = $releases | Where-Object { $_.name -eq $name } | Select-Object -First 1
if (-not $release) {
throw "Could not find a draft release named '$name'"
}
Write-Output "Found draft release id $($release.id) with tag '$($release.tag_name)' for '$name'"
gh release download $release.tag_name --repo "${{ github.repository }}" --pattern "*.nupkg" --dir nugets
if ($LASTEXITCODE -ne 0) {
throw "Failed to download release assets for tag '$($release.tag_name)'"
}
env:
GH_TOKEN: ${{ github.token }}
- name: Resolve NuGet feed domain
id: resolve
if: inputs.publish-mode == 'trusted-publishing'
shell: pwsh
run: |
$domain = ([Uri]"${{ inputs.feed-url }}").GetLeftPart([System.UriPartial]::Authority)
Comment thread
tamararivera marked this conversation as resolved.
Write-Output "domain=$domain" >> $env:GITHUB_OUTPUT
- name: Get NuGet trusted publishing API key
if: inputs.publish-mode == 'trusted-publishing'
uses: NuGet/login@v1
id: login
with:
user: ${{ inputs.nuget-user }}
token-service-url: ${{ inputs.nuget-source-domain }}/api/v2/token
audience: ${{ inputs.nuget-source-domain }}
- name: Push NuGet packages to production feed
token-service-url: ${{ steps.resolve.outputs.domain }}/api/v2/token
Comment thread
tamararivera marked this conversation as resolved.
audience: ${{ steps.resolve.outputs.domain }}
- name: Push NuGet packages
shell: pwsh
run: |
$getChildItemParams = @{ Path = 'nugets/*'; Include = '*.nupkg' }
$excludePattern = "${{ inputs.exclude-package-pattern }}"
if ($excludePattern) { $getChildItemParams.Exclude = $excludePattern }
$packages = Get-ChildItem @getChildItemParams
Write-Output "Pushing $($packages.Count) NuGet package(s) to ${{ inputs.nuget-source-domain }}:"
$source = "${{ inputs.feed-url }}"
$apiKey = if ("${{ inputs.publish-mode }}" -eq 'trusted-publishing') { "${{ steps.login.outputs.NUGET_API_KEY }}" } else { "${{ inputs.api-key }}" }
Write-Output "Pushing $($packages.Count) NuGet package(s) to $source`:"
$packages | ForEach-Object { Write-Output " - $($_.Name)" }
$failed = @()
foreach ($package in $packages)
{
dotnet nuget push $package.FullName --source ${{ inputs.nuget-source-domain }}/api/v2/package --api-key ${{ steps.login.outputs.NUGET_API_KEY }}
dotnet nuget push $package.FullName --source $source --api-key $apiKey --skip-duplicate
if ($LASTEXITCODE -ne 0) { $failed += $package.Name }
}
if ($failed.Count -gt 0) {
throw "Failed to push $($failed.Count) package(s): $($failed -join ', ')"
}
50 changes: 0 additions & 50 deletions .github/workflows/push-nuget-packages-staging.yml

This file was deleted.

Loading