Skip to content

Commit 22b8cc7

Browse files
andreiborzaclaude
andcommitted
feat(skills): Add backport-pr skill
Adds a skill that backports a merged PR to a maintenance major branch (v10 by default, with a target-major parameter for older majors like v9). It cherry-picks the PR's squash-merge commit, namespaces the commit/PR title scope (e.g. fix(core) -> fix(v10/core)), and opens a draft backport PR following the convention used for the v9 backports. Co-Authored-By: Opus 4.8 <noreply@anthropic.com>
1 parent c9fce92 commit 22b8cc7

2 files changed

Lines changed: 177 additions & 2 deletions

File tree

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
name: backport-pr
3+
description: Backport a merged PR to a maintenance major branch (v10 by default) in getsentry/sentry-javascript. Cherry-picks the PR's squash-merge commit onto the target branch, namespaces the commit/PR title scope (e.g. fix(core) -> fix(v10/core)), and opens a draft backport PR. Use when asked to backport a PR, port a fix to v10 (or an older major like v9), or cut a maintenance release change. Trigger phrases include "backport", "port to v10", "cherry-pick to the maintenance branch", "release this on v10".
4+
argument-hint: '<pr-number> [target-major] # e.g. 18211 v10; target defaults to v10'
5+
---
6+
7+
# Backport a PR to a maintenance major branch
8+
9+
`develop` is the current major (v11). Released changes now go onto the previous major's
10+
maintenance branch (`v10` by default). This skill cherry-picks a merged PR's changes onto
11+
that branch and opens a draft backport PR, following the same convention used for the v9
12+
backports.
13+
14+
## Inputs
15+
16+
- **PR number** (required): the already-merged PR on `develop` to backport.
17+
- **Target major** (optional, default `v10`): the maintenance branch to backport onto.
18+
Accept `v10`, `10`, `v9`, etc. Normalize to a branch name like `v10`.
19+
20+
If the PR number is missing, ask for it. Do not guess.
21+
22+
## Convention (learned from the v9 backports)
23+
24+
- **Base branch** = the target major branch (`v10`), which must already exist on `origin`.
25+
- **Commit + PR title**: keep the original conventional-commit prefix but namespace the
26+
scope with the major, e.g.
27+
- `fix(core): Fix logs flush starvation` -> `fix(v10/core): Fix logs flush starvation`
28+
- `feat(node): Add X` -> `feat(v10/node): Add X`
29+
- If the original has no scope (e.g. `fix: ...`), use `fix(v10): ...`.
30+
- For a multi-scope title, prefix the whole group once, not each scope:
31+
`fix(cloudflare,deno,node): ...` -> `fix(v10/cloudflare,deno,node): ...`.
32+
- **PR body** is a single line: `Backport of: #<original-pr-number>`.
33+
- **PR is opened as a draft.**
34+
- **Branch name**: `ab/<major>-<short-slug>` (personal rule is the `ab/` prefix). Derive
35+
`<short-slug>` from the original PR title, e.g. `ab/v10-fix-log-flush-starvation`.
36+
- The changes come from the PR's **squash-merge commit** on `develop` (one commit per PR),
37+
so a single `git cherry-pick` normally covers the whole PR.
38+
39+
## Steps
40+
41+
### 1. Resolve the PR and target branch
42+
43+
```bash
44+
# Fetch PR metadata (title, merge commit, base branch)
45+
gh pr view <PR> --json number,title,baseRefName,mergeCommit,state,url
46+
```
47+
48+
Verify:
49+
- The PR is **merged** (`state == "MERGED"`). If not, stop and tell the user.
50+
- Its `baseRefName` is `develop` (or the expected parent major). If it targeted something
51+
else, confirm with the user before continuing.
52+
53+
Grab `mergeCommit.oid` — this is the squash commit to cherry-pick.
54+
55+
Make sure the target branch exists and is up to date:
56+
57+
```bash
58+
git fetch origin <major> develop
59+
git rev-parse --verify origin/<major> # errors if the branch doesn't exist
60+
```
61+
62+
If `origin/<major>` doesn't exist, stop: the maintenance branch hasn't been created yet.
63+
64+
Then check the change isn't already on the target. A freshly cut major often still shares
65+
history with `develop`, so a recent PR may already be present:
66+
67+
```bash
68+
git merge-base --is-ancestor <mergeCommit-oid> origin/<major> && echo "ALREADY ON <major>"
69+
```
70+
71+
If it prints `ALREADY ON`, there's nothing to backport — stop and tell the user rather than
72+
producing an empty commit.
73+
74+
### 2. Create the backport branch off the target major
75+
76+
```bash
77+
git checkout -b ab/<major>-<slug> origin/<major>
78+
```
79+
80+
### 3. Cherry-pick the merge commit
81+
82+
```bash
83+
git cherry-pick <mergeCommit-oid>
84+
```
85+
86+
- If git reports the pick is **empty** ("nothing to commit" / "the previous cherry-pick is
87+
now empty"), the change is already on the target. Run `git cherry-pick --abort` and stop —
88+
do not force it through with `--allow-empty`. This is the same situation the ancestor check
89+
in step 1 guards against, caught here for changes that landed via a different commit.
90+
- On **conflicts**: resolve them by consulting the original diff (`git show <oid>`).
91+
The target major may lack refactors that landed on `develop`, so adapt the change to the
92+
older code rather than force-porting it. After resolving: `git add -A && git cherry-pick --continue`.
93+
If the change can't be cleanly adapted, stop and surface the conflict to the user instead
94+
of guessing.
95+
- If the PR was **not** squash-merged (multiple commits, e.g. a merge commit), cherry-pick
96+
each relevant commit in order, or use `git cherry-pick -m 1 <merge-oid>` for a merge commit.
97+
98+
### 4. Reword the commit to namespace the scope
99+
100+
Rewrite only the subject line's scope to include the major; keep the body. Do **not** add a
101+
`Co-Authored-By` line or conventional prefix beyond what's described here — the backport
102+
branch's first commit mirrors an existing commit rather than being new authored work.
103+
104+
```bash
105+
git commit --amend -m "<prefix>(<major>/<scope>): <original subject>" -m "Backport of: #<PR>"
106+
```
107+
108+
Example: `fix(v10/core): Fix logs flush timeout starvation with continuous logging`
109+
110+
### 5. Build and verify before pushing
111+
112+
Run the repo's pre-commit checks so the backport branch is green:
113+
114+
```bash
115+
yarn format
116+
yarn lint
117+
yarn build:dev
118+
```
119+
120+
Run tests scoped to the touched packages when possible (full `yarn test` if unsure). If the
121+
target major's toolchain differs and a check fails for reasons unrelated to the change, note
122+
it for the user rather than silently skipping.
123+
124+
### 6. Push and open the draft PR
125+
126+
```bash
127+
git push -u origin ab/<major>-<slug>
128+
129+
gh pr create \
130+
--draft \
131+
--base <major> \
132+
--title "<prefix>(<major>/<scope>): <original subject>" \
133+
--body "Backport of: #<PR>"
134+
```
135+
136+
### 7. Cross-link on the original PR
137+
138+
Add a note to the original PR pointing at the backport (mirrors `v9 backport: #NNNN`):
139+
140+
```bash
141+
gh pr comment <PR> --body "<major> backport: #<new-backport-pr>"
142+
```
143+
144+
## Notes
145+
146+
- Never push directly to `develop`, `master`, or the major branch. Work only on the
147+
`ab/<major>-...` branch and open a PR.
148+
- One PR per backport. If asked to backport several PRs, repeat the whole flow per PR (each
149+
gets its own branch and draft PR).
150+
- If asked to backport to multiple majors at once (e.g. v10 and v9), do them as separate
151+
branches/PRs, each based off its own `origin/<major>`.

agents.toml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ name = "bump-size-limit"
5151
source = "path:.agents/skills/bump-size-limit"
5252

5353
[[skills]]
54-
name = "upgrade-otel"
55-
source = "path:.agents/skills/upgrade-otel"
54+
name = "vendor-otel"
55+
source = "path:.agents/skills/vendor-otel"
5656

5757
[[skills]]
5858
name = "skill-scanner"
@@ -61,3 +61,27 @@ source = "getsentry/skills"
6161
[[skills]]
6262
name = "skill-creator"
6363
source = "anthropics/skills"
64+
65+
[[skills]]
66+
name = "backport-pr"
67+
source = "path:.agents/skills/backport-pr"
68+
69+
[[skills]]
70+
name = "bump-conventions"
71+
source = "path:.agents/skills/bump-conventions"
72+
73+
[[skills]]
74+
name = "linear-project-status"
75+
source = "path:.agents/skills/linear-project-status"
76+
77+
[[skills]]
78+
name = "linear-project-update"
79+
source = "path:.agents/skills/linear-project-update"
80+
81+
[[skills]]
82+
name = "track-framework-updates"
83+
source = "path:.agents/skills/track-framework-updates"
84+
85+
[[skills]]
86+
name = "write-tests"
87+
source = "path:.agents/skills/write-tests"

0 commit comments

Comments
 (0)