docs(platform.ci-cd): branch lifecycle — auto-delete vs protected develop
Auto-delete-head-branch-on-merge is on fleet-wide and is correct for feature branches, but on a develop->main release PR the head IS develop, so it deleted develop itself (hit hiveops-agent twice). Documents the 2026-07-19 fix: a deliberately permissive protection rule on develop in 41/42 repos that blocks deletion and nothing else, why hiveops-deploy is excluded, and that the guard is by-name so other integration branches need the same treatment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -156,6 +156,46 @@ together on 2026-07-13 fired six workflows simultaneously and **broke runner-01'
|
||||
builds failed with the lease/network errors above. **Stagger merges**, or accept that you will be
|
||||
repairing the runner afterwards.
|
||||
|
||||
## Branch lifecycle — auto-delete on merge, and why `develop` is protected
|
||||
|
||||
**Auto-delete-head-branch-on-merge is ON in all 49 repos.** It exists to reap the feature branches
|
||||
cut *from* `develop` after they merge back, and for that it is correct — leave it on.
|
||||
|
||||
⚠️ **The trap:** on a `develop` → `main` release PR, the head branch **is `develop`**, so the same
|
||||
setting deleted `develop` itself on merge. `hiveops-agent` hit this twice; each time `develop` had to
|
||||
be recreated from `main`. Gitea has no per-branch exclusion for auto-delete — the only lever is that
|
||||
**a protected branch cannot be deleted**.
|
||||
|
||||
**Fixed 2026-07-19:** `develop` now carries a branch-protection rule in **41 of 42** repos that have
|
||||
one. The rule is deliberately permissive and **restricts nothing except deletion** —
|
||||
`enable_push: true`, no push whitelist, `required_approvals: 0`, no status checks, no
|
||||
outdated-branch blocking. Direct pushes and PR merges into `develop` behave exactly as before.
|
||||
|
||||
| Operation on `develop` | Before | After |
|
||||
|---|---|---|
|
||||
| Delete branch | `204` deleted | `403 branch protected` |
|
||||
| Direct push / write | allowed | allowed (unchanged) |
|
||||
| PR merge into `develop` | allowed | allowed (unchanged) |
|
||||
|
||||
`hiveops-deploy` is the one exclusion — it is **archived** (the API returns `423 Locked`), so no
|
||||
merge can run and there is nothing to protect against.
|
||||
|
||||
⛔ **Do not remove this protection as "redundant".** It looks like a no-op rule precisely because it
|
||||
is designed to be one; deleting it re-arms the trap above.
|
||||
|
||||
**It guards `develop` by name only.** Any other long-lived integration branch used as a PR *head*
|
||||
(release branches, recovery branches) is still exposed — protect those the same way:
|
||||
|
||||
```bash
|
||||
curl -X POST "$GITEA/api/v1/repos/<org>/<repo>/branch_protections" \
|
||||
-H "Authorization: token $TOKEN" -H 'Content-Type: application/json' \
|
||||
-d '{"branch_name":"develop","enable_push":true,"enable_push_whitelist":false,
|
||||
"required_approvals":0,"block_on_rejected_reviews":false,
|
||||
"block_on_official_review_requests":false,"block_on_outdated_branch":false,
|
||||
"enable_status_check":false}'
|
||||
# verify: GET /repos/<org>/<repo>/branches/develop → "protected": true
|
||||
```
|
||||
|
||||
## Root fragility
|
||||
|
||||
The runners are VMs on the cluster they depend on, with a single non-HA resolver — so cluster
|
||||
|
||||
Reference in New Issue
Block a user