From 509bacd0e0491ba520ccf9f39acb8610275cb22c Mon Sep 17 00:00:00 2001 From: Philippe Matray Date: Sat, 25 Jul 2026 15:12:08 +0200 Subject: [PATCH] ci: make the NuGet publish actually work, via Trusted Publishing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This job held a live NUGET_API_KEY secret while being incapable of publishing anything. Four faults, all on the same path: - it never packed. The job checked out, computed a version, installed the SDK, then pushed packages that did not exist — the build/test jobs run on separate runners and nothing carried their output over; - it invoked 'nuget push', the nuget.exe CLI, which is not present on ubuntu-latest; - the glob was Windows-shaped ('**\*.nupkg'); - BUILD_VERSION was computed from the tag and then never used, so any release would have carried the literal 0.5.0 from Directory.Build.props. 'gh run list --workflow=publish-to-nuget.yml' returns nothing: this workflow has never run once. So none of the above ever surfaced, and the secret sat there regardless. Now: packs both packable projects with -p:Version from the tag, pushes with dotnet nuget push, and authorizes through Trusted Publishing — the GitHub OIDC token exchanged for a key valid ~1 hour, no long-lived secret. Also fixes the pwsh Import-Module path, which used backslashes on a Linux runner. Requires a Trusted Publishing policy on nuget.org covering both package ids and the NUGET_USER secret before the first real release. --- .github/workflows/publish-to-nuget.yml | 32 +++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-to-nuget.yml b/.github/workflows/publish-to-nuget.yml index bf20508..0f9f18e 100644 --- a/.github/workflows/publish-to-nuget.yml +++ b/.github/workflows/publish-to-nuget.yml @@ -57,12 +57,16 @@ jobs: needs: test runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # request the GitHub OIDC token for NuGet Trusted Publishing + steps: - uses: actions/checkout@v6 - name: Get Build Version run: | - Import-Module .\build\GetBuildVersion.psm1 + Import-Module ./build/GetBuildVersion.psm1 Write-Host $Env:GITHUB_REF $version = GetBuildVersion -VersionString $Env:GITHUB_REF echo "BUILD_VERSION=$version" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append @@ -73,6 +77,28 @@ jobs: with: dotnet-version: 10.0.x + # The version comes from the tag, overriding the hard-coded in + # Directory.Build.props — without -p:Version every tag would publish that literal instead. + - name: Pack + run: | + dotnet pack src/Atypical.VirtualFileSystem.Core/Atypical.VirtualFileSystem.Core.csproj \ + --configuration Release -p:Version=$BUILD_VERSION --output ./artifacts + dotnet pack src/Atypical.VirtualFileSystem.GitHub/Atypical.VirtualFileSystem.GitHub.csproj \ + --configuration Release -p:Version=$BUILD_VERSION --output ./artifacts + + # Trusted Publishing: exchanges the OIDC token for a NuGet key valid ~1 hour, so no + # long-lived secret is stored. Requires a Trusted Publishing policy on nuget.org covering + # Atypical.VirtualFileSystem and Atypical.VirtualFileSystem.GitHub, naming this repository + # and publish-to-nuget.yml, plus the NUGET_USER secret (the nuget.org profile name). + - name: NuGet login (OIDC -> short-lived key) + id: nuget-login + uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0 + with: + user: ${{ secrets.NUGET_USER }} + - name: Publish to NuGet - if: startsWith(github.ref, 'refs/tags') - run: nuget push **\*.nupkg -Source 'https://api.nuget.org/v3/index.json' -ApiKey ${{secrets.NUGET_API_KEY}} \ No newline at end of file + run: | + dotnet nuget push "./artifacts/*.nupkg" \ + --api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" \ + --source https://api.nuget.org/v3/index.json \ + --skip-duplicate \ No newline at end of file