diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f62c76f..1a83476 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,6 +17,9 @@ jobs: publish: name: Build, Test and Publish NuGet Packages runs-on: ubuntu-latest + permissions: + contents: read + id-token: write services: redis: image: redis:7-alpine @@ -86,21 +89,22 @@ jobs: PACKAGE_VERSION: ${{ steps.version.outputs.package_version }} run: bash .github/scripts/validate-nuget-packages.sh "$PACKAGE_VERSION" artifacts - - name: Require NuGet publishing credentials - shell: bash - env: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} - run: | - if [[ -z "${NUGET_API_KEY:-}" ]]; then - echo "::error::Set the repository Actions secret NUGET_API_KEY before publishing this GitHub Release to NuGet.org." >&2 - exit 1 - fi + - name: NuGet login via Trusted Publishing (OIDC) + id: nuget-login + uses: NuGet/login@v1 + with: + user: peyman9722 - name: Publish packages and symbols to NuGet.org env: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + NUGET_API_KEY: ${{ steps.nuget-login.outputs.NUGET_API_KEY }} run: | + set -euo pipefail dotnet nuget push "artifacts/*.nupkg" \ --api-key "$NUGET_API_KEY" \ --source https://api.nuget.org/v3/index.json \ --skip-duplicate + dotnet nuget push "artifacts/*.snupkg" \ + --api-key "$NUGET_API_KEY" \ + --source https://api.nuget.org/v3/index.json \ + --skip-duplicate diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a006f56..a8551cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ on: type: string permissions: - contents: write + contents: read concurrency: group: release-${{ github.ref }} @@ -22,6 +22,9 @@ jobs: release: name: Validate, pack, and publish runs-on: ubuntu-latest + permissions: + contents: write + actions: write services: redis: image: redis:7-alpine @@ -144,24 +147,12 @@ jobs: --title "RateLimitEngine $RELEASE_TAG" --generate-notes fi - - name: Publish packages and symbols to NuGet.org when configured + - name: Dispatch NuGet publishing workflow via Trusted Publishing if: steps.version.outputs.skip != 'true' - shell: bash env: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + RELEASE_TAG: ${{ steps.version.outputs.tag }} run: | set -euo pipefail - if [[ -z "${NUGET_API_KEY:-}" ]]; then - echo "::notice::GitHub Release created successfully. NuGet publication was skipped because NUGET_API_KEY is not configured." - exit 0 - fi - - dotnet nuget push "artifacts/*.nupkg" \ - --api-key "$NUGET_API_KEY" \ - --source https://api.nuget.org/v3/index.json \ - --skip-duplicate - - dotnet nuget push "artifacts/*.snupkg" \ - --api-key "$NUGET_API_KEY" \ - --source https://api.nuget.org/v3/index.json \ - --skip-duplicate + gh workflow run publish.yml --repo "$GH_REPO" --ref main -f "release_tag=$RELEASE_TAG" diff --git a/README.md b/README.md index 67b502a..2ed8216 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ dotnet add package RateLimitEngine.Redis `RateLimitEngine.Core` is installed automatically as a dependency where required. -The current release is `1.0.0`. +The current GitHub Release is `1.0.1`. NuGet.org package availability begins after the first successful NuGet publishing workflow run. --- @@ -1059,7 +1059,7 @@ RateLimitEngine is split into focused packages. | `RateLimitEngine.Redis` | Redis-backed state implementations | | `RateLimitEngine.AspNetCore` | ASP.NET Core middleware and configuration | -The packages are versioned together for the current `1.0.0` release. +The packages are versioned together for the current `1.0.1` GitHub Release. --- @@ -1258,4 +1258,4 @@ All package versions are centralized in `Directory.Build.props`. The release wor To release a new version, update the `Version` value in `Directory.Build.props` and push the change to `main`, or push a matching `vMAJOR.MINOR.PATCH` tag. Existing version tags are not overwritten. -The GitHub Release workflow runs automatically on pushes to `main`: it validates the centralized version, restores/builds/tests the solution, packs all four libraries, verifies the `.nupkg` and `.snupkg` files, and creates a versioned GitHub Release with those artifacts. After the GitHub Release is created, the same workflow publishes the `.nupkg` and `.snupkg` files to NuGet.org when a valid repository Actions secret named `NUGET_API_KEY` is available; without the secret, GitHub Release still succeeds and NuGet publishing is explicitly skipped. To publish an existing GitHub Release manually after configuring the key, run `.github/workflows/publish.yml` from Actions and provide its exact tag (for example, `v1.0.1`). That workflow checks out the tag, verifies its package version, runs build/tests/package-consumer validation, and then publishes the packages and symbols to NuGet.org. CI starts two Redis instances (ports 6379 and 6382) for ordinary distributed tests and dedicated timeout scenarios. +The GitHub Release workflow runs automatically on pushes to `main`: it validates the centralized version, restores/builds/tests the solution, packs all four libraries, verifies the `.nupkg` and `.snupkg` files, and creates a versioned GitHub Release with those artifacts. It then dispatches `.github/workflows/publish.yml`, which performs a fresh build, test run, and package-consumer validation before publishing the `.nupkg` and `.snupkg` files to NuGet.org through Trusted Publishing (GitHub OIDC); no long-lived NuGet API key or repository secret is required. The trusted-publishing policy on NuGet.org must match the GitHub repository and the workflow file name `publish.yml`. To publish an existing GitHub Release manually, run `Publish NuGet Packages` from Actions and provide its exact tag (for example, `v1.0.1`). CI starts two Redis instances (ports 6379 and 6382) for ordinary distributed tests and dedicated timeout scenarios.