Cherry-pick Commit to Branch #14
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| 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 |