release-bot needs push_whitelist_usernames membership for direct-push manifest path #260

Closed
opened 2026-06-29 15:00:46 +02:00 by quartermaster · 0 comments

Empirical anchor

Surfaced during the tmux-tell#630 recovery (release-toolkit#259's sibling investigation): the toolkit's path-α design assumes release-bot can direct-push manifest commits to main past branch protection. That requires the release-bot account to be in the consumer repo's push_whitelist_usernames for the default branch.

tmux-tell's main branch protection has push_whitelist_usernames: ["alex", "quartermaster"] — release-bot is NOT in the list. When Engineer's #635 recovery runbook attempted Step 3 (manifest push as release-bot identity), the push got rejected with Forgejo: Not allowed to push to protected branch main. Workaround for the recovery: push from a whitelisted user (quartermaster) with author=release-bot.

In the normal automated cut flow, the workflow's release-bot manifest push would have hit the same rejection if the cut had fired properly (it didn't — release-toolkit#259's Layer-1 miss intercepted first, so this gap was second-order revealed only during recovery).

Why a separate tracker (not folded into #257)

Related to release-toolkit#257 (release-bot PAT for CI-trigger) but mechanically distinct:

Aspect #257 (PAT) THIS issue (whitelist)
Mechanism HTTP token auth for API + push Forgejo branch protection allowlist for direct-push bypass
Failure shape CI doesn't trigger after release-bot push Push outright rejected (Not allowed to push to protected branch)
Adopter setup Generate PAT, store as secret Add release-bot user to push_whitelist_usernames in repo branch protection UI/API
Workaround Manual workflow_dispatch / manual trigger commit Push from a whitelisted identity (workaround in tmux-tell#630 recovery)
Fix path Toolkit-side: switch from system token to PAT Toolkit-side: pre-flight check + adopter docs

Both are "release-bot identity needs rights the adopter must grant" but they fail differently + need different docs + different validation. Separate trackers let each surface independent scheduling, separate ACs, separate verification.

Cross-reference noted in release-toolkit#257 comment 76476 — the original framing folded the two; on reflection separate trackers carry the asymmetric failure modes better.

Proposed scope

  1. Adopter precondition docs in docs/integration.md: explicit step "Add release-bot to consumer repo's branch protection push_whitelist_usernames for default branch. Without this, path-α manifest pushes fail with Not allowed to push to protected branch and the cut substrate goes out of sync."

  2. Pre-flight check (recommended): in reusable-release.yml, probe the consumer repo's branch protection config at workflow start + fail-loud if the configured release-bot identity isn't in the whitelist. Same shape as #124's structural backstop for self-bootstrap re-pin — surface the misconfiguration as a workflow failure, not a silent runtime push rejection mid-cut.

  3. Path-γ note: under path-γ (manual-apply, per ADR-0007), manifest commits don't direct-push — they go through PR + merge. Path-γ adopters don't need the whitelist precondition. Docs should distinguish path-α vs path-γ requirements explicitly.

What this issue does NOT do

  • Does NOT touch the PAT-related machinery (that's release-toolkit#257's scope)
  • Does NOT propose changing Forgejo's branch protection semantics (workaround at the toolkit + adopter level)
  • Does NOT change the path-γ manifest lifecycle (PR-mediated, doesn't need direct-push)

Refs

  • tmux-tell#630 (empirical anchor — first toolkit-driven cut)
  • tmux-tell#635 (recovery runbook + the rejection observation in Step 3)
  • release-toolkit#257 (sibling: release-bot PAT for CI-trigger)
  • release-toolkit#259 (sibling: Layer-1 cut detection)
  • release-toolkit#258 (sibling: fragment-vs-commit dedup)
  • ADR-0007 (manifest commit lifecycle: path-α direct-push vs path-γ manual-apply)

priority/medium · size/S-M (docs + optional pre-flight check + adopter migration note)

This is gap 6 of 6 surfaced by the first toolkit-driven cut on tmux-tell. The empirical-validation gate (tmux-tell#617) is doing exactly its design intent: surface the adopter-setup substrate gaps where rubber-meets-road on the first real consumer cut.

## Empirical anchor Surfaced during the tmux-tell#630 recovery (release-toolkit#259's sibling investigation): the toolkit's path-α design assumes release-bot can direct-push manifest commits to `main` past branch protection. That requires the release-bot account to be in the consumer repo's `push_whitelist_usernames` for the default branch. tmux-tell's `main` branch protection has `push_whitelist_usernames: ["alex", "quartermaster"]` — release-bot is NOT in the list. When Engineer's #635 recovery runbook attempted Step 3 (manifest push as release-bot identity), the push got rejected with `Forgejo: Not allowed to push to protected branch main`. Workaround for the recovery: push from a whitelisted user (quartermaster) with author=release-bot. In the normal automated cut flow, the workflow's release-bot manifest push would have hit the same rejection if the cut had fired properly (it didn't — release-toolkit#259's Layer-1 miss intercepted first, so this gap was second-order revealed only during recovery). ## Why a separate tracker (not folded into #257) Related to release-toolkit#257 (release-bot PAT for CI-trigger) but **mechanically distinct**: | Aspect | #257 (PAT) | THIS issue (whitelist) | |---|---|---| | **Mechanism** | HTTP token auth for API + push | Forgejo branch protection allowlist for direct-push bypass | | **Failure shape** | CI doesn't trigger after release-bot push | Push outright rejected (`Not allowed to push to protected branch`) | | **Adopter setup** | Generate PAT, store as secret | Add release-bot user to `push_whitelist_usernames` in repo branch protection UI/API | | **Workaround** | Manual workflow_dispatch / manual trigger commit | Push from a whitelisted identity (workaround in tmux-tell#630 recovery) | | **Fix path** | Toolkit-side: switch from system token to PAT | Toolkit-side: pre-flight check + adopter docs | Both are "release-bot identity needs rights the adopter must grant" but they fail differently + need different docs + different validation. Separate trackers let each surface independent scheduling, separate ACs, separate verification. Cross-reference noted in release-toolkit#257 comment 76476 — the original framing folded the two; on reflection separate trackers carry the asymmetric failure modes better. ## Proposed scope 1. **Adopter precondition docs** in `docs/integration.md`: explicit step "Add release-bot to consumer repo's branch protection `push_whitelist_usernames` for default branch. Without this, path-α manifest pushes fail with `Not allowed to push to protected branch` and the cut substrate goes out of sync." 2. **Pre-flight check** (recommended): in `reusable-release.yml`, probe the consumer repo's branch protection config at workflow start + fail-loud if the configured release-bot identity isn't in the whitelist. Same shape as #124's structural backstop for self-bootstrap re-pin — surface the misconfiguration as a workflow failure, not a silent runtime push rejection mid-cut. 3. **Path-γ note**: under path-γ (manual-apply, per ADR-0007), manifest commits don't direct-push — they go through PR + merge. Path-γ adopters don't need the whitelist precondition. Docs should distinguish path-α vs path-γ requirements explicitly. ## What this issue does NOT do - Does NOT touch the PAT-related machinery (that's release-toolkit#257's scope) - Does NOT propose changing Forgejo's branch protection semantics (workaround at the toolkit + adopter level) - Does NOT change the path-γ manifest lifecycle (PR-mediated, doesn't need direct-push) ## Refs - tmux-tell#630 (empirical anchor — first toolkit-driven cut) - tmux-tell#635 (recovery runbook + the rejection observation in Step 3) - release-toolkit#257 (sibling: release-bot PAT for CI-trigger) - release-toolkit#259 (sibling: Layer-1 cut detection) - release-toolkit#258 (sibling: fragment-vs-commit dedup) - ADR-0007 (manifest commit lifecycle: path-α direct-push vs path-γ manual-apply) priority/medium · size/S-M (docs + optional pre-flight check + adopter migration note) This is gap **6 of 6** surfaced by the first toolkit-driven cut on tmux-tell. The empirical-validation gate (tmux-tell#617) is doing exactly its design intent: surface the adopter-setup substrate gaps where rubber-meets-road on the first real consumer cut.
bosun closed this issue 2026-06-29 22:09:35 +02:00
Sign in to join this conversation.
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
frankenbit/release-toolkit#260
No description provided.