Repository navigation
Commit 8ea8155
committed
feat(release): add backport-audit, a pre-release backport triage tool
Before a release or an rc is cut there was no way to answer whether
everything labelled for backport had actually reached the release
branch. The documented approach, `gh pr list --search "is:merged
label:backport"`, lists every PR ever labelled and says nothing about
whether the change arrived, which is the only thing that matters at
that point. Answering it by hand means reading the branch history per
PR, so backports go missing quietly -- and one class of them was being
lost with no draft PR and no failed check to notice.
A `backport` label does not name a branch: backport.yaml resolves the
target from getLatestRelease at merge time, so the same label means
release-1.5 on a PR merged in June and release-1.6 on one merged in
August. The audit reproduces that rule rather than trusting the label
text, treating a line as current from the publication of its first
non-prerelease release.
Landing is then established from three independent kinds of evidence:
the merge commit already being reachable from the branch (it merged
before the cut, so nothing was needed); a linked backport PR, found by
the bot's head branch or by a "Backport of #N" body reference, which is
what a hand-written backport carries; or the branch's own history --
the bot's merge subject, a commit subject identical to one of the PR's,
or an -x cherry-pick reference. What is left over is reported as
MISSING, pending on an open backport PR (including the drafts the bot
opens with the conflict committed), or dropped with whatever reason
someone recorded on the closed backport PR, since that reason is what
stops the next release re-opening the same investigation.
The exit code is computed from the results rather than as a side effect
of printing them, so it holds under --json, which is the mode a gate
would consume. Color follows cmd/check-readiness and auto-disables on a
non-TTY and under --json, so piping into jq stays clean.
Verified against an independently written prototype rather than against
its own reimplementation of these rules: over release-1.6, release-1.5
and release-1.4 the JSON is byte-identical across all 68 verdicts, as
is the text report and the exit code. That parity also covers the one
shortcut taken -- the history walk the audit already makes collects the
reachable commit oids, so a set lookup replaces one `git merge-base
--is-ancestor` per candidate per branch, 813 subprocesses for three
lines. Reachable from the branch tip is exactly what --is-ancestor
tests. It is not faster end to end: wall-clock is dominated by the gh
API calls.
Assisted-By: Claude <[email protected]>
Signed-off-by: Myasnikov Daniil <[email protected]>1 parent 67b4e23 commit 8ea8155
3 files changed
Lines changed: 927 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
0 commit comments