From 6a6b4a424f0f77a46cd6f0b03c0e8fc4b6339441 Mon Sep 17 00:00:00 2001 From: Muhannad Al-Khatib Date: Tue, 10 Nov 2026 18:23:53 +0300 Subject: [PATCH] ci: push the SDK through nuget.org trusted publishing The org's SWNUGETKEY API key has expired, so the SDK push to nuget.org now fails with 403. Trusted publishing trades the job's OIDC token for a one-hour key, so nothing stored can expire. nuget.org requires the token's job_workflow_ref to be in this repository, so the shared service workflow no longer pushes (its nuget-projects is empty; build and tests still run there) and a nuget job here logs in with NuGet/login (NUGET_USER) and pushes the SDK with the version the shared workflow computed. --- .github/workflows/ci-cd.yml | 48 +++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 3e52dfd..780c24a 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -23,8 +23,9 @@ jobs: minor-version: '0' dotnet-version: '10.0.x' - # Build + push the SDK NuGet package (tests off, as before) - nuget-projects: 'SW.Surl.Sdk/SW.Surl.Sdk.csproj' + # The SDK is pushed by the nuget job below (trusted publishing), not here: + # the build still run in the shared workflow. + nuget-projects: '' run-tests: 'false' dockerfile-path: './Dockerfile' @@ -73,9 +74,6 @@ jobs: chartmuseum-username: ${{ secrets.CM_USER }} chartmuseum-password: ${{ secrets.CM_PASSWORD }} - # NuGet API key (publishes to nuget.org, the reusable's default feed) - nuget-api-key: ${{ secrets.SWNUGETKEY }} - # Gateway-API cluster kubeconfig (V2) kubeconfig-gateway: ${{ secrets.S9DEV_KUBECONFIG_V2 }} @@ -86,3 +84,43 @@ jobs: # App configuration passed to helm --set-string during deploy (masked) helm-set-secret-values: 'db=${{ secrets.DBCS }}' dependabot-alerts-token: ${{ secrets.DEPENDABOT_ALERTS_TOKEN }} + + # The SDK goes to nuget.org with Trusted Publishing: GitHub's OIDC token is traded for an API key + # that lasts an hour, so there is no stored key to expire (the SWNUGETKEY secret had expired). + # nuget.org takes the workflow file from the token's job_workflow_ref and requires it to be in + # this repository, so the login can't run inside the shared reusable-service-cicd.yml; it runs + # here, after it, with the version it computed. The nuget.org policy: owner simplify9, + # repository SW-Surl-api, workflow ci-cd.yml. NUGET_USER (a repository or organisation variable) is + # the nuget.org user who created the policy. The version is tagged by then, and a failed push + # can be re-run on its own: --skip-duplicate makes that safe. + nuget: + needs: Task + runs-on: ubuntu-24.04 + timeout-minutes: 20 + permissions: + contents: read + id-token: write # the OIDC token NuGet/login trades for a short-lived API key + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Restore and build + uses: simplify9/.github/.github/actions/dotnet-build@main + with: + projects: 'SW.Surl.Sdk/SW.Surl.Sdk.csproj' + configuration: Release + dotnet-version: '10.0.x' + run-tests: false + - name: NuGet login (OIDC to a one-hour API key) + id: login + uses: NuGet/login@v1 + with: + user: ${{ vars.NUGET_USER }} + - name: Pack and push + uses: simplify9/.github/.github/actions/dotnet-pack-push@main + with: + projects: 'SW.Surl.Sdk/SW.Surl.Sdk.csproj' + configuration: Release + version: ${{ needs.Task.outputs.version }} + api-key: ${{ steps.login.outputs.NUGET_API_KEY }} + nuget-source: 'https://api.nuget.org/v3/index.json'