docs(platform.ci-cd): back-merge main into develop before cutting a release
Hotfixes merged straight to `main` are not in `develop`. Nothing warns you they have diverged; the bill arrives at the next release, as a conflict on the prod branch. hiveops-remote hit this on 2026-07-20: main had 5 commits develop had never seen (OWASP suppressions, jackson-bom fix, jackson bump, cd-main rework, sonar-pr removal) against develop's 9 including the hiveops-bom 1.0.2 -> 1.0.8 bumps. Both sides had fixed the SAME jackson/spring/tomcat CVEs by different routes — main suppressed, develop bumped — so develop -> main conflicted in pom.xml with main's hotfixes at risk of being clobbered. Documents the two read-only probes (rev-list count, merge-tree exit code), the back-merge-first ordering, and why resolving a divergence inside the release PR is the wrong place for it. Also records the second-order effect: hotfixes that bypass the develop PR flow lose their issue paperwork. agent#62, bom#6 and devices#55/#60 all sat open with a shipped fix, no Verify Fix label and no milestone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -196,6 +196,43 @@ curl -X POST "$GITEA/api/v1/repos/<org>/<repo>/branch_protections" \
|
||||
# verify: GET /repos/<org>/<repo>/branches/develop → "protected": true
|
||||
```
|
||||
|
||||
## ⚠️ Back-merge `main` into `develop` before cutting a release
|
||||
|
||||
A hotfix merged straight to `main` is **not** in `develop`. Do that a few times and the two branches
|
||||
diverge silently — nothing warns you, and the bill arrives when you try to release.
|
||||
|
||||
**`hiveops-remote`, 2026-07-20.** `main` had 5 commits `develop` had never seen (OWASP suppressions,
|
||||
a jackson-bom import fix, a jackson bump, the cd-main rework, a sonar-pr removal), while `develop`
|
||||
had 9 of its own including the `hiveops-bom` 1.0.2 → 1.0.8 bumps. Both branches had fixed **the same
|
||||
jackson/spring/tomcat CVEs by different routes** — `main` *suppressed* them, `develop` *bumped the
|
||||
BOM*. The `develop` → `main` release PR conflicted in `pom.xml`, on the prod branch, with `main`'s
|
||||
hotfixes at risk of being clobbered by an older `develop` state.
|
||||
|
||||
**Probe before you assume a release is clean** — this writes nothing:
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git rev-list --count origin/develop..origin/main # >0 = unmerged hotfixes on main
|
||||
git merge-tree --write-tree origin/main origin/develop >/dev/null; echo $? # 1 = CONFLICTS
|
||||
```
|
||||
|
||||
**The fix is ordering, not cleverness:**
|
||||
|
||||
| Step | Where | Why |
|
||||
|---|---|---|
|
||||
| 1. Back-merge `main` → `develop` on a branch | targets `develop` | CI validates the resolution; nothing is prod-bound |
|
||||
| 2. Resolve the conflict there, PR it, merge | `develop` | one resolution, reviewed, reversible |
|
||||
| 3. *Then* cut `develop` → `main` | prod branch | now a clean merge |
|
||||
|
||||
⛔ **Never resolve a divergence conflict inside the release PR itself.** That puts an unreviewed
|
||||
merge resolution directly onto the branch production builds from, and a wrong `--ours`/`--theirs`
|
||||
silently reverts a shipped hotfix.
|
||||
|
||||
**The paperwork rots too.** Hotfixes that bypass the `develop` PR flow tend to lose their issue
|
||||
links: the fix merges, but the issue keeps no `Verify Fix` label and no milestone, so it reads as
|
||||
untouched forever. `hiveops-agent#62`, `hiveops-bom#6` and `hiveops-devices#55`/`#60` all sat open
|
||||
with a shipped fix for this reason. After any hotfix to `main`, go back and label the issue.
|
||||
|
||||
## 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