Skip to content

ci: automate backport labeling and open PRs for failed backports - #6941

Merged
Yicong-Huang merged 3 commits into
apache:mainfrom
Yicong-Huang:6940-backport-lifecycle
Jul 27, 2026
Merged

ci: automate backport labeling and open PRs for failed backports#6941
Yicong-Huang merged 3 commits into
apache:mainfrom
Yicong-Huang:6940-backport-lifecycle

Conversation

@Yicong-Huang

@Yicong-Huang Yicong-Huang commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

This PR overhauls the release-backport lifecycle so it stops depending on people remembering. Three problems today, each addressed below.

Problem 1 — Backports are forgotten. The release/* label is added by hand, so authors and committers routinely forget to request a backport, and fixes silently never reach the release branch.

Solution: Backporting becomes opt-out. A new backport-auto-label workflow labels every fix: PR into main with the configured release/* targets and requests review from each branch's release manager. .github/release-branches.yml is the single source of truth mapping each release branch to its manager and an actively-supporting flag (release/v1.2xuang7, active; release/v1.1bobbai00, inactive), parsed by a stdlib-only helper. Only actively-supporting branches are auto-labeled; an inactive branch stays a valid manual target but isn't offered by default. Remove a label to decline — a removal is remembered via the timeline, so a later edit never silently re-adds it.

Problem 2 — Failed backports are lost. When a backport conflicts, the only trace is a PR comment that sinks to the bottom and gets forgotten; nobody is on the hook to finish it. And a conflicting cherry-pick still burns the full build matrix.

Solution: The pre-merge backport is split into a fast, git-only apply-check that gates the expensive build (a conflict is reported in seconds and no longer spins up the stacks), and backport is removed from the Required Checks aggregator so it's advisory, not a merge gate. Post-merge, direct-backport-push classifies each target from that signal: green cherry-picks straight to the release branch; red (conflict, or applies-but-won't-build) auto-opens a draft backport PR fix(scope, vX.Y): … on backport/<PR>-<slug>-<target>, with the conflicted tree committed, assigned to the author with the release manager as reviewer — an actionable task instead of a lost comment.

Problem 3 — Fixes for main-only features get backported anyway. A fix for a feature that only exists on main shouldn't go to the release at all, but it still gets labeled and attempted.

Solution: Automatic feature-absent skip — before labeling a target (and again on the red path), skip it when every file the PR modifies (added files excluded) is absent on that release branch: the feature clearly isn't there. Any ambiguity keeps the label and lets the apply-check decide. For what automation can't catch (new code inside an existing file, or pure judgment), a no-backport-needed label is a hard manual veto honored end-to-end (auto-label, pre-merge precheck, and post-merge push).

Note: a red apply-check now shows as a (non-blocking) red check on the PR — the intended "this needs a manual backport" signal, not a merge blocker.

Any related issues, documentation, discussions?

Resolves #6940.

How was this PR tested?

Static: actionlint on all workflows; YAML parses; every github-script block passes node --check; bash -n on the scripts; unit-checked the parser, branch-slug derivation, fix(scope, vX.Y) title injection, and the feature-absent git guard.

End-to-end on a fork test harness (Yicong-Huang/texera, throwaway release/test-clean + release/test-conflict branches, docs-only fixes to skip the heavy build):

Scenario Result Evidence
fix: PR into main → auto-labeled with both targets PR #19
apply-check: green on clean target, red on conflicting one run
red apply-check does not block merge (Required Checks green) run
green target → cherry-picked to the release branch (author preserved) commit ef1df63 · run
red target → draft PR fix(scope, vX.Y): …, conflict markers committed, assigned to author PR #22
fix touching only files absent on the release branch → not labeled PR #20
no-backport-needed → all backport work vetoed PR #21
remove a label then edit → not re-added (opt-out remembered) PR #23

Not exercised on the fork: the request-review success path (the test manager was the PR author, so it correctly took the skip branch) and a full heavy-build green path (docs-only by design).

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.8)

Yicong-Huang and others added 2 commits July 27, 2026 12:58
Make release backports opt-out instead of easy-to-forget opt-in, and turn
a failing backport into an actionable PR instead of a comment nobody reads.

- .github/release-branches.yml: single source of truth mapping each active
  release branch to its release manager (release/v1.2 -> xuang7,
  release/v1.1 -> bobbai00), with a stdlib-only parser.
- backport-auto-label: on a fix: PR into main, label it with every configured
  release/* target and request review from that branch's release manager.
  A removed label is remembered (timeline unlabeled event), so opting out
  sticks across later edits.
- required-checks: split the pre-merge backport into a fast git-only
  apply-check that gates the expensive build matrix, and drop backport from
  the Required Checks aggregator so a red backport no longer blocks merge.
- direct-backport-push: classify each target from the apply-check/build
  signal — green cherry-picks straight to the release branch (unchanged),
  red opens a draft backport PR (fix(scope, vX.Y): ...) with the conflicted
  tree committed, assigned to the author with the manager as reviewer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A fix for a feature that only exists on main should not be backported.
Detect it automatically and add an explicit manual override, so neither
case relies on someone remembering.

- Auto-label: before labeling a target, skip it when every file the PR
  *modifies* (added files excluded) is absent on that release branch — the
  feature clearly isn't there. Any ambiguity keeps the label.
- no-backport-needed label: a hard manual override that vetoes all backport
  work — honored by auto-label, the required-checks precheck (so apply-check
  and build skip), and the post-merge discover.
- Red path: create-backport-branch applies the same feature-absent guard;
  when it fires, direct-backport-push records it on the PR instead of opening
  a doomed draft PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @mengw15
    You can notify them by mentioning @mengw15 in a comment.

@github-actions github-actions Bot added the ci changes related to CI label Jul 27, 2026
@Yicong-Huang
Yicong-Huang requested a review from xuang7 July 27, 2026 21:04
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 3 worse · ⚪ 12 noise (<±5%) · 0 without baseline

Compared against main 49f9e2c benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 480 0.293 21,122/24,556/24,556 us 🔴 +40.3% / 🔴 +69.0%
bs=100 sw=10 sl=64 1,204 0.735 82,051/116,355/116,355 us ⚪ within ±5% / 🟢 +23.5%
bs=1000 sw=10 sl=64 1,420 0.867 709,410/750,195/750,195 us ⚪ within ±5% / 🟢 +41.5%
Baseline details

Latest main 49f9e2c from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 480 tuples/sec 603 tuples/sec 767.9 tuples/sec -20.4% -37.5%
bs=10 sw=10 sl=64 MB/s 0.293 MB/s 0.368 MB/s 0.469 MB/s -20.4% -37.5%
bs=10 sw=10 sl=64 p50 21,122 us 15,058 us 12,502 us +40.3% +69.0%
bs=10 sw=10 sl=64 p95 24,556 us 25,148 us 16,234 us -2.4% +51.3%
bs=10 sw=10 sl=64 p99 24,556 us 25,148 us 18,919 us -2.4% +29.8%
bs=100 sw=10 sl=64 throughput 1,204 tuples/sec 1,205 tuples/sec 974.8 tuples/sec -0.1% +23.5%
bs=100 sw=10 sl=64 MB/s 0.735 MB/s 0.736 MB/s 0.595 MB/s -0.1% +23.5%
bs=100 sw=10 sl=64 p50 82,051 us 79,945 us 102,449 us +2.6% -19.9%
bs=100 sw=10 sl=64 p95 116,355 us 118,043 us 108,652 us -1.4% +7.1%
bs=100 sw=10 sl=64 p99 116,355 us 118,043 us 116,310 us -1.4% +0.0%
bs=1000 sw=10 sl=64 throughput 1,420 tuples/sec 1,452 tuples/sec 1,004 tuples/sec -2.2% +41.4%
bs=1000 sw=10 sl=64 MB/s 0.867 MB/s 0.886 MB/s 0.613 MB/s -2.1% +41.5%
bs=1000 sw=10 sl=64 p50 709,410 us 685,868 us 999,606 us +3.4% -29.0%
bs=1000 sw=10 sl=64 p95 750,195 us 726,383 us 1,046,770 us +3.3% -28.3%
bs=1000 sw=10 sl=64 p99 750,195 us 726,383 us 1,076,937 us +3.3% -30.3%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,416.67,200,128000,480,0.293,21122.26,24555.54,24555.54
1,100,10,64,20,1661.68,2000,1280000,1204,0.735,82050.90,116354.63,116354.63
2,1000,10,64,20,14080.79,20000,12800000,1420,0.867,709409.83,750194.77,750194.77

Add `actively-supporting` (boolean, defaults to true) to each release-branches
entry. Only actively-supporting branches are auto-labeled on new fix: PRs;
an inactive branch stays a valid manual backport target (its apply-check and
post-merge backport still run when labeled by hand) but isn't offered by
default. release/v1.2 is active, release/v1.1 is not.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Yicong-Huang
Yicong-Huang force-pushed the 6940-backport-lifecycle branch from 76b4f99 to 7c612da Compare July 27, 2026 21:17

@xuang7 xuang7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@codecov-commenter

codecov-commenter commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.94%. Comparing base (49f9e2c) to head (7c612da).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6941      +/-   ##
============================================
- Coverage     78.96%   78.94%   -0.02%     
+ Complexity     3798     3794       -4     
============================================
  Files          1161     1161              
  Lines         46084    46084              
  Branches       5110     5110              
============================================
- Hits          36388    36381       -7     
- Misses         8076     8078       +2     
- Partials       1620     1625       +5     
Flag Coverage Δ
access-control-service 70.00% <ø> (ø)
agent-service 76.76% <ø> (ø)
amber 72.19% <ø> (-0.04%) ⬇️
computing-unit-managing-service 20.49% <ø> (ø)
config-service 66.66% <ø> (ø)
file-service 67.21% <ø> (ø)
frontend 82.91% <ø> (-0.01%) ⬇️
notebook-migration-service 78.94% <ø> (ø)
pyamber 95.38% <ø> (ø)
workflow-compiling-service 55.14% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Yicong-Huang
Yicong-Huang added this pull request to the merge queue Jul 27, 2026
Merged via the queue into apache:main with commit 31f1e7b Jul 27, 2026
38 checks passed
@Yicong-Huang
Yicong-Huang deleted the 6940-backport-lifecycle branch July 27, 2026 22:49
renovate-bot pushed a commit to renovate-bot/apache-_-texera that referenced this pull request Jul 28, 2026
…ts as neutral (apache#6959)

### What changes were proposed in this PR?

Follow-up to apache#6941, improving the backport CI/PRs so they stop reading
as failures:

- **A backport conflict no longer shows a red X.** Moved backport
preflight/build out of `required-checks.yml` into a dedicated **Backport
Checks** workflow, and report a conflict as a **`neutral`** (grey) check
instead of a failing job. Still advisory, still never blocks merge
(backport was never a required context).
- **Shared precheck.** Extracted `precheck` into a reusable workflow so
the label→stack mapping lives in one place.
- **Nicer auto-opened draft backport PRs:** opened as
`github-actions[bot]`, follow the PR template, title no longer links
back to the original PR (trailing `(#N)` stripped), and the body carries
the original PR's linked issue/discussion.

### Any related issues, documentation, discussions?

Closes apache#6954. Follow-up to apache#6941.

### How was this PR tested?

`actionlint` and `node --check` clean on all workflows; the apply-check
shell/jq and the title/related-section logic were exercised locally.
Full behavior runs on a real backport-labeled PR.

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 4.8)
renovate-bot pushed a commit to renovate-bot/apache-_-texera that referenced this pull request Jul 28, 2026
### What changes were proposed in this PR?

The backport auto-label workflow
(`.github/workflows/backport-auto-label.yml`) decides, per
actively-supported release branch, whether to add a `release/*` label to
a `fix:` PR. Until now every skip was silent — visible only in the
Actions log. Its cheap "is this feature on the branch?" check compares
**exact file paths**, so a file moved or renamed after the branch was
cut reads as *absent* and the label is dropped with no signal to the
author. apache#6960 hit exactly this: its files live under `coordinator/` on
`main` but `controller/` on `release/v1.2`, so a fix that genuinely
applied to v1.2 was never labeled.

This PR makes the workflow write its reasoning back to the PR as a
single report comment:

- **One row per actively-supported release branch**, with the decision
and why:
- ✅ **labeled** — change detected on the branch; label added (and who
was requested for review);
- ⚠️ **skipped** — none of the modified files exist on the branch (the
files are listed), with a prompt to check and add the label by hand if
the fix should be backported;
  - 🚫 **declined** — a previously removed label (opt-out), not re-added.
- The comment is **upserted in place** via a hidden marker, so `edited`
re-runs update the same comment instead of stacking new ones (editing a
comment sends no notification, so re-runs stay quiet).
- It links the auto-label run, and is authored by `github-actions[bot]`
like the existing review request (no label PAT needed).
- Inactive branches and non-`fix:` PRs are unchanged (no comment); a
`no-backport-needed` PR gets a one-line note instead of the table.

Labeling behavior itself is unchanged — this only surfaces the decisions
that were already being made.

### Any related issues, documentation, discussions?

Resolves apache#6961. Follow-up to the backport lifecycle automation (apache#6941,
apache#6959). Motivated by apache#6960, which was silently not labeled for
`release/v1.2`.

### How was this PR tested?

- YAML parses and the embedded github-script passes `node --check`
(async-wrapped).
- Walked the branch/label/timeline/file-status cases against apache#6960's
real data to confirm the rows and skip reasons render as intended.
- Full end-to-end exercise needs a live `pull_request_target` event with
the org PAT/secrets, which only runs once merged.

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.8)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci changes related to CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Overhaul backport lifecycle: auto-label fix PRs, request release-manager review, auto-open PRs for failed backports

3 participants