forgejo bump-formula: pre-receive 403 on auto-token git push #81

Open
opened 2026-05-25 06:57:30 +00:00 by coilysiren · 0 comments
Owner

Problem

Coily's forgejo release pipeline lands the tag + Release end-to-end (verified with v2.38.0 cut at run 34), but the bump-formula job fails with HTTP 500: PushRejected. Forgejo server logs trace this to the internal pre-receive hook returning 403:

POST /api/internal/hook/pre-receive/coilysiren/coily, 403 Forbidden in 1.7ms
*git.ErrPushRejected PushRejected
[remote rejected] <sha> -> main (pre-receive hook declined)

The Contents API endpoint accepts the PUT (HTTP 200 on GET; auth is recognized), but the underlying git push that forgejo performs to commit the rewrite is rejected at the pre-receive hook with 403. Looking at this from outside: the auto-issued ${{ github.token }} has API-layer write scope but lacks git-layer push permission.

Workflow has permissions: contents: write at both top-level and job-level; doesn't help.

Consequence

  • Brew install path currently works — Formula on forgejo main was updated by the brew sweep (#79) to forgejo URLs pinning v2.37.0, and forgejo serves that version fine. Mac users on brew upgrade get v2.37.0.
  • Auto-bump on subsequent releases doesn't fire. Tag v2.38.0 exists, Release v2.38.0 exists, but Formula/coily.rb still pins v2.37.0. Each release cycle ships a fresh tag without bumping the Formula.

Candidate fixes

  1. Provision a dedicated bump PAT. Create a fine-grained forgejo PAT scoped to coilysiren/coily contents:write, stash in SSM, expose to the workflow as a repo Actions secret, pass into bump-formula via forgejo_token: input. Bypasses the auto-token's git-layer gap. Cleanest fix. Decision needed: which SSM path, who creates the PAT.
  2. Toggle a forgejo server setting. If there's a config flag that grants Actions auto-tokens git push rights (haven't located one in app.ini or templates), flipping it would fix this systemically.
  3. Forgejo upstream bug? Possibly a known limitation in forgejo 15.0.2+gitea-1.22.0. Worth a brief upstream check.

Cleanup

Stray v2.23.0 tag was created during an earlier debug run (the tag-bump action ran before all historical tags were backfilled to forgejo, so it computed "v2.22 + patch" instead of "v2.37 + patch"). The historical v2.23.0 commit on github is a different SHA. Forgejo's v2.23.0 now points at the post-rebase main HEAD. Decide whether to delete and recreate at the correct historical SHA, or leave as-is (brew never installs from v2.23 again).

**Problem** Coily's forgejo release pipeline lands the tag + Release end-to-end (verified with v2.38.0 cut at run 34), but the `bump-formula` job fails with `HTTP 500: PushRejected`. Forgejo server logs trace this to the internal `pre-receive` hook returning 403: ``` POST /api/internal/hook/pre-receive/coilysiren/coily, 403 Forbidden in 1.7ms *git.ErrPushRejected PushRejected [remote rejected] <sha> -> main (pre-receive hook declined) ``` The Contents API endpoint accepts the PUT (HTTP 200 on GET; auth is recognized), but the underlying git push that forgejo performs to commit the rewrite is rejected at the pre-receive hook with 403. Looking at this from outside: the auto-issued `${{ github.token }}` has API-layer write scope but lacks git-layer push permission. Workflow has `permissions: contents: write` at both top-level and job-level; doesn't help. **Consequence** - Brew install path *currently works* — Formula on forgejo main was updated by the brew sweep (#79) to forgejo URLs pinning v2.37.0, and forgejo serves that version fine. Mac users on `brew upgrade` get v2.37.0. - Auto-bump on subsequent releases doesn't fire. Tag v2.38.0 exists, Release v2.38.0 exists, but Formula/coily.rb still pins v2.37.0. Each release cycle ships a fresh tag without bumping the Formula. **Candidate fixes** 1. **Provision a dedicated bump PAT.** Create a fine-grained forgejo PAT scoped to coilysiren/coily contents:write, stash in SSM, expose to the workflow as a repo Actions secret, pass into `bump-formula` via `forgejo_token:` input. Bypasses the auto-token's git-layer gap. Cleanest fix. Decision needed: which SSM path, who creates the PAT. 2. **Toggle a forgejo server setting.** If there's a config flag that grants Actions auto-tokens git push rights (haven't located one in app.ini or templates), flipping it would fix this systemically. 3. **Forgejo upstream bug?** Possibly a known limitation in forgejo 15.0.2+gitea-1.22.0. Worth a brief upstream check. **Cleanup** Stray `v2.23.0` tag was created during an earlier debug run (the tag-bump action ran before all historical tags were backfilled to forgejo, so it computed "v2.22 + patch" instead of "v2.37 + patch"). The historical v2.23.0 commit on github is a different SHA. Forgejo's v2.23.0 now points at the post-rebase main HEAD. Decide whether to delete and recreate at the correct historical SHA, or leave as-is (brew never installs from v2.23 again).
coilysiren added
P2
and removed
P1
labels 2026-05-31 06:59:46 +00:00
Sign in to join this conversation.
No labels
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-bridge/coily#81
No description provided.