Cherry Pick Single workflow (argoproj/argo-rollouts)
The Cherry Pick Single workflow from argoproj/argo-rollouts, explained and optimized by Latchkey.
A
CI health: A - excellent
Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Cherry Pick Single workflow from the argoproj/argo-rollouts repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
workflow (.yml)
name: Cherry Pick Single
on:
workflow_call:
inputs:
merge_commit_sha:
required: true
type: string
description: "The merge commit SHA to cherry-pick"
version_number:
required: true
type: string
description: "The version number (from cherry-pick/ label)"
pr_number:
required: true
type: string
description: "The original PR number"
pr_title:
required: true
type: string
description: "The original PR title"
secrets:
CHERRYPICK_APP_ID:
required: true
CHERRYPICK_APP_PRIVATE_KEY:
required: true
jobs:
cherry-pick:
name: Cherry Pick to ${{ inputs.version_number }}
runs-on: ubuntu-24.04
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.CHERRYPICK_APP_ID }}
private-key: ${{ secrets.CHERRYPICK_APP_PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
# Explicitly check out the base repository's default branch. This
# workflow runs on pull_request_target but never executes fork code:
# it cherry-picks an already-merged commit onto a release branch.
# Pinning ref/repository to the base avoids checkout v7's fork-PR
# guard ("Refusing to check out fork pull request code...").
ref: master
repository: ${{ github.repository }}
token: ${{ steps.generate-token.outputs.token }}
- name: Configure Git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Cherry pick commit
id: cherry-pick
run: |
set -e
MERGE_COMMIT="${{ inputs.merge_commit_sha }}"
TARGET_BRANCH="release-${{ inputs.version_number }}"
echo "π Cherry-picking commit $MERGE_COMMIT to branch $TARGET_BRANCH"
# Check if target branch exists
if ! git show-ref --verify --quiet "refs/remotes/origin/$TARGET_BRANCH"; then
echo "β Target branch '$TARGET_BRANCH' does not exist"
exit 1
fi
# Create new branch for cherry-pick
CHERRY_PICK_BRANCH="cherry-pick-${{ inputs.pr_number }}-to-${TARGET_BRANCH}"
git checkout -b "$CHERRY_PICK_BRANCH" "origin/$TARGET_BRANCH"
# Perform cherry-pick
if git cherry-pick -m 1 "$MERGE_COMMIT"; then
echo "β
Cherry-pick successful"
# Extract Signed-off-by from the cherry-pick commit
SIGNOFF=$(git log -1 --pretty=format:"%B" | grep -E '^Signed-off-by:' || echo "")
# Push the new branch. Force push to ensure that in case the original cherry-pick branch is stale,
# that the current state of the $TARGET_BRANCH + cherry-pick gets in $CHERRY_PICK_BRANCH.
git push origin -f "$CHERRY_PICK_BRANCH"
# Save data for PR creation
echo "branch_name=$CHERRY_PICK_BRANCH" >> "$GITHUB_OUTPUT"
{
echo "signoff<<EOF"
echo "$SIGNOFF"
echo "EOF"
} >> "$GITHUB_OUTPUT"
echo "target_branch=$TARGET_BRANCH" >> "$GITHUB_OUTPUT"
else
echo "β Cherry-pick failed due to conflicts"
git cherry-pick --abort
exit 1
fi
- name: Create Pull Request
run: |
# Create cherry-pick PR
TITLE="${PR_TITLE} (cherry-pick #${{ inputs.pr_number }} for ${{ inputs.version_number }})"
BODY=$(cat <<EOF
Cherry-picked ${PR_TITLE} (#${{ inputs.pr_number }})
${{ steps.cherry-pick.outputs.signoff }}
EOF
)
gh pr create \
--title "$TITLE" \
--body "$BODY" \
--base "${{ steps.cherry-pick.outputs.target_branch }}" \
--head "${{ steps.cherry-pick.outputs.branch_name }}"
# Comment on original PR
gh pr comment ${{ inputs.pr_number }} \
--body "π Cherry-pick PR created for ${{ inputs.version_number }}: #$(gh pr list --head ${{ steps.cherry-pick.outputs.branch_name }} --json number --jq '.[0].number')"
env:
PR_TITLE: ${{ inputs.pr_title }}
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- name: Comment on failure
if: failure()
run: |
gh pr comment ${{ inputs.pr_number }} \
--body "β Cherry-pick failed for ${{ inputs.version_number }}. Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Cherry Pick Single on: workflow_call: inputs: merge_commit_sha: required: true type: string description: "The merge commit SHA to cherry-pick" version_number: required: true type: string description: "The version number (from cherry-pick/ label)" pr_number: required: true type: string description: "The original PR number" pr_title: required: true type: string description: "The original PR title" secrets: CHERRYPICK_APP_ID: required: true CHERRYPICK_APP_PRIVATE_KEY: required: true jobs: cherry-pick: timeout-minutes: 30 name: Cherry Pick to ${{ inputs.version_number }} runs-on: latchkey-small steps: - name: Generate a token id: generate-token uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: app-id: ${{ secrets.CHERRYPICK_APP_ID }} private-key: ${{ secrets.CHERRYPICK_APP_PRIVATE_KEY }} - name: Checkout repository uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 # Explicitly check out the base repository's default branch. This # workflow runs on pull_request_target but never executes fork code: # it cherry-picks an already-merged commit onto a release branch. # Pinning ref/repository to the base avoids checkout v7's fork-PR # guard ("Refusing to check out fork pull request code..."). ref: master repository: ${{ github.repository }} token: ${{ steps.generate-token.outputs.token }} - name: Configure Git run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" - name: Cherry pick commit id: cherry-pick run: | set -e MERGE_COMMIT="${{ inputs.merge_commit_sha }}" TARGET_BRANCH="release-${{ inputs.version_number }}" echo "π Cherry-picking commit $MERGE_COMMIT to branch $TARGET_BRANCH" # Check if target branch exists if ! git show-ref --verify --quiet "refs/remotes/origin/$TARGET_BRANCH"; then echo "β Target branch '$TARGET_BRANCH' does not exist" exit 1 fi # Create new branch for cherry-pick CHERRY_PICK_BRANCH="cherry-pick-${{ inputs.pr_number }}-to-${TARGET_BRANCH}" git checkout -b "$CHERRY_PICK_BRANCH" "origin/$TARGET_BRANCH" # Perform cherry-pick if git cherry-pick -m 1 "$MERGE_COMMIT"; then echo "β Cherry-pick successful" # Extract Signed-off-by from the cherry-pick commit SIGNOFF=$(git log -1 --pretty=format:"%B" | grep -E '^Signed-off-by:' || echo "") # Push the new branch. Force push to ensure that in case the original cherry-pick branch is stale, # that the current state of the $TARGET_BRANCH + cherry-pick gets in $CHERRY_PICK_BRANCH. git push origin -f "$CHERRY_PICK_BRANCH" # Save data for PR creation echo "branch_name=$CHERRY_PICK_BRANCH" >> "$GITHUB_OUTPUT" { echo "signoff<<EOF" echo "$SIGNOFF" echo "EOF" } >> "$GITHUB_OUTPUT" echo "target_branch=$TARGET_BRANCH" >> "$GITHUB_OUTPUT" else echo "β Cherry-pick failed due to conflicts" git cherry-pick --abort exit 1 fi - name: Create Pull Request run: | # Create cherry-pick PR TITLE="${PR_TITLE} (cherry-pick #${{ inputs.pr_number }} for ${{ inputs.version_number }})" BODY=$(cat <<EOF Cherry-picked ${PR_TITLE} (#${{ inputs.pr_number }}) ${{ steps.cherry-pick.outputs.signoff }} EOF ) gh pr create \ --title "$TITLE" \ --body "$BODY" \ --base "${{ steps.cherry-pick.outputs.target_branch }}" \ --head "${{ steps.cherry-pick.outputs.branch_name }}" # Comment on original PR gh pr comment ${{ inputs.pr_number }} \ --body "π Cherry-pick PR created for ${{ inputs.version_number }}: #$(gh pr list --head ${{ steps.cherry-pick.outputs.branch_name }} --json number --jq '.[0].number')" env: PR_TITLE: ${{ inputs.pr_title }} GH_TOKEN: ${{ steps.generate-token.outputs.token }} - name: Comment on failure if: failure() run: | gh pr comment ${{ inputs.pr_number }} \ --body "β Cherry-pick failed for ${{ inputs.version_number }}. Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details." env: GH_TOKEN: ${{ steps.generate-token.outputs.token }}
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.