From 807e5e3e6a1bb3077fa5b5015cb8b204fc753bdb Mon Sep 17 00:00:00 2001 From: Tejas Chopra Date: Thu, 9 Jul 2026 12:07:19 -0400 Subject: [PATCH] ci(release-please): use a PAT so releases trigger the publish workflows (#1920) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Makes the release pipeline hands-off by fixing the token release-please uses. ### Why the current setup silently breaks publishing release-please authenticates with `secrets.GITHUB_TOKEN`. **A release/tag created by `GITHUB_TOKEN` does not emit events that trigger other workflows** — this is GitHub's built-in recursion guard. So `release.yml` (PyPI + npm) and `docker.yml`, which both fire on `release: published`, **never ran off a bot-created release**. The result: releases had to be cut by hand (`gh release create`, which runs as a real user and *does* trigger them), and pip / npm / Docker drifted out of sync (pip 0.30 vs Docker 0.27). Proof: creating v0.31.0 manually (my user token) immediately kicked off both `Release: v0.31.0` and `Docker: v0.31.0`; a `GITHUB_TOKEN`-created release would not have. ### Change Use `RELEASE_PLEASE_TOKEN` (a fine-grained PAT with `contents: write` + `pull-requests: write`, treated by GitHub as a real user): ```yaml token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }} ``` - The release the bot creates now **does** trigger `release.yml` / `docker.yml` → PyPI + npm + Docker publish automatically on merge of the release PR. - The PAT can also tag past branch/tag protection. - Falls back to `GITHUB_TOKEN` if the secret is ever unset — the release PR still opens; it just won't trigger downstream publishes (i.e. no worse than today). The `RELEASE_PLEASE_TOKEN` secret is already configured in repo settings. ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [ ] New feature - [ ] Breaking change - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - `.github/workflows/release-please.yml`: swap `token: ${{ secrets.GITHUB_TOKEN }}` for `${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}`, with a comment explaining the recursion-guard reason. ## Testing - [x] Manual testing performed (YAML validated; token expression resolves) ### Test Output ```text $ python -c "import yaml; ... token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}" parse OK ``` ## Real Behavior Proof - Environment: local macOS; CI workflow YAML change only. - Exact command / steps: changed the `token:` input on the `release-please-action` step to the PAT (with GITHUB_TOKEN fallback); validated the workflow YAML parses and the token expression is correct. - Observed result: the workflow now authenticates release-please as a real user via `RELEASE_PLEASE_TOKEN`, so releases it creates will emit `release: published` and trigger `release.yml` + `docker.yml`. Verified out-of-band that a user-token release does trigger those two workflows (v0.31.0), whereas the bot token does not. - Not tested: a full bot-driven release cycle end-to-end (only observable when the next release PR merges with this token in place); this PR is the enabling change for that. ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [x] My changes generate no new warnings --- .github/workflows/release-please.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 99dce459e..ce458bfd8 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -44,6 +44,14 @@ jobs: steps: - uses: googleapis/release-please-action@v5 with: - token: ${{ secrets.GITHUB_TOKEN }} + # PAT (not GITHUB_TOKEN): a release/tag created by GITHUB_TOKEN does + # NOT emit events that trigger other workflows, so release.yml + # (PyPI/npm) and docker.yml — which fire on `release: published` — + # never ran, and releases had to be cut by hand. A PAT is treated as a + # real user, so the release it creates DOES trigger those publishes; it + # also lets the bot tag past branch/tag protection. Falls back to + # GITHUB_TOKEN when the secret is unset (the release PR still opens; it + # just won't trigger the downstream publishes). + token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }} config-file: .release-please-config.json manifest-file: .release-please-manifest.json