Problem
release.yml's release-final / release-manual jobs push the version-bump commit and the
release tag directly to main:
git push origin "${REF_NAME}" # REF_NAME == main
git push origin "v${NEW_VERSION}"
main carries lock_branch: enabled and required_pull_request_reviews
(1 approval). The push is made by github-actions[bot] via secrets.GITHUB_TOKEN, which has no
bypass, so the push is rejected:
remote: - Changes must be made through a pull request.
remote: - Cannot change this locked branch
! [remote rejected] main -> main (protected branch hook declined)
Observed on run
32313394044
(Merge pull request #177 from f5devcentral/staging, 2026-08-19): Final Release v4.0.0 failed,
Publish images skipped. Note enforce_admins: false does not help — a human admin is exempt,
but the actor here is the bot, so a user-scoped exemption changes nothing.
The current workaround is to relax protection on main for the duration of a release and restore it
afterwards. That leaves main unprotected during the release window and depends on someone
remembering to restore it.
Proposal
Give the release workflow a scoped, durable bypass instead of relaxing the branch:
- Create a GitHub App (or use a fine-grained PAT held as a secret) with
contents: write on this
repo only.
- Add that identity to
bypass_pull_request_allowances on main, and — if lock_branch stays on
— to the ruleset's bypass actors list. lock_branch under the legacy protection API has no
bypass list, so this likely means migrating main to a repository ruleset, where bypass
actors are first-class.
- Change the release jobs'
actions/checkout to use that token instead of
secrets.GITHUB_TOKEN.
Acceptance
- A release run pushes the bump commit and tag to
main with lock_branch and the review
requirement still in force for everyone else.
- No human step disables protection.
- The bypass identity is scoped to this repo and to
contents: write — it cannot approve PRs.
Notes
Consider alongside the alternative in the companion issue (stop pushing to main at all). If that
one lands, this becomes unnecessary — they are competing designs, not sequential steps.
Problem
release.yml'srelease-final/release-manualjobs push the version-bump commit and therelease tag directly to
main:maincarrieslock_branch: enabledandrequired_pull_request_reviews(1 approval). The push is made by
github-actions[bot]viasecrets.GITHUB_TOKEN, which has nobypass, so the push is rejected:
Observed on run
32313394044
(
Merge pull request #177 from f5devcentral/staging, 2026-08-19):Final Release v4.0.0failed,Publish imagesskipped. Noteenforce_admins: falsedoes not help — a human admin is exempt,but the actor here is the bot, so a user-scoped exemption changes nothing.
The current workaround is to relax protection on
mainfor the duration of a release and restore itafterwards. That leaves
mainunprotected during the release window and depends on someoneremembering to restore it.
Proposal
Give the release workflow a scoped, durable bypass instead of relaxing the branch:
contents: writeon thisrepo only.
bypass_pull_request_allowancesonmain, and — iflock_branchstays on— to the ruleset's bypass actors list.
lock_branchunder the legacy protection API has nobypass list, so this likely means migrating
mainto a repository ruleset, where bypassactors are first-class.
actions/checkoutto use that token instead ofsecrets.GITHUB_TOKEN.Acceptance
mainwithlock_branchand the reviewrequirement still in force for everyone else.
contents: write— it cannot approve PRs.Notes
Consider alongside the alternative in the companion issue (stop pushing to
mainat all). If thatone lands, this becomes unnecessary — they are competing designs, not sequential steps.