Skip to main content

cherrypick-to-release

Resolves a commit and cherry-picks it into one or more client release branches. By default, cherry-picks into BOTH preview and stable. Use when the user asks to cherrypick, backport, or apply a hotfix to a release branch. Optionally waits for a public commit to sync into an internal repo before creating release PRs assigned to the current on-call.

Quellinformationen

Repository
warpdotdev/client-release-agent-oss
Letzte Quellaktivität
8. Juli 2026 um 15:54
Erkannte Sprache von SKILL.md
Englisch
Sterne
3
Forks
1

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
cherrypick-to-release
description
Resolves a commit and cherry-picks it into one or more client release branches. By default, cherry-picks into BOTH preview and stable. Use when the user asks to cherrypick, backport, or apply a hotfix to a release branch. Optionally waits for a public commit to sync into an internal repo before creating release PRs assigned to the current on-call.
# cherrypick-to-release Cherry-pick a commit into release branches and open PRs assigned to the current on-call. **By default, cherry-pick into every channel in `$RELEASE_CHANNELS` (e.g. `preview` and `stable`).** Only cherry-pick into a single channel if the user explicitly names one in their prompt. ## Configuration This skill reads environment-specific values from environment variables (see the repo `README.md`): - `INTERNAL_REPO` — `owner/repo` that holds your release branches (release cherry-picks always land here). - `PUBLIC_REPO` — optional `owner/repo` of a public repo that syncs into `INTERNAL_REPO`. Only relevant if your workflow maps public commits to internal ones. - `REPO_DIR` — absolute path to your local checkout of `INTERNAL_REPO`. - `GITHUB_ORG` — GitHub org used to resolve the on-call's GitHub username. - `SLACK_BOT_TOKEN` — Slack bot token (used to look up the on-call). - `ONCALL_SLACK_GROUP` — Slack usergroup handle for the on-call (e.g. `oncall-primary`). - `RELEASE_CHANNELS` — space-separated, ordered release channels (default `preview stable`). Cherry-picks run in this order. - `RELEASE_BRANCH_PREFIX` — per-channel branch path prefix; `{channel}` is replaced with the channel name (default `{channel}_release/`). - `DEFAULT_BRANCH` — internal default branch searched for the synced commit (default `main`). - `CHERRYPICK_BRANCH_PREFIX` — prefix for created cherry-pick branches (default `cherrypick/`). - `SYNC_TRAILER_KEY` — commit trailer key identifying a synced commit's public origin (default `Repo-Sync-Origin`). **All release-branch git operations run inside `INTERNAL_REPO`.** Run `cd "$REPO_DIR"` before fetching internal history or creating cherry-picks. If `REPO_DIR` is not set, ask the user for the local path to their release repo. ## Step 1: Clarify inputs and identify the source repo Before proceeding, ensure you have: - **Channels**: Default to **all channels in `$RELEASE_CHANNELS`**. Only use a single channel if the user explicitly requested it. - **Source repo**: Determine whether the commit comes from `INTERNAL_REPO` or (if configured) `PUBLIC_REPO`. - Set `SOURCE_REPO` to the identified `owner/repo` value for the commands below. - An `INTERNAL_REPO` commit is already the synced commit the user wants to cherry-pick. Use it directly. - A `PUBLIC_REPO` commit or PR must be mapped to its synced `INTERNAL_REPO` commit in Step 2. - For a bare SHA, check whether it exists in `INTERNAL_REPO` first, then `PUBLIC_REPO`. If neither repo contains it, ask the user for the source repo or URL. - For a bare PR number, ask which repo it belongs to. - **Source commit hash**: Resolve the full SHA in the source repo. If the user gave a PR URL, get its merge commit SHA: ```bash gh pr view <PR_NUMBER> --repo "$SOURCE_REPO" --json mergeCommit --jq '.mergeCommit.oid' ``` If the PR is not merged, stop and tell the user. - **Original PR title**: If the user provided a PR URL or number, fetch the title for use in the cherry-pick PR title: ```bash gh pr view <PR_NUMBER> --repo "$SOURCE_REPO" --json title --jq '.title' ``` If the user only provided a commit hash, use the first line of the source commit message: ```bash gh api "repos/$SOURCE_REPO/commits/<SOURCE_COMMIT_HASH>" --jq '.commit.message | split("\n")[0]' ``` - **Release branch(es)**: Check whether the user specified a branch name or version string (e.g. `stable_release/v0.YYYY.MM.DD.HH.MM.stable_NN` or just `v0.YYYY.MM.DD`). If so, use it directly and **skip Step 3**. ## Step 2: Resolve the internal cherry-pick commit The final `COMMIT_HASH` must identify a commit in `INTERNAL_REPO`. Never cherry-pick a public `PUBLIC_REPO` SHA directly into an internal release branch. ### If the source is INTERNAL_REPO Set `COMMIT_HASH` to the full `INTERNAL_REPO` source commit SHA and continue to Step 3. Do not search for a corresponding public commit. ### If the source is PUBLIC_REPO (optional public↔internal sync) If your workflow syncs public commits into `INTERNAL_REPO`, the sync typically rewrites commit SHAs and adds a trailer keyed by `$SYNC_TRAILER_KEY` (default `Repo-Sync-Origin`) to the synced internal commit identifying its origin, for example: ```text Repo-Sync-Origin: <PUBLIC_REPO>@<PUBLIC_SHA> ``` From `"$REPO_DIR"`, fetch and search the internal default branch history for the synced commit. If it is not present yet, poll once per minute for up to one hour: ```bash PUBLIC_SHA=<full-public-source-commit-sha> COMMIT_HASH="" for attempt in {1..60}; do git fetch origin "$DEFAULT_BRANCH" COMMIT_HASH=$(git log FETCH_HEAD --format='%H' \ --grep="${SYNC_TRAILER_KEY}: ${PUBLIC_REPO}@$PUBLIC_SHA" -1) [[ -n "$COMMIT_HASH" ]] && break sleep 60 done ``` If `COMMIT_HASH` is still empty after the final attempt, stop and tell the user that the commit has not synced to `INTERNAL_REPO`. Do not create the cherry-picks until the synced internal commit is available. ## Step 3: Find the latest release branches **Skip this step if the user already provided a specific branch name or version.** ```bash git fetch # For each target channel, resolve its branch prefix from RELEASE_BRANCH_PREFIX # (replacing {channel}) and pick the newest matching branch. Example for `stable`: CHANNEL=stable PREFIX=$(printf '%s' "$RELEASE_BRANCH_PREFIX" | sed "s|{channel}|$CHANNEL|") git branch -r | grep -oE "${PREFIX}.*" | sort | tail -n 1 ``` Run this for each target channel in `$RELEASE_CHANNELS`. If the user gave a version string but not a full branch name, use the grep output to find the matching branch. Show the results to the user and confirm before proceeding. ## Step 4: Run the cherry-picks **Repeat the following for each target channel**, in the order listed in `$RELEASE_CHANNELS`. ```bash BRANCH_NAME=<release-branch-from-step-3> CP_BRANCH="${CHERRYPICK_BRANCH_PREFIX}${BRANCH_NAME}_${COMMIT_HASH:0:7}" git checkout $BRANCH_NAME git pull git checkout -b $CP_BRANCH git cherry-pick $COMMIT_HASH ``` **If there is a conflict**, stop and tell the user. They must resolve it manually, run `git cherry-pick --continue`, then push: ```bash git push --set-upstream origin $CP_BRANCH --no-verify ``` If no conflict, push immediately: ```bash git push --set-upstream origin $CP_BRANCH --no-verify ``` After completing the first channel, proceed to the second channel. ## Step 5: Find the current on-call Look up the current on-call automatically using the Slack API. Requires `$SLACK_BOT_TOKEN` to be set in the environment. The token needs these OAuth scopes: `usergroups:read`, `users:read`, `users:read.email`. ```bash # 1. Get the on-call usergroup ID GROUP_ID=$(curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ "https://slack.com/api/usergroups.list" | \ jq -r --arg handle "$ONCALL_SLACK_GROUP" '.usergroups[] | select(.handle==$handle) | .id') # 2. Get the current member(s) USER_ID=$(curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ "https://slack.com/api/usergroups.users.list?usergroup=$GROUP_ID" | \ jq -r '.users[0]') # 3. Resolve to name and email curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ "https://slack.com/api/users.info?user=$USER_ID" | \ jq '.user.profile | {name: .real_name, email: .email}' ``` If `$SLACK_BOT_TOKEN` is not set, ask the user: **"Who is the current on-call (`@$ONCALL_SLACK_GROUP` in Slack)?"** Once you have their name, find their GitHub username with: ```bash gh api "/orgs/$GITHUB_ORG/members" --paginate --jq '.[] | select(.login | ascii_downcase | contains("<firstname>")) | .login' ``` Confirm with the user if the match is ambiguous. ## Step 6: Open the PRs **Create a PR for each channel's cherry-pick branch.** For each: Determine the channel label from the channel name — capitalize it and append ` CP` (e.g. `preview` → `Preview CP`, `stable` → `Stable CP`): ```bash CP_LABEL="$(printf '%s' "${CHANNEL:0:1}" | tr '[:lower:]' '[:upper:]')${CHANNEL:1} CP" ``` ```bash gh pr create \ --repo "$INTERNAL_REPO" \ --base $BRANCH_NAME \ --head $CP_BRANCH \ --title "[$CP_LABEL] <original PR title>" \ --body-file .github/PULL_REQUEST_TEMPLATE/cherrypick.md \ --reviewer <oncall-github-username> ``` For example, if the original PR title is "Fix crash on startup" and the channel is preview, the title should be: `[Preview CP] Fix crash on startup`. Then share both PR URLs with the user and notify the on-call. ## Step 7: Update release status After cherry-pick PRs have been created, invoke the **post-release-status** skill to post or update the release status message in Slack. Pass the release branch from Step 3 and the Slack channel (ask the user if not already known). ## Notes - By default, cherry-pick into **every channel in `$RELEASE_CHANNELS`**. Only target a single channel if the user explicitly requests it. - An `INTERNAL_REPO` commit is authoritative. Use it directly rather than looking for a public origin. - If you use a public↔internal sync, public commits must finish syncing to `INTERNAL_REPO` before release cherry-picks begin. - After the PRs merge, the on-call must start the release-candidate build on each release branch (see the **cut-new-release-candidate** skill).
Auf GitHub ansehen