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.

ソース情報

リポジトリ
warpdotdev/client-release-agent-oss
ソースの最終更新活動
2026年7月8日 15:54
検出された SKILL.md の言語
英語
スター
3
フォーク
1

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
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).
GitHubで見る