Skip to content

chore(ci): handle multiple cherry-pick labels #10

chore(ci): handle multiple cherry-pick labels

chore(ci): handle multiple cherry-pick labels #10

Workflow file for this run

name: Cherry Pick
on:
pull_request_target:
branches:
- master
types: ["labeled", "closed"]
jobs:
cherry-pick:
name: Cherry Pick
if: |
github.event.pull_request.merged == true && (
(github.event.action == 'labeled' && startsWith(github.event.label.name, 'cherry-pick/')) ||
(github.event.action == 'closed' && contains(toJSON(github.event.pull_request.labels.*.name), 'cherry-pick/'))
)
runs-on: ubuntu-latest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
with:
app-id: ${{ vars.CHERRYPICK_APP_ID }}
private-key: ${{ secrets.CHERRYPICK_APP_PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
with:
fetch-depth: 0
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 and create PRs
id: cherry-pick
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
set -e
# Extract data directly from GitHub event context
MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}"
# Collect all cherry-pick/x.y labels
CHERRY_PICK_LABELS=$(echo '${{ toJSON(github.event.pull_request.labels) }}' | jq -r '.[] | select(.name | startswith("cherry-pick/")) | .name')
PR_LINKS=()
PR_ERRORS=()
for CHERRY_PICK_LABEL in $CHERRY_PICK_LABELS; do
VERSION_NUMBER="${CHERRY_PICK_LABEL#cherry-pick/}"
TARGET_BRANCH="release-$VERSION_NUMBER" # Remove 'cherry-pick/' prefix with `release-` prefix
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"
PR_ERRORS+=("$VERSION_NUMBER: Target branch '$TARGET_BRANCH' does not exist")
continue
fi
# Create new branch for cherry-pick
CHERRY_PICK_BRANCH="cherry-pick-${{ github.event.pull_request.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
PR_ERRORS+=("$VERSION_NUMBER: Cherry-pick failed due to conflicts")
git cherry-pick --abort || true
continue
fi
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
git push origin "$CHERRY_PICK_BRANCH"
# Create Pull Request
PR_URL=$(gh pr create \
--title "${{ github.event.pull_request.title }} (cherry-pick #${{ github.event.pull_request.number }} for $VERSION_NUMBER)" \
--body "Cherry-picked ${{ github.event.pull_request.title }} (#${{ github.event.pull_request.number }})
$SIGNOFF" \
--base "$TARGET_BRANCH" \
--head "$CHERRY_PICK_BRANCH" 2>&1)
if echo "$PR_URL" | grep -q '^https://'; then
PR_LINKS+=("$VERSION_NUMBER: $PR_URL")
else
SANITIZED_ERROR=$(echo "$PR_URL" | tr '\n' ' ')
PR_ERRORS+=("$VERSION_NUMBER: $SANITIZED_ERROR")
fi
done
{
echo "pr_links<<EOF"
printf "%s\n" "${PR_LINKS[@]}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
{
echo "pr_errors<<EOF"
printf "%s\n" "${PR_ERRORS[@]}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Comment with cherry-pick results
if: steps.cherry-pick.outputs.pr_links != '' || steps.cherry-pick.outputs.pr_errors != ''
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
LOGS_URL="https://github.com/argoproj/argo-cd/actions/runs/${GITHUB_RUN_ID}"
COMMENT="### Cherry-pick Results\n"
if [ -n "${{ steps.cherry_pick.outputs.pr_links }}" ]; then
COMMENT+="**Created PRs:**\n"
while read -r line; do
[ -z "$line" ] && continue
VERSION_NUMBER=$(echo "$line" | cut -d: -f1)
URL=$(echo "$line" | cut -d: -f2-)
COMMENT+="- [$VERSION_NUMBER]($URL)\n"
done <<< "${{ steps.cherry-pick.outputs.pr_links }}"
fi
if [ -n "${{ steps.cherry-pick.outputs.pr_errors }}" ]; then
COMMENT+="\n**Errors:**\n"
while read -r line; do
[ -z "$line" ] && continue
COMMENT+="- $line ([logs]($LOGS_URL))\n"
done <<< "${{ steps.cherry-pick.outputs.pr_errors }}"
fi
gh pr comment "${{ github.event.pull_request.number }}" --body "$COMMENT"