From bbf90bdafdba4305bb16f7df8695cf46579b50f2 Mon Sep 17 00:00:00 2001 From: jsklan Date: Fri, 26 Jun 2026 11:54:12 -0400 Subject: [PATCH 1/3] ci: publish to NuGet via Trusted Publishing (OIDC) Replace the long-lived NUGET_API_KEY publish step with nuget.org Trusted Publishing. A dedicated publish job (needs: [ci]) mints a short-lived key via NuGet/login@v1 using GitHub OIDC, scoping id-token: write to publishing only (off the test-running job). Mirrors the OIDC workflow now generated first-class by fern-csharp-sdk 2.69.0 (fern-api/fern#16725), adapted to this repo's solution build, dotnet 8.x, and legacy-tag exclusions. ci.yml stays in .fernignore so these customizations are preserved. Requires a nuget.org trust policy (owner=square, repo=square-dotnet-sdk, workflow=ci.yml) and a NUGET_USER secret; the NUGET_API_KEY secret can be removed after the first successful publish. --- .github/workflows/ci.yml | 55 +++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a10fcafc..3426cfff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,16 @@ +# Publishing uses nuget.org Trusted Publishing (OIDC) instead of a long-lived +# API key. This workflow filename (ci.yml) is part of the trust-policy contract +# on nuget.org -- do not rename it without updating the policy. +# +# Setup (one-time, on nuget.org): +# 1. nuget.org -> user menu -> Trusted Publishing -> create policy. +# 2. Repository Owner: square, Repository: square-dotnet-sdk, +# Workflow File: "ci.yml" (filename only, no path). +# 3. Add a NUGET_USER repo secret containing your nuget.org profile name +# (not your email). +# 4. After the first successful publish, remove the old NUGET_API_KEY secret +# (a stale key can interfere with OIDC login). + name: CI on: @@ -42,7 +55,6 @@ jobs: run: dotnet restore src/Square.sln - name: Build release - id: build run: dotnet build src/Square.sln -c Release /p:ContinuousIntegrationBuild=true - name: Run Tests @@ -52,10 +64,39 @@ jobs: TEST_SQUARE_TOKEN: ${{ secrets.TEST_SQUARE_TOKEN }} TEST_SQUARE_REPORTING: ${{ secrets.TEST_SQUARE_REPORTING }} + publish: + needs: [ci] + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + permissions: + contents: read # Required for checkout + id-token: write # Required for NuGet Trusted Publishing (OIDC) + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + + - name: Install tools + run: dotnet tool restore + + - name: Restore dependencies + run: dotnet restore src/Square.sln + + - name: Build release + run: dotnet build src/Square.sln --no-restore -c Release /p:ContinuousIntegrationBuild=true + + - name: Pack + run: dotnet pack src/Square.sln --no-build --no-restore -c Release -o dist + + - name: NuGet login (OIDC -> temp API key) + uses: NuGet/login@v1 + id: login + with: + user: ${{ secrets.NUGET_USER }} + - name: Publish to nuget.org - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') && steps.build.outcome == 'success' - env: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} - run: | - dotnet pack src/Square.sln --no-build --no-restore -c Release -o dist - dotnet nuget push dist/*.nupkg --api-key $NUGET_API_KEY --source "nuget.org" \ No newline at end of file + run: dotnet nuget push dist/*.nupkg --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --source "nuget.org" --skip-duplicate \ No newline at end of file From cefd8120dfbcec45268b4e3732ffff3b9d017753 Mon Sep 17 00:00:00 2001 From: jsklan Date: Fri, 26 Jun 2026 11:57:48 -0400 Subject: [PATCH 2/3] ci: pin NuGet/login to commit SHA (zizmor unpinned-uses) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3426cfff..264439f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,7 +93,7 @@ jobs: run: dotnet pack src/Square.sln --no-build --no-restore -c Release -o dist - name: NuGet login (OIDC -> temp API key) - uses: NuGet/login@v1 + uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0 id: login with: user: ${{ secrets.NUGET_USER }} From 8907e96aeb0103f16b3fb892c77ede895148d3c3 Mon Sep 17 00:00:00 2001 From: jsklan Date: Fri, 26 Jun 2026 12:45:05 -0400 Subject: [PATCH 3/3] ci: pass OIDC key via env to avoid run-step interpolation (semgrep) --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 264439f6..361ba3de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,4 +99,6 @@ jobs: user: ${{ secrets.NUGET_USER }} - name: Publish to nuget.org - run: dotnet nuget push dist/*.nupkg --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --source "nuget.org" --skip-duplicate \ No newline at end of file + env: + NUGET_API_KEY: ${{ steps.login.outputs.NUGET_API_KEY }} + run: dotnet nuget push dist/*.nupkg --api-key "$NUGET_API_KEY" --source "nuget.org" --skip-duplicate \ No newline at end of file