diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 56d097c..3a6fdc7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,12 +3,14 @@ name: Release on: push: tags: [ "v*" ] + workflow_dispatch: permissions: - contents: write + contents: read jobs: release: + if: github.event_name == 'push' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -36,10 +38,57 @@ jobs: - name: Pack run: dotnet pack src/BabelQueue.Core/BabelQueue.Core.csproj -c Release -o artifacts + - name: Upload packages + uses: actions/upload-artifact@v7 + with: + name: nupkg + # Same set the old inline push sent: dotnet nuget push also picks up the sibling .snupkg. + path: | + artifacts/*.nupkg + artifacts/*.snupkg + if-no-files-found: error + retention-days: 1 + + - name: Upload conformance results + uses: actions/upload-artifact@v7 + with: + name: conformance-results + path: results.json + if-no-files-found: error + retention-days: 1 + + # Runs only after build + tests passed. The only job (besides the dry run) that can request + # an OIDC token, so third-party build/test code never sees ACTIONS_ID_TOKEN_REQUEST_*. + publish: + if: github.event_name == 'push' + needs: release + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + steps: + - name: Download packages + uses: actions/download-artifact@v8 + with: + name: nupkg + path: artifacts + + - name: Download conformance results + uses: actions/download-artifact@v8 + with: + name: conformance-results + path: . + + - name: NuGet login (Trusted Publishing) + id: nuget-login + uses: NuGet/login@v1 + with: + user: ${{ vars.NUGET_USER }} + - name: Publish to NuGet run: > dotnet nuget push "artifacts/*.nupkg" - --api-key "${{ secrets.NUGET_API_KEY }}" + --api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate @@ -49,3 +98,28 @@ jobs: generate_release_notes: true files: results.json fail_on_unmatched_files: true + + # Manual dry run: exercises only the NuGet Trusted Publishing login (no test, pack, push + # or GitHub release), so the nuget.org policy can be verified without cutting a version. + verify-trusted-publishing: + if: github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + permissions: + id-token: write + steps: + - name: NuGet login (Trusted Publishing) + id: nuget-login + uses: NuGet/login@v1 + with: + user: ${{ vars.NUGET_USER }} + + - name: Verify the short-lived API key was issued + env: + KEY: ${{ steps.nuget-login.outputs.NUGET_API_KEY }} + run: | + if [ -n "$KEY" ]; then + echo "Trusted Publishing login OK" + else + echo "Trusted Publishing login returned an empty API key" >&2 + exit 1 + fi