Files
coder/scripts
Garrett Delfosse 76b35edaff ci: backport to ESR and ESR-1 release branches (#27460)
## What

Extend the backport workflow so the `backport` label fans out to **every
actively supported release channel**, not just the latest three minors.

Target branches are now the union of:

- the latest 3 `release/2.X` branches (mainline `n`, stable `n-1`,
security `n-2`), and
- the active **ESR** and **maintenance ESR (ESR-1)** branches.

The set is de-duplicated, so a branch that is both stable and ESR (today
`release/2.34`) is backported once. Dry-run against the current branch
list yields `release/2.29`, `release/2.33`, `release/2.34`,
`release/2.35`.

## Why

ESR / ESR-1 are designated biannually and can sit well below the top-3
window, so the previous `head -3` heuristic silently skipped them (e.g.
the maintenance ESR `release/2.29`). The current ESR was only covered by
coincidence when it happened to equal stable.

## Changes

- Add `scripts/release_channels/esr_versions.txt` as the single source
of truth for active ESR minors.
- `scripts/update-release-calendar.sh` now reads that file instead of a
hardcoded `ESR_VERSIONS` array (calendar output verified unchanged).
- `backport.yaml` `detect` job unions the latest 3 branches with the ESR
branches (existence-checked, warns and skips missing ones) and
de-duplicates.
- Backport PRs now get a `backport/v<version>` label, mirroring
`cherry-pick.yaml`, with `issues: write` added to create the label.

### Resilience to partial failures

Even with the independent matrix (`fail-fast: false`), a single branch's
job could previously abort without leaving anything behind, forcing the
remaining branches to be backported entirely by hand. Fixed so each
branch always ends with a PR (real or placeholder):

- Label, assignee, and reviewer are attached **after** the PR is
created, as best-effort steps. Requesting review from / assigning the PR
author is rejected by GitHub, which previously aborted `gh pr create`
under `set -e` and left no PR.
- Idempotency now keys off an existing backport **PR** rather than the
branch, and an existing backport branch is reused instead of bailing, so
a re-run recovers a branch that was pushed before its PR was opened.
- The workflow now comments on the original PR with each created
backport link, flagging conflicts that still need manual resolution.
- Conflicting cherry-picks continue to open a placeholder PR with
copy-paste resolution steps.

## Validation

- `actionlint`, `shellcheck -x`, and `zizmor` all pass.
- Re-ran `update-release-calendar.sh`; ESR statuses (`2.29 Extended
Support Release`, `2.34 Stable (ESR)`) are identical after the refactor.
- Dry-ran the detection logic against the live branch list (see set
above).

<details>
<summary>Implementation plan</summary>

# Plan: Backport to all supported release channels (mainline, stable,
security, ESR, ESR-1)

## Goal

The backport GitHub Action should open cherry-pick PRs against every
actively supported release branch:

| Channel | Meaning | Example today |

|-------------------------|-----------------------------|----------------|
| Mainline | last release (n) | `release/2.35` |
| Stable | n-1 | `release/2.34` |
| Security Support | n-2 | `release/2.33` |
| ESR | current Extended Support | `release/2.34` |
| Maintenance ESR (ESR-1) | previous ESR still patched | `release/2.29`
|

All channels map to `release/2.X` branches.

## What we targeted before

`.github/workflows/backport.yaml` took the exact `release/2.X` branches,
sorted by minor descending, and kept the top 3
(mainline/stable/security). ESR and ESR-1 are not derivable from version
ordering, so the maintenance ESR was silently skipped.

## Source of truth for ESR branches

`scripts/update-release-calendar.sh` already encoded the active ESR
minors (`ESR_VERSIONS=(29 34)`), driving the release calendar. Rather
than maintaining a second list, this list was extracted into a shared
data file consumed by both the calendar script and the workflow.

## Changes

1. Extract the ESR minors into
`scripts/release_channels/esr_versions.txt`; update
`update-release-calendar.sh` to read it.
2. Extend the `detect` job to emit the union of the top-3 branches and
one `release/2.<minor>` per ESR entry, existence-checked and
de-duplicated.
3. Add per-release `backport/v<version>` labels (with `issues: write`),
mirroring the cherry-pick workflow.

## Assumptions

- Major version is always `2` (matches existing code).
- The ESR list is maintained manually when ESR versions change.
- `cherry-pick.yaml` stays single-branch and is out of scope.
- Missing ESR branches are skipped with a warning, not a failure.

</details>

---
*Opened by Coder Agents on behalf of @f0ssel.*
2026-07-24 12:13:19 -04:00
..
2023-02-06 16:49:33 +00:00