ci(release): open the packaging PR with a release GitHub App token #86

Merged
KofTwentyTwo merged 1 commits from ci/packaging-app-token into main 2026-10-10 17:24:58 +00:00
KofTwentyTwo commented 2026-10-10 17:17:41 +00:00 (Migrated from github.com)

What

protect-main requires signed commits, and the build(packaging): … PR the packages job opens had an unsigned commit. #82's DCO sign-off was not enough: peter-evans/create-pull-request signs only with a bot token and explicitly not with a PAT, which is why the v1.0.1 packaging PR went #80 → #83 (re-created unsigned by "update branch") → #84 (cherry-picked and signed by hand).

  • packages now mints a short-lived token from a release GitHub App (actions/create-github-app-token v3.2.0, SHA-pinned) using the repository variable RELEASE_APP_CLIENT_ID and the release-environment secret RELEASE_APP_PRIVATE_KEY (contents + pull requests write, this repository only, no bypass), and opens the PR with it and sign-commits: true. GitHub signs the commit, its author is the App's [bot] user (exempt from pr / dco), and the PR still triggers the required checks. Same pattern as the standards repository's own release automation.
  • DEPS_PAT is no longer used by the release workflow (it stays optional for nuget-updates.yml). The preflight step fails when the App id or key is missing.
  • docs/RELEASING.md (tokens table + "Why a GitHub App" with the one-time setup), ADR 0003 and the threat model revision table record the change.

Closes #85 (follows #81, part of #62).

Owner steps before the next stable release

  1. Create a GitHub App (Settings → Developer settings → GitHub Apps): installed only on KofTwentyTwo/gclo, permissions Contents: write and Pull requests: write, no ruleset bypass.
  2. Repository variable RELEASE_APP_CLIENT_ID = the App's client id.
  3. release environment secret RELEASE_APP_PRIVATE_KEY = the App's private key (.pem), e.g. op read "op://<vault>/<item>/private key" | gh secret set RELEASE_APP_PRIVATE_KEY --env release --repo KofTwentyTwo/gclo.

How it was tested

  • actionlint clean; create-github-app-token@bcd2ba4 is the v3.2.0 tag and exposes client-id, private-key, permission-contents, permission-pull-requests.
  • Not exercised on a tag: the next stable release is the first run. If the App is not set up by then, the packages job fails at its preflight and can be re-run alone after the secrets are added.

🤖 Generated with Claude Code

## What `protect-main` requires signed commits, and the `build(packaging): …` PR the `packages` job opens had an unsigned commit. #82's DCO sign-off was not enough: `peter-evans/create-pull-request` signs only with a bot token and explicitly not with a PAT, which is why the v1.0.1 packaging PR went #80 → #83 (re-created unsigned by "update branch") → #84 (cherry-picked and signed by hand). - `packages` now mints a short-lived token from a release GitHub App (`actions/create-github-app-token` v3.2.0, SHA-pinned) using the repository variable `RELEASE_APP_CLIENT_ID` and the `release`-environment secret `RELEASE_APP_PRIVATE_KEY` (contents + pull requests write, this repository only, no bypass), and opens the PR with it and `sign-commits: true`. GitHub signs the commit, its author is the App's `[bot]` user (exempt from `pr / dco`), and the PR still triggers the required checks. Same pattern as the standards repository's own release automation. - `DEPS_PAT` is no longer used by the release workflow (it stays optional for `nuget-updates.yml`). The preflight step fails when the App id or key is missing. - `docs/RELEASING.md` (tokens table + "Why a GitHub App" with the one-time setup), ADR 0003 and the threat model revision table record the change. Closes #85 (follows #81, part of #62). ## Owner steps before the next stable release 1. Create a GitHub App (Settings → Developer settings → GitHub Apps): installed **only on KofTwentyTwo/gclo**, permissions **Contents: write** and **Pull requests: write**, no ruleset bypass. 2. Repository variable `RELEASE_APP_CLIENT_ID` = the App's client id. 3. `release` environment secret `RELEASE_APP_PRIVATE_KEY` = the App's private key (`.pem`), e.g. `op read "op://<vault>/<item>/private key" | gh secret set RELEASE_APP_PRIVATE_KEY --env release --repo KofTwentyTwo/gclo`. ## How it was tested - `actionlint` clean; `create-github-app-token@bcd2ba4` is the `v3.2.0` tag and exposes `client-id`, `private-key`, `permission-contents`, `permission-pull-requests`. - Not exercised on a tag: the next stable release is the first run. If the App is not set up by then, the `packages` job fails at its preflight and can be re-run alone after the secrets are added. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.