Skip to main content

backport-pr

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)), opens a draft backport PR, and documents any deviation from the original PR in its body. Use when asked to backport a PR, or port a fix to v10 (or an older major like v9). Trigger phrases include "backport", "port to v10", "release this on v10".

소스 정보

저장소
getsentry/sentry-javascript
최근 소스 활동
2026년 8월 10일 08:23
감지된 SKILL.md 언어
영어
스타
8,756
포크
1,860

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
backport-pr
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)), opens a draft backport PR, and documents any deviation from the original PR in its body. Use when asked to backport a PR, or port a fix to v10 (or an older major like v9). Trigger phrases include "backport", "port to v10", "release this on v10".
argument-hint
<pr-number-or-url> [target-major] # e.g. 18211 v10; target defaults to v10
# Backport a PR to a maintenance major branch `develop` is the current major (v11). A change that also needs to ship on a still-maintained older major has to land on that major's branch too (`v10` by default). This skill cherry-picks a merged `develop` PR onto that branch and opens a draft backport PR. ## Inputs - **PR** (required): the already-merged PR on `develop` to backport, given as either a full GitHub URL or a bare number. `gh pr view` accepts both, so pass whichever the user gave through unchanged; `<PR>` in the commands below is that value. - **Target major** (optional, default `v10`): the maintenance branch to backport onto. Accept `v10`, `10`, `v9`, etc. Normalize to a branch name like `v10`. If no PR is given, ask for it. Do not guess. ## Convention - **Base branch** = the target major branch (`v10`), which must already exist on `origin`. - **Commit + PR title**: keep the original conventional-commit prefix but namespace the scope with the major, e.g. - `fix(core): Fix logs flush starvation` -> `fix(v10/core): Fix logs flush starvation` - `feat(node): Add X` -> `feat(v10/node): Add X` - If the original has no scope (e.g. `fix: ...`), use `fix(v10): ...`. - For a multi-scope title, prefix the whole group once, not each scope: `fix(cloudflare,deno,node): ...` -> `fix(v10/cloudflare,deno,node): ...`. - **PR body** starts with a single line: `Backport of: #<original-pr-number>`. If the backported change deviates from the original in substance, append a `## Differences to the original PR` section listing each deviation and why it was necessary (see step 4). A clean cherry-pick keeps the body at the single line. - **PR is opened as a draft.** - **Working branch**: branch off the target major and give it a descriptive name. - The changes come from the PR's **squash-merge commit** on `develop` (one commit per PR), so a single `git cherry-pick` normally covers the whole PR. ## Steps ### 1. Resolve the PR and target branch ```bash # Fetch PR metadata (title, merge commit, base branch) gh pr view <PR> --json number,title,baseRefName,mergeCommit,state,url ``` Verify: - The PR is **merged** (`state == "MERGED"`). If not, stop and tell the user. - Its `baseRefName` is `develop` (or the expected parent major). If it targeted something else, confirm with the user before continuing. Grab `mergeCommit.oid` — this is the squash commit to cherry-pick. Also grab `number`: use that bare number (not the raw input) wherever `#<PR>` appears below, so `Backport of:` reads `Backport of: #18211` even when the user passed a URL. Make sure the target branch exists and is up to date: ```bash git fetch origin <major> develop git rev-parse --verify origin/<major> # errors if the branch doesn't exist ``` If `origin/<major>` doesn't exist, stop: the maintenance branch hasn't been created yet. Then check whether the change is already on the target. A freshly cut major often still shares history with `develop`, so a recent PR may already be present: ```bash git merge-base --is-ancestor <mergeCommit-oid> origin/<major> && echo "ALREADY ON <major>" ``` If it prints `ALREADY ON`, the commit is in the target's history — usually meaning nothing to backport. It's not conclusive on its own, though: a commit that was later reverted on the maintenance branch still shows as an ancestor. So treat this as a strong signal to stop and tell the user, but if you have reason to think the change was reverted, confirm the fix is actually present (e.g. `git log origin/<major> -- <a changed file>`, or grep for the change) before deciding. The cherry-pick in step 3 is the real backstop — it comes up empty only when the change is genuinely still applied. ### 2. Create the backport branch off the target major ```bash git checkout -b <branch> origin/<major> ``` ### 3. Cherry-pick the merge commit ```bash git cherry-pick <mergeCommit-oid> ``` - If git reports the pick is **empty** ("nothing to commit" / "the previous cherry-pick is now empty"), the change is already on the target. Run `git cherry-pick --abort` and stop — do not force it through with `--allow-empty`. This is the same situation the ancestor check in step 1 guards against, caught here for changes that landed via a different commit. - On **conflicts**: resolve them by consulting the original diff (`git show <oid>`). The target major may lack refactors that landed on `develop`, so adapt the change to the older code rather than force-porting it. Stage the resolved files with `git add -u` (tracked files only, so stray untracked workspace files don't get baked in), then `git cherry-pick --continue`. If the change can't be cleanly adapted, stop and surface the conflict to the user instead of guessing. Keep a running note of every adaptation you make here — which file, what you changed relative to the original, and why the target major needed it. Step 6 turns these notes into the PR body, and reconstructing them after the fact is unreliable. - If the PR was **not** squash-merged (multiple commits, e.g. a merge commit), cherry-pick each relevant commit in order, or use `git cherry-pick -m 1 <merge-oid>` for a merge commit. ### 4. Build and verify Run the repo's pre-commit checks. Do this **before** finalizing the commit in step 5, because `yarn format` writes changes to the working tree — those fixes must end up inside the backport commit, not left dangling after it (otherwise you'd push an unformatted tree and CI would fail on a commit that doesn't match your local state). ```bash yarn format yarn lint:fix yarn build:dev ``` Use `lint:fix`, not `lint` — plain `yarn lint` only reports, so auto-fixable issues would otherwise survive to fail CI. Run tests scoped to the touched packages when possible (full `yarn test` if unsure). If the target major's toolchain differs and a check fails for reasons unrelated to the change, note it for the user rather than silently skipping. ### 5. Finalize the commit (fold in verification changes) First stage the format/lint fixes. Use `git add -u` so only tracked files the cherry-pick and verification touched are staged, not unrelated local edits — sanity-check with `git status` first if `yarn format` may have reformatted files outside the backport. ```bash git add -u ``` Then finalize, depending on how step 3 went: **Single squash commit (the usual case)** — amend HEAD to both namespace the subject scope and fold in the staged fixes. The message is the namespaced title plus the one-line `Backport of:` body (this replaces the squash-merge body, matching the convention above). Do **not** add a `Co-Authored-By` line — the backport commit mirrors an existing commit, not new authored work. Build the title as in the convention: `<prefix>(<major>/<scope>):` when the original had a scope, or `<prefix>(<major>):` when it didn't (never emit an empty `<major>/`). ```bash git commit --amend -m "<namespaced-title>" -m "Backport of: #<PR>" ``` Example subject: `fix(v10/core): Fix logs flush timeout starvation with continuous logging` **Multiple commits (non-squash merge)** — leave the individual commit messages as-is; the namespaced title lives on the PR (step 7), not on each commit. Just fold the staged fixes into HEAD without rewording: ```bash git commit --amend --no-edit ``` Confirm the tree is clean so nothing is left uncommitted before you push: ```bash git status --porcelain # expect no output ``` ### 6. Diff the backport against the original PR Even a cherry-pick that reported no conflicts can end up different — `yarn format`/`lint:fix` on the older toolchain, dropped hunks, adaptations you made in step 3. Compare the final commit against the original before writing the PR body, rather than trusting your memory of step 3: ```bash git show <mergeCommit-oid> --stat git show HEAD --stat # file lists should match diff <(git show <mergeCommit-oid>) <(git show HEAD) ``` Ignore noise that carries no meaning: commit hashes/headers, hunk line offsets, surrounding context lines, and the reworded commit message. What counts as a **difference** is a change in what the patch does — a file added or missing, a hunk dropped or added, changed code or test expectations, an API adapted to the older major, a version/changelog entry that only exists on one branch. If the only differences are noise, the PR body stays the single `Backport of:` line. Otherwise draft a section like: ```markdown Backport of: #<PR> ## Differences to the original PR - `packages/core/src/foo.ts`: used `getClient()` instead of `getCurrentScope().getClient()` — v10 has no `getClient()` on the scope. - Dropped the `bar.test.ts` case for `baz()`; that helper doesn't exist on v10. ``` One bullet per deviation: what changed, and why the target major required it. Keep it factual — this is the reviewer's diff-of-the-diff, not a summary of the original PR. If a difference means the backport doesn't fully deliver the original fix, say so explicitly in the PR body **and** to the user — that's a review decision, not a footnote. ### 7. Push and open the draft PR The `Backport of: #<PR>` line references the original PR, so GitHub cross-links the two automatically — no separate comment needed. ```bash git push -u origin <branch> gh pr create \ --draft \ --base <major> \ --title "<namespaced-title>" \ --body "Backport of: #<PR>" ``` When step 6 produced a differences section, pass the multi-line body via `--body-file` instead (write it to a scratch file first) so the markdown survives intact. ## Notes - Never push directly to `develop`, `master`, or the major branch. Work only on your backport branch and open a PR. - One PR per backport. If asked to backport several PRs, repeat the whole flow per PR (each gets its own branch and draft PR). - If asked to backport to multiple majors at once (e.g. v10 and v9), do them as separate branches/PRs, each based off its own `origin/<major>`.
GitHub에서 보기