diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 218ba14..f05bb24 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -24,20 +24,34 @@ jobs: release-please: runs-on: ubuntu-latest steps: - # NOTE: SHA-pin this to match the repo's action-pinning convention once the - # v4 commit SHA is available (e.g. `@ # v4`). Left as a floating tag - # here because the SHA can't be resolved offline. + # Mint a short-lived GitHub App installation token when the App is + # configured (org secrets RELEASE_PLEASE_APP_ID + RELEASE_PLEASE_APP_KEY). + # An App token — like a PAT, unlike GITHUB_TOKEN — triggers the tag-driven + # `release.yml`, but it's short-lived, auto-minted (nothing to rotate), and + # tied to no human account. The step is skipped if the App isn't set up. + # + # NOTE: SHA-pin `create-github-app-token` and `release-please-action` to + # match the repo's action-pinning convention (e.g. `@ # v2`) once the + # SHAs are available — left as floating tags because they can't be + # resolved offline. + - name: Mint GitHub App token + id: app-token + if: ${{ vars.RELEASE_PLEASE_APP_ID != '' }} + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.RELEASE_PLEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_PLEASE_APP_KEY }} + - uses: googleapis/release-please-action@v4 with: - # Prefer a PAT (`RELEASE_PLEASE_TOKEN`, `contents` + `pull-requests` - # write); fall back to GITHUB_TOKEN so release-please still opens and - # maintains the release PR out of the box. - # - # The PAT matters only for the *publish chain*: a tag created with the - # default GITHUB_TOKEN does NOT fire `on: push: tags`, so with the - # fallback the release PR and tag are still created, but `release.yml` - # (PyPI + Docker) won't run until a maintainer re-pushes the tag. Set - # the `RELEASE_PLEASE_TOKEN` secret to make merge-to-publish automatic. - token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }} + # Token precedence: + # 1. GitHub App installation token (recommended — see above). + # 2. RELEASE_PLEASE_TOKEN PAT (if someone set one instead). + # 3. GITHUB_TOKEN fallback — release-please still opens/maintains the + # release PR out of the box, but a tag it creates will NOT fire + # `on: push: tags`, so `release.yml` (PyPI + Docker) won't run + # until a maintainer re-pushes the tag. Configure the App (or the + # PAT) to make merge-to-publish automatic. + token: ${{ steps.app-token.outputs.token || secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }} config-file: release-please-config.json manifest-file: .release-please-manifest.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 13db1e4..cf3a1ad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -124,10 +124,23 @@ Users install the stable release with: curl -fsSL https://get2knowio.github.io/remo/install.sh | bash ``` -> **One-time setup:** the tag release-please creates must be authored by a PAT -> (repo secret `RELEASE_PLEASE_TOKEN`, `contents` + `pull-requests` write) for -> the publish to fire — a tag made with the default `GITHUB_TOKEN` does not -> trigger `release.yml`. See `.github/workflows/release-please.yml`. +> **One-time setup — publish trigger:** the tag release-please creates must be +> authored by a token that can trigger workflows, or `release.yml` (PyPI + +> Docker) won't fire (a tag made with the default `GITHUB_TOKEN` does **not** +> trigger `on: push: tags`). `release-please.yml` resolves the token in this +> order: +> +> 1. **GitHub App (recommended)** — set the org (or repo) Actions **variable** +> `RELEASE_PLEASE_APP_ID` and the **secret** `RELEASE_PLEASE_APP_KEY` (the +> App's private key). Install a GitHub App with **Contents: write** + +> **Pull requests: write** on this repo. Short-lived, auto-minted, nothing to +> rotate, tied to no personal account — and reusable across org repos. +> 2. **`RELEASE_PLEASE_TOKEN` PAT** — a personal access token (`contents` + +> `pull-requests` write) as a fallback if you don't use an App. +> 3. **`GITHUB_TOKEN`** — automatic last resort: release PRs still open, but the +> tag won't auto-publish until a maintainer re-pushes it. +> +> See `.github/workflows/release-please.yml`. > > **Note:** release-please does not run `uv lock`; if `uv.lock`'s recorded > project version matters to you, run `uv lock` and amend it onto the release PR