Skip to content

[integ-tests] Compute wrong_version dynamically in test_build_image_wrong_pcluster_version #23

[integ-tests] Compute wrong_version dynamically in test_build_image_wrong_pcluster_version

[integ-tests] Compute wrong_version dynamically in test_build_image_wrong_pcluster_version #23

name: Cherry-pick to branch
on:
pull_request:
types: [labeled, closed]
jobs:
cherry-pick:
# Run when:
# 1. A cherry-pick:* label is added to a merged PR — triggers immediately
# 2. A PR with cherry-pick:* labels is merged — triggers at merge time
if: >
(github.event.action == 'labeled' &&
startsWith(github.event.label.name, 'cherry-pick:') &&
github.event.pull_request.merged == true) ||
(github.event.action == 'closed' &&
github.event.pull_request.merged == true &&
contains(toJSON(github.event.pull_request.labels.*.name), 'cherry-pick:'))
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Get PR details
id: pr-info
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
SOURCE_BRANCH: ${{ github.event.pull_request.base.ref }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
EVENT_ACTION: ${{ github.event.action }}
LABEL_NAME: ${{ github.event.label.name }}
LABELS_JSON: ${{ toJSON(github.event.pull_request.labels.*.name) }}
REPO: ${{ github.repository }}
run: |
# Determine target branches from cherry-pick:* labels
if [ "${EVENT_ACTION}" = "labeled" ]; then
# Single label was just added
TARGET_BRANCHES="${LABEL_NAME#cherry-pick:}"
else
# PR was closed/merged — pick up all cherry-pick:* labels
LABELS=$(echo "${LABELS_JSON}" | jq -r '.[] | select(startswith("cherry-pick:"))')
TARGET_BRANCHES=""
for LABEL in $LABELS; do
TARGET="${LABEL#cherry-pick:}"
TARGET_BRANCHES="${TARGET_BRANCHES}${TARGET} "
done
fi
# Validate target branches contain only safe characters
for BRANCH in ${TARGET_BRANCHES}; do
if ! echo "${BRANCH}" | grep -qE '^[a-zA-Z0-9._/-]+$'; then
echo "::error::Invalid branch name '${BRANCH}' — must match [a-zA-Z0-9._/-]+"
exit 1
fi
done
# Get all commit SHAs from the PR
COMMITS=$(gh pr view "$PR_NUMBER" --repo "${REPO}" --json commits --jq '.commits[].oid' | tr '\n' ' ')
echo "commits=${COMMITS}" >> "$GITHUB_OUTPUT"
echo "source_branch=${SOURCE_BRANCH}" >> "$GITHUB_OUTPUT"
echo "pr_number=${PR_NUMBER}" >> "$GITHUB_OUTPUT"
echo "pr_title=${PR_TITLE}" >> "$GITHUB_OUTPUT"
echo "pr_author=${PR_AUTHOR}" >> "$GITHUB_OUTPUT"
echo "target_branches=${TARGET_BRANCHES}" >> "$GITHUB_OUTPUT"
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Cherry-pick and create PR(s)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMITS: ${{ steps.pr-info.outputs.commits }}
SOURCE_BRANCH: ${{ steps.pr-info.outputs.source_branch }}
PR_NUMBER: ${{ steps.pr-info.outputs.pr_number }}
PR_TITLE: ${{ steps.pr-info.outputs.pr_title }}
PR_AUTHOR: ${{ steps.pr-info.outputs.pr_author }}
TARGET_BRANCHES: ${{ steps.pr-info.outputs.target_branches }}
REPO: ${{ github.repository }}
run: |
# Fetch the PR's commits. They may live in a fork (different account),
# so they are not present in the base repo checkout. The refs/pull/*/head
# ref makes them available regardless of which fork the PR came from.
git fetch origin "refs/pull/${PR_NUMBER}/head"
HAS_FAILURE=false
for TARGET_BRANCH in ${TARGET_BRANCHES}; do
CHERRY_PICK_BRANCH="cherry-pick/pr-${PR_NUMBER}-to-${TARGET_BRANCH}"
echo "Cherry-picking commits from PR #${PR_NUMBER} to ${TARGET_BRANCH}"
echo "Commits: ${COMMITS}"
git fetch origin "${TARGET_BRANCH}"
git checkout -b "${CHERRY_PICK_BRANCH}" "origin/${TARGET_BRANCH}"
# Cherry-pick all commits in order (works for both squash and rebase)
CHERRY_PICK_FAILED=false
for COMMIT in ${COMMITS}; do
if ! git cherry-pick "${COMMIT}" --no-edit; then
CHERRY_PICK_FAILED=true
git cherry-pick --abort
break
fi
done
if [ "${CHERRY_PICK_FAILED}" = "false" ]; then
git push origin "${CHERRY_PICK_BRANCH}"
NEW_PR_URL=$(gh pr create \
--base "${TARGET_BRANCH}" \
--head "${CHERRY_PICK_BRANCH}" \
--title "Cherry-pick #${PR_NUMBER}: ${PR_TITLE}" \
--body "Automated cherry-pick of #${PR_NUMBER} from \`${SOURCE_BRANCH}\` to \`${TARGET_BRANCH}\`.
Original PR by @${PR_AUTHOR}." \
--label "cherry-pick")
gh pr comment "${PR_NUMBER}" --repo "${REPO}" \
--body "✅ Cherry-pick to \`${TARGET_BRANCH}\` opened: ${NEW_PR_URL}"
echo "✅ Cherry-pick PR to ${TARGET_BRANCH} created successfully: ${NEW_PR_URL}"
else
HAS_FAILURE=true
gh pr comment "${PR_NUMBER}" --repo "${REPO}" \
--body "⚠️ Automated cherry-pick to \`${TARGET_BRANCH}\` failed due to merge conflicts.
Please cherry-pick manually"
echo "::error::Cherry-pick to ${TARGET_BRANCH} failed due to conflicts."
fi
# Clean up for next iteration
git checkout --detach 2>/dev/null || true
git branch -D "${CHERRY_PICK_BRANCH}" 2>/dev/null || true
done
if [ "${HAS_FAILURE}" = "true" ]; then
exit 1
fi