Skip to content

Cherry-pick Commit to Branch #14

Cherry-pick Commit to Branch

Cherry-pick Commit to Branch #14

---
name: Cherry-pick Commit to Branch
'on':
workflow_dispatch:
inputs:
commit_id:
description: 'Commit SHA or ID to cherry-pick'
required: true
type: string
target_branch:
description: 'Target branch name to cherry-pick into'
required: true
type: string
create_pr:
description: 'Create a PR instead of direct cherry-pick'
required: false
type: boolean
default: false
permissions:
contents: write
pull-requests: write
jobs:
cherry-pick:
runs-on: ubuntu-latest
# Prefer UPDATE_PAT if present; else fall back to GITHUB_TOKEN
env:
GH_TOKEN_EFFECTIVE: ${{ secrets.UPDATE_PAT || secrets.GITHUB_TOKEN }}
steps:
- name: Ensure token exists
run: |
if [ -z "${GH_TOKEN_EFFECTIVE}" ]; then
echo "::error::No UPDATE_PAT or GITHUB_TOKEN available. Add UPDATE_PAT (PAT with repo scope) to Secrets, or enable Read & Write and 'Allow Actions to create PRs' for GITHUB_TOKEN."
exit 1
fi
- name: Install GitHub CLI
run: |
sudo apt update
sudo apt install -y gh
- name: Authenticate GitHub CLI
env:
GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }}
run: echo "${GH_TOKEN_EFFECTIVE}" | gh auth login --with-token
- name: Checkout repository
uses: actions/checkout@v4
with:
# Use the effective token for fetch/push
token: ${{ env.GH_TOKEN_EFFECTIVE }}
path: repo
fetch-depth: 0
- name: Configure Git
working-directory: ./repo
run: |
git config user.name "React-Native-Windows Bot"
git config user.email "53619745+rnbot@users.noreply.github.com"
- name: Checkout target branch
working-directory: ./repo
run: |
git fetch origin "${{ github.event.inputs.target_branch }}"
git checkout "${{ github.event.inputs.target_branch }}"
git pull --ff-only origin "${{ github.event.inputs.target_branch }}"
- name: Create cherry-pick branch (if creating PR)
if: github.event.inputs.create_pr == 'true'
working-directory: ./repo
run: |
COMMIT_ID="${{ github.event.inputs.commit_id }}"
SHORT_COMMIT_ID="${COMMIT_ID:0:8}"
BRANCH_NAME="cherry-pick-${SHORT_COMMIT_ID}-to-${{ github.event.inputs.target_branch }}"
git checkout -b "${BRANCH_NAME}"
echo "CHERRY_PICK_BRANCH=${BRANCH_NAME}" >> "$GITHUB_ENV"
- name: Cherry-pick commit
working-directory: ./repo
run: |
COMMIT_ID="${{ github.event.inputs.commit_id }}"
TARGET_BRANCH="${{ github.event.inputs.target_branch }}"
echo "🍒 Cherry-picking commit ${COMMIT_ID} into branch ${TARGET_BRANCH}"
if git cherry-pick "${COMMIT_ID}"; then
echo "✅ Cherry-pick successful"
else
echo "❌ Cherry-pick failed with conflicts"
echo "Conflict details:"
git status
# Optionally show conflicted files
git diff --name-only --diff-filter=U || true
exit 1
fi
- name: Push changes directly to target branch (may be blocked by protected branch rules)
if: github.event.inputs.create_pr == 'false'
working-directory: ./repo
env:
GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }}
run: |
COMMIT_ID="${{ github.event.inputs.commit_id }}"
TARGET_BRANCH="${{ github.event.inputs.target_branch }}"
echo "📤 Pushing cherry-picked commit directly to ${TARGET_BRANCH}"
REPO_URL="https://x-access-token:${GH_TOKEN_EFFECTIVE}@github.com/${{ github.repository }}.git"
# Push current HEAD (target branch) without changing remote HEAD name
if git push "${REPO_URL}" "${TARGET_BRANCH}"; then
echo "✅ Successfully cherry-picked ${COMMIT_ID} to ${TARGET_BRANCH}"
else
echo "::error::Push to ${TARGET_BRANCH} failed. This branch may be protected. Consider re-running with 'create_pr: true'."
exit 1
fi
- name: Push cherry-pick branch
if: github.event.inputs.create_pr == 'true'
working-directory: ./repo
env:
GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }}
run: |
BRANCH_NAME="${CHERRY_PICK_BRANCH}"
echo "📤 Pushing cherry-pick branch ${BRANCH_NAME}"
REPO_URL="https://x-access-token:${GH_TOKEN_EFFECTIVE}@github.com/${{ github.repository }}.git"
git push "${REPO_URL}" "${BRANCH_NAME}"
- name: Create Pull Request
if: github.event.inputs.create_pr == 'true'
working-directory: ./repo
env:
GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }}
run: |
set -e
COMMIT_ID="${{ github.event.inputs.commit_id }}"
TARGET_BRANCH="${{ github.event.inputs.target_branch }}"
BRANCH_NAME="${CHERRY_PICK_BRANCH}"
ORIGINAL_COMMIT_MSG=$(git log --format=%s -n 1 "${COMMIT_ID}")
PR_TITLE="Cherry-pick ${COMMIT_ID} to ${TARGET_BRANCH}: ${ORIGINAL_COMMIT_MSG}"
PR_BODY="This PR cherry-picks commit ${COMMIT_ID} to the ${TARGET_BRANCH} branch.
**Original commit:** ${COMMIT_ID}
**Target branch:** ${TARGET_BRANCH}
**Original commit message:** ${ORIGINAL_COMMIT_MSG}
Please review the changes before merging."
echo "📋 Creating Pull Request from ${BRANCH_NAME} -> ${TARGET_BRANCH}"
if gh pr create \
--title "${PR_TITLE}" \
--body "${PR_BODY}" \
--base "${TARGET_BRANCH}" \
--head "${BRANCH_NAME}"; then
echo "✅ Successfully created PR for cherry-pick of ${COMMIT_ID} to ${TARGET_BRANCH}"
else
echo "::error::PR creation failed. If using GITHUB_TOKEN, ensure 'Allow GitHub Actions to create and approve pull requests' is enabled at Org/Repo (or supply UPDATE_PAT)."
exit 1
fi