Problem
auto-release-pr.yaml creates the Release: develop -> main PR using
secrets.GITHUB_TOKEN. GitHub's no-recursive-workflow policy
means PRs opened by GITHUB_TOKEN do not propagate pull_request
events to other workflows — so ci.yaml does not run when the bot
opens a Release PR.
Today's workaround: a human removes and re-adds the ci:full label on
the bot-opened PR, which fires a labeled event from a human actor
and unblocks CI. This is brittle and easy to forget. PR #139 hit it
this round.
Fix shape
Replace secrets.GITHUB_TOKEN in auto-release-pr.yaml with a token
that GitHub does propagate. Two viable options:
Option 1 — Personal Access Token (fast, less robust)
Create a fine-grained PAT under a maintainer account with:
- Repo selected:
zk-coins/node
- Permissions:
Contents: read, Pull requests: write, Issues: write
- Expiry: 1 year (track in calendar)
Store as repo secret RELEASE_PR_PAT. Trade-off: tied to the issuing
account; rotation has to happen explicitly; if the account loses
access, every repo that uses this pattern needs a new PAT.
Option 2 — GitHub App (slower setup, org-wide robust)
Register a GitHub App owned by the zk-coins org with:
- Repo permissions:
Contents: read, Pull requests: write, Issues: write
- Install on
zk-coins/node (and the other org repos that have the
same workflow — zk-coins/app, zk-coins/landing-page)
In the workflow, exchange the App's app_id + private_key for a
short-lived installation token via actions/create-github-app-token@v1
on each run.
Trade-off: 1-time setup cost; no rotation burden after that;
multi-repo install is trivial; tokens are ephemeral per-run.
DFXswiss has the same gap on every auto-release-pr.yaml in the
org (DFXswiss/api, DFXswiss/server, DFXswiss/services,
DFXswiss/realunit-app, zk-coins/landing-page, zk-coins/app).
Option 2 fixes them all with one App.
Concrete code diff (after a token is available)
# .github/workflows/auto-release-pr.yaml
# Option 1 — PAT:
env:
GH_TOKEN: ${{ secrets.RELEASE_PR_PAT }}
# Option 2 — App:
permissions:
contents: read
pull-requests: write
issues: write
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.RELEASE_PR_APP_ID }}
private-key: ${{ secrets.RELEASE_PR_APP_KEY }}
- name: Create Release PR
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
...
Verification
Open a fresh Release PR via Actions → Auto Release PR → Run workflow
on a develop branch with at least one commit ahead of main. Confirm
that the CI workflow runs against the new PR without a human
label-cycle.
Out of scope
- Backporting to the other org repos — track separately.
- Replacing the
Auto Release PR workflow itself with a different
mechanism — separate decision.
Who can pick this up
This needs a maintainer with org-owner rights (for Option 2) or with
PAT-creation rights on an account that has Contents: read,
Pull requests: write on the repo (for Option 1). After the token /
App is registered, the code diff is ~5 lines and the PR is mechanical.
Problem
auto-release-pr.yamlcreates theRelease: develop -> mainPR usingsecrets.GITHUB_TOKEN. GitHub's no-recursive-workflow policymeans PRs opened by
GITHUB_TOKENdo not propagatepull_requestevents to other workflows — so
ci.yamldoes not run when the botopens a Release PR.
Today's workaround: a human removes and re-adds the
ci:fulllabel onthe bot-opened PR, which fires a
labeledevent from a human actorand unblocks CI. This is brittle and easy to forget. PR #139 hit it
this round.
Fix shape
Replace
secrets.GITHUB_TOKENinauto-release-pr.yamlwith a tokenthat GitHub does propagate. Two viable options:
Option 1 — Personal Access Token (fast, less robust)
Create a fine-grained PAT under a maintainer account with:
zk-coins/nodeContents: read,Pull requests: write,Issues: writeStore as repo secret
RELEASE_PR_PAT. Trade-off: tied to the issuingaccount; rotation has to happen explicitly; if the account loses
access, every repo that uses this pattern needs a new PAT.
Option 2 — GitHub App (slower setup, org-wide robust)
Register a GitHub App owned by the
zk-coinsorg with:Contents: read,Pull requests: write,Issues: writezk-coins/node(and the other org repos that have thesame workflow —
zk-coins/app,zk-coins/landing-page)In the workflow, exchange the App's
app_id+private_keyfor ashort-lived installation token via
actions/create-github-app-token@v1on each run.
Trade-off: 1-time setup cost; no rotation burden after that;
multi-repo install is trivial; tokens are ephemeral per-run.
DFXswiss has the same gap on every auto-release-pr.yaml in the
org (
DFXswiss/api,DFXswiss/server,DFXswiss/services,DFXswiss/realunit-app,zk-coins/landing-page,zk-coins/app).Option 2 fixes them all with one App.
Concrete code diff (after a token is available)
Verification
Open a fresh Release PR via
Actions → Auto Release PR → Run workflowon a develop branch with at least one commit ahead of main. Confirm
that the
CIworkflow runs against the new PR without a humanlabel-cycle.
Out of scope
Auto Release PRworkflow itself with a differentmechanism — separate decision.
Who can pick this up
This needs a maintainer with org-owner rights (for Option 2) or with
PAT-creation rights on an account that has
Contents: read,Pull requests: writeon the repo (for Option 1). After the token /App is registered, the code diff is ~5 lines and the PR is mechanical.