branching: the merge methods the orchestrator is told to use
All checks were successful
PR build (required check) / changes (pull_request) Successful in 14s
secrets-guard / encrypted (pull_request) Successful in 10s
shell-lint / shellcheck (pull_request) Successful in 11s
PR build (required check) / build-backend (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / gate (pull_request) Successful in 2s
All checks were successful
PR build (required check) / changes (pull_request) Successful in 14s
secrets-guard / encrypted (pull_request) Successful in 10s
shell-lint / shellcheck (pull_request) Successful in 11s
PR build (required check) / build-backend (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / gate (pull_request) Successful in 2s
Forgejo now allows only squash and fast-forward-only, so the three method= calls in this file named styles the API rejects: rebase for feat->dev, and merge commits for both promotions. An orchestrator following them gets a 405. The fast-forward paragraph said adopting ff-only 'needs a one-time reconciliation of the protected branches, which is the owner's decision'. That decision was taken and the reconciliation done — the trees were already identical, so it carried no content. release subset-of main subset-of dev now holds and promotions land the branches on the same SHA. The paragraph keeps the structural explanation, since it is what makes the failure mode recognisable, and now points at reconciliation as the remedy.
This commit is contained in:
parent
960c936d86
commit
fd12ad6740
1 changed files with 18 additions and 12 deletions
|
|
@ -134,7 +134,7 @@ You merge **one PR into `dev` at a time**. For each:
|
|||
3. `forge_pr_await(pr=N, until="checks_complete")` — checks on the **rebased**
|
||||
head. The run you saw before the update was for a merge base that no longer
|
||||
exists.
|
||||
4. `forge_pr_merge(pr=N, method="rebase", delete_branch=true)`.
|
||||
4. `forge_pr_merge(pr=N, method="squash", delete_branch=true)`.
|
||||
5. Only then move to the next PR.
|
||||
|
||||
`block_on_outdated_branch` is set on `dev`, so Forgejo enforces step 2 rather
|
||||
|
|
@ -150,7 +150,7 @@ context. Do not resolve a large conflict on someone else's behalf.
|
|||
Promote when `dev` is green and a coherent batch is complete — not on a timer,
|
||||
not mid-feature. `promote(from="dev", to="main")` opens the PR with the
|
||||
divergence, the conflict prediction and the changelog written into its body.
|
||||
Merge it with `method="merge"`.
|
||||
Merge it with `method="fast-forward-only"`.
|
||||
|
||||
Unready work belongs behind a feature flag, or not on `dev` yet. **Never promote
|
||||
around it with cherry-picks.**
|
||||
|
|
@ -161,17 +161,23 @@ SHAs, and merging it would fire the target's deploys for nothing.
|
|||
|
||||
### Promotion: `main` → `release`
|
||||
|
||||
Prepare with `promote`, then ask. On the owner's yes, merge with `method="merge"`
|
||||
and tag it: `forge_releases(create={tag:"v<semver>", target:"release", ...})`.
|
||||
Prepare with `promote`, then ask. On the owner's yes, merge with
|
||||
`method="fast-forward-only"` and tag it: `forge_releases(create={tag:"v<semver>", target:"release", ...})`.
|
||||
|
||||
**On fast-forward.** The written policy is that `release` moves only by
|
||||
fast-forward. It cannot today: every promotion so far has been a merge commit
|
||||
*into* the target, which the source never receives, so the branches are mutually
|
||||
divergent by construction and Forgejo will refuse a `fast-forward-only` merge —
|
||||
correctly. The style is implemented and accepted by `forge_pr_merge`; adopting
|
||||
it needs a one-time reconciliation of the protected branches, which is the
|
||||
owner's decision. Until that happens, promotions are merge commits. Do not
|
||||
attempt to "fix" this with a rebase or a force-push.
|
||||
**On fast-forward.** Both promotions move by fast-forward, and as of
|
||||
2026-08-01 that is in force rather than aspirational. It was blocked until then
|
||||
for a structural reason worth remembering: every promotion had been a merge
|
||||
commit *into* the target, which the source never receives, so the branches were
|
||||
mutually divergent by construction and Forgejo refused `fast-forward-only` —
|
||||
correctly. The one-time reconciliation the old policy was waiting for has
|
||||
happened; the trees were already identical, so it carried no content.
|
||||
|
||||
`release ⊆ main ⊆ dev` now holds, and a promotion lands the branches on the
|
||||
same SHA rather than merely the same tree. Merge commits and rebase merges are
|
||||
disabled repo-wide, so a slip fails loudly instead of quietly re-diverging the
|
||||
chain. If Forgejo refuses with "diverging branches", the target has picked up a
|
||||
commit the source lacks — reconcile it once, target into source, fast-forward.
|
||||
Do not attempt to "fix" it with a rebase or a force-push.
|
||||
|
||||
### Hotfix
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue