| name | cherry-pick-to-release |
| description | Cherry-pick a merged main-branch PR onto a MsQuic release branch (release/X.Y). |
Cherry-Pick to MsQuic Release Branch
You are helping a maintainer back-port a fix from main to one or more
MsQuic release branches (release/2.4, release/2.5, etc.).
This skill encodes the patterns the project uses.
When This Skill Activates
The user asks to cherry-pick / back-port / "CP" a PR or commit from main
onto a release branch. Typical requests:
- "Cherry-pick #5942 to release/2.4 and release/2.5"
- "Back-port the ACK underflow fix to 2.5"
- "CP this commit to the 2.4 release branch"
Inputs You Need
Before doing anything, make sure you know:
- Source: a PR number on
main (preferred) or a commit SHA on origin/main.
- Target release branch(es): e.g.
release/2.4, release/2.5. If the
user is ambiguous (e.g. "to the release branches"), ask whether they want
one branch or both, and which.
- Whether to push / open a PR. You must never push a branch or open a PR
without explicit permission. Stop and ask before any
git push or gh pr create.
If anything is missing, ask before proceeding.
Project Conventions (must follow)
PR Title
[CP] <Original PR title> (#<original_pr_number>)
Examples actually used on the release branches:
[CP] Fix underflow in ACK frame parsing #5942 (→ PR #5943 on 2.5, #5944 on 2.4)
[CP] Fix SAL annotation placement on function templates (#5895)
[CP] Free AES 256 GCM algorithm handle on cleanup (#5526)
[CP] Fix double deref in connection pool error path (#5597)
When the same fix targets multiple release branches, the title is identical
across PRs; only the target branch differs. After squash-merge, GitHub
appends the new PR number, producing commits like
[CP] Fix underflow in ACK frame parsing #5942 (#5943) on the release
branch — this is expected and required (it makes traceability trivial).
Do not invent new prefixes; stick to [CP] unless asked.
PR Body
Use the exact body of the original PR, verbatim, including the
## Description, ## Testing, and ## Documentation sections as the
original author wrote them. Do not rewrite, summarize, or augment them
with cherry-pick commentary.
No additions or modification of the original description is acceptable.
Branch Naming
Project convention (observed on most recent cherry-pick PRs):
<user>/cp_<short_description>_<target_version>_copilot
The <short_description> is a snake_case summary of the fix, mirroring
prior branches like cp_conn_pool_deref, cp_free_aes_256_gcm_handle,
underflow_fix_cp.
Use one branch per target release branch (do not try to land both
release branches from a single branch / PR).
Commits Inside the PR
- Almost always one commit — the cherry-picked commit, with its
original message preserved.
- Occasionally a second commit is acceptable if needed to make the
release branch build/pass tests (merge conflict resolutions and build fixes).
Keep these tightly scoped to enabling the cherry-pick; do not sneak in unrelated changes.
- Squash-merge erases the multi-commit structure on the release branch.
- Do not add
(cherry picked from commit X) trailers — the project
doesn't use git cherry-pick -x; traceability comes from the PR title
containing the original PR number.
Workflow
Follow these steps in order. Do not skip a phase.
Phase 1 — Identify the source commit on main
- If given a PR number, find its squash-merge commit on
origin/main:
gh pr view <orig_pr> --repo microsoft/msquic --json mergeCommit,state,title,body,baseRefName
Verify state == MERGED and baseRefName == main. If not merged, stop and tell the user — never cherry-pick an unmerged change.
- If given a SHA, confirm it is reachable from
origin/main:
git --no-pager log -1 --format="%H %s" <sha>
git --no-pager branch -r --contains <sha> | Select-String "origin/main"
- Capture the original PR title and body — you'll reuse them.
Phase 2 — Prepare the local branch
Repeat for each target release branch.
- Make sure the working tree is clean (
git status). If not, stop and ask.
- Fetch latest refs:
git fetch origin --prune.
- Create the branch from the tip of the release branch:
git checkout -b <user>/cp_<short_desc>_2_5_copilot origin/release/2.5
Phase 3 — Apply the cherry-pick
- Run
git cherry-pick <commit_sha> (no -x).
- On conflicts:
- Resolve them, keeping the spirit of the original fix.
- If the conflict is non-trivial, briefly summarize the resolution in the PR body under
## Description so reviewers know what differs from main.
- If the fix depends on code that doesn't exist on the release branch, stop and ask the user how to proceed (skip, adapt, or pull in additional commits) — do not silently rewrite the fix.
Phase 4 — Regenerate derived files (only if applicable)
Check whether the cherry-pick touches things that require regeneration. CI
will fail otherwise (check-clog.yml, check-dotnet.yml).
-
Trace / log macro changes (QuicTraceLogInfo, QuicTraceEvent,
etc., or anything under src/manifest/):
./scripts/update-sidecar.ps1
Commit any changes under src/generated/ and src/manifest/clog.sidecar as part of the same commit (or amend).
-
Public C API surface changes (anything under src/inc/, especially msquic.h):
./scripts/generate-dotnet.ps1
Commit any changes under src/cs/.
If neither applies, skip this phase.
Phase 5 — Build and run tests locally (REQUIRED)
Build and run tests locally before pushing. This is required for every
cherry-pick, regardless of whether the git cherry-pick was clean or
required conflict resolution. Do not skip this phase.
-
Build with the default TLS provider for the platform you're on:
./scripts/build.ps1 -Tls schannel # Windows
pwsh ./scripts/build.ps1 -Tls openssl # Linux
-
Run the tests that exercise the cherry-picked code. Use a
GoogleTest --Filter to keep the runtime short:
./scripts/test.ps1 -Tls schannel -Filter '<TestSuite>.<TestPattern>*'
At minimum, run:
- the tests that were added or modified by the cherry-pick, and
- the tests directly covering the changed code paths (e.g.
TlsTest.* for src/platform/tls_*, ApiTest.* for src/inc/
surface changes, HandshakeTest.* for src/core/ handshake logic).
-
If the build or the relevant tests fail on the release branch but
pass on main, stop and ask the user — do not push a broken
cherry-pick. Likely causes: missing prerequisite commits, API drift
between branches, or test infra changes that didn't get back-ported.
Capture the build and test outcome (pass/fail, number of tests run) to
mention briefly when you ask for permission to push.
Phase 6 — Push and open the PR (gated on explicit user permission)
Stop here and show a summary of the cherry-pick to the user:
original PR, target branch, branch name, PR title, build and test status.
Confirm with the user before pushing. Then:
- Push the branch:
git push -u origin <user>/cp_<short_desc>_2_5_copilot
- Open the PR as a draft (per the user's standing rule, unless they say otherwise):
gh pr create --repo microsoft/msquic `
--base release/2.5 `
--head <user>/cp_<short_desc>_2_5_copilot `
--draft `
--title "[CP] <Original title> (#<orig_pr>)" `
--body-file <path_to_body.md>
--base must be the release branch (release/2.4, release/2.5, …), not main.
- If cherry-picking to multiple release branches, repeat phases 2–6 for each branch. Open one PR per branch; mention the sibling PR number in each body so reviewers can correlate them (e.g.
Companion PR for release/2.4: #5944).
Self-Verification Checklist
Before telling the user the cherry-pick is ready:
Anti-Patterns to Avoid
- Don't cherry-pick a PR that isn't merged on
main yet.
- Don't use
git cherry-pick -x — the project doesn't include
(cherry picked from commit X) trailers in the final commit message.
- Don't bundle unrelated fixes into the same cherry-pick PR. If you
see a related-but-distinct issue, open a separate cherry-pick.
- Don't invent a new title prefix (e.g.
[BACKPORT 2.5]) — stick to
[CP] to stay consistent with the last ~2 years of cherry-pick PRs.
- Don't silently drop test changes.
- Don't rewrite, summarize, or paraphrase the original PR's
description. The body must contain the original PR's body verbatim without additions.
- Don't skip the local build / test step (Phase 5), even when the
cherry-pick applied with no conflicts. Auto-merged hunks can still
produce subtly wrong code.
- Don't push or open a PR without explicit user permission.
- Don't bump the version number as part of a cherry-pick PR —
version bumps (
Bump version to v2.5.X) are separate PRs done at
release time.
Non-Goals
- Triaging whether a fix should be cherry-picked. The user decides
that; this skill just executes the cherry-pick cleanly.
- Releasing / tagging / publishing artifacts. Those are separate
processes handled outside this skill.