diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index e0c7fd8..f4ea0a2 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -1,15 +1,13 @@ -# Auto-tags and cuts a GitHub Release whenever pyproject.toml's version changes -# on main and the Python Test workflow has passed for that commit. Publishing -# a Release (types: [published]) is exactly what python-publish.yml already -# listens for, so this is the only piece needed to make merging to main (with -# a version bump) publish to PyPI, with no separate manual release step. +# Auto-tags, cuts a GitHub Release, and publishes to PyPI whenever +# pyproject.toml's version changes on main and the Python Test workflow has +# passed for that commit. No manual "cut a release" step needed. # -# The release-creation step deliberately uses the RELEASE_TOKEN secret (a -# PAT), not the default GITHUB_TOKEN: GitHub Actions does not fire other -# workflows' triggers (release: published included) for events performed -# with the automatic GITHUB_TOKEN, to prevent recursive runs. A release -# created with a PAT is attributed to a real actor instead, so it triggers -# python-publish.yml normally. See README "Releasing" for one-time setup. +# The publish job calls python-publish.yml directly via workflow_call rather +# than relying on the release: published event to cascade into it: GitHub +# Actions doesn't fire other workflows' triggers for events performed with +# the automatic GITHUB_TOKEN (anti-recursion safeguard), so a release created +# here wouldn't otherwise trigger it. Calling the job directly sidesteps that +# entirely -- no PAT/secret needed, since it's one run, not two. name: Auto Release @@ -30,6 +28,8 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + released: ${{ steps.check.outputs.exists == 'false' }} steps: - uses: actions/checkout@v4 with: @@ -55,13 +55,17 @@ jobs: - name: Create tag and GitHub release if: steps.check.outputs.exists == 'false' env: - GH_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GH_TOKEN: ${{ github.token }} run: | - if [ -z "$GH_TOKEN" ]; then - echo "::error::RELEASE_TOKEN repo secret is not set (needed so this release triggers python-publish.yml -- see README 'Releasing')." - exit 1 - fi gh release create "v${{ steps.version.outputs.version }}" \ --title "v${{ steps.version.outputs.version }}" \ --target "${{ github.event.workflow_run.head_sha }}" \ --generate-notes + + publish: + needs: release + if: needs.release.outputs.released == 'true' + permissions: + id-token: write + contents: read + uses: ./.github/workflows/python-publish.yml diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 00325f5..8c35b0d 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -12,6 +12,7 @@ on: release: types: [published] workflow_dispatch: + workflow_call: jobs: deploy: diff --git a/README.md b/README.md index fe908bf..5ec238c 100644 --- a/README.md +++ b/README.md @@ -300,21 +300,17 @@ async with pool.connection() as con: Bump `version` in `pyproject.toml` as part of your PR, same as any other change. Once that PR merges to `main` and the `Python Test` workflow passes for that commit, `.github/workflows/auto-release.yml` automatically tags it -`vX.Y.Z` and cuts a GitHub Release (skipping if that version was already -released, e.g. a merge that didn't touch the version) — no manual release -step needed. Publishing a Release is what `.github/workflows/python-publish.yml` -already listens for, so the new release then builds and publishes to PyPI -via trusted (OIDC) publishing automatically. - -`workflow_dispatch` on `python-publish.yml` still works as a manual -fallback if you ever need to re-publish a version without going through a -fresh tag/release. - -**One-time setup:** `auto-release.yml` needs a `RELEASE_TOKEN` repository -secret — a PAT (classic, `repo` scope, or fine-grained with this repo's -Contents: Read and write) belonging to someone with write access. This is -required because GitHub Actions doesn't fire other workflows' triggers -(`release: published` included) for a release created with the automatic -`GITHUB_TOKEN`, to prevent recursive runs — a release created with a PAT is -attributed to a real actor instead, so it triggers `python-publish.yml` -normally. Add it under Settings → Secrets and variables → Actions. +`vX.Y.Z`, cuts a GitHub Release (skipping if that version was already +released, e.g. a merge that didn't touch the version), and publishes to +PyPI via trusted (OIDC) publishing — no manual release step, and no extra +secret to configure. It calls `python-publish.yml`'s `deploy` job directly +(`workflow_call`) rather than relying on the release it just created to +trigger that workflow on its own — GitHub Actions doesn't fire other +workflows' triggers for events performed with the automatic `GITHUB_TOKEN`, +so a manually-created-via-Action release wouldn't otherwise cascade into a +publish; calling the job directly sidesteps that instead of working around +it with a PAT. + +`workflow_dispatch` (or an actual GitHub UI release) on `python-publish.yml` +still works as a manual fallback if you ever need to re-publish a version +without going through `auto-release.yml`.