|
1 | | ---- |
2 | | -name: Cherry-pick Commit to Branch |
3 | | - |
4 | | -'on': |
5 | | - workflow_dispatch: |
6 | | - inputs: |
7 | | - commit_id: |
8 | | - description: 'Commit SHA or ID to cherry-pick' |
9 | | - required: true |
10 | | - type: string |
11 | | - target_branch: |
12 | | - description: 'Target branch name to cherry-pick into' |
13 | | - required: true |
14 | | - type: string |
15 | | - create_pr: |
16 | | - description: 'Create a PR instead of direct cherry-pick' |
17 | | - required: false |
18 | | - type: boolean |
19 | | - default: false |
20 | | - |
21 | | -permissions: |
22 | | - contents: write |
23 | | - pull-requests: write |
24 | | - |
25 | | -jobs: |
26 | | - cherry-pick: |
27 | | - runs-on: ubuntu-latest |
28 | | - |
29 | | - # Prefer UPDATE_PROJECT_V2_PAT if present; else fall back to GITHUB_TOKEN |
30 | | - env: |
31 | | - GH_TOKEN_EFFECTIVE: ${{ secrets.UPDATE_PROJECT_V2_PAT || secrets.GITHUB_TOKEN }} |
| 1 | +env: |
| 2 | + GH_TOKEN_EFFECTIVE: ${{ secrets.UPDATE_PAT || secrets.GITHUB_TOKEN }} |
32 | 3 |
|
33 | 4 | steps: |
34 | 5 | - name: Ensure token exists |
35 | 6 | run: | |
36 | 7 | if [ -z "${GH_TOKEN_EFFECTIVE}" ]; then |
37 | | - echo "::error::No UPDATE_PROJECT_V2_PAT or GITHUB_TOKEN available. Add UPDATE_PROJECT_V2_PAT (PAT with repo scope) to Secrets, or enable Read & Write and 'Allow Actions to create PRs' for GITHUB_TOKEN." |
| 8 | + echo "::error::No UPDATE_PAT or GITHUB_TOKEN available. Add UPDATE_PAT (PAT with repo scope) to Secrets." |
38 | 9 | exit 1 |
39 | 10 | fi |
| 11 | + echo "GH_TOKEN=${GH_TOKEN_EFFECTIVE}" >> "$GITHUB_ENV" |
40 | 12 |
|
41 | 13 | - name: Install GitHub CLI |
42 | 14 | run: | |
43 | 15 | sudo apt update |
44 | 16 | sudo apt install -y gh |
45 | 17 |
|
46 | | - - name: Authenticate GitHub CLI |
47 | | - env: |
48 | | - GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }} |
49 | | - run: echo "${GH_TOKEN_EFFECTIVE}" | gh auth login --with-token |
| 18 | + # No 'gh auth login' needed — gh uses GH_TOKEN automatically |
50 | 19 |
|
51 | 20 | - name: Checkout repository |
52 | 21 | uses: actions/checkout@v4 |
53 | 22 | with: |
54 | | - # Use the effective token for fetch/push |
55 | 23 | token: ${{ env.GH_TOKEN_EFFECTIVE }} |
56 | 24 | path: repo |
57 | 25 | fetch-depth: 0 |
58 | | - |
59 | | - - name: Configure Git |
60 | | - working-directory: ./repo |
61 | | - run: | |
62 | | - git config user.name "React-Native-Windows Bot" |
63 | | - git config user.email "[email protected]" |
64 | | -
|
65 | | - - name: Checkout target branch |
66 | | - working-directory: ./repo |
67 | | - run: | |
68 | | - git fetch origin "${{ github.event.inputs.target_branch }}" |
69 | | - git checkout "${{ github.event.inputs.target_branch }}" |
70 | | - git pull --ff-only origin "${{ github.event.inputs.target_branch }}" |
71 | | -
|
72 | | - - name: Create cherry-pick branch (if creating PR) |
73 | | - if: github.event.inputs.create_pr == 'true' |
74 | | - working-directory: ./repo |
75 | | - run: | |
76 | | - COMMIT_ID="${{ github.event.inputs.commit_id }}" |
77 | | - SHORT_COMMIT_ID="${COMMIT_ID:0:8}" |
78 | | - BRANCH_NAME="cherry-pick-${SHORT_COMMIT_ID}-to-${{ github.event.inputs.target_branch }}" |
79 | | - git checkout -b "${BRANCH_NAME}" |
80 | | - echo "CHERRY_PICK_BRANCH=${BRANCH_NAME}" >> "$GITHUB_ENV" |
81 | | -
|
82 | | - - name: Cherry-pick commit |
83 | | - working-directory: ./repo |
84 | | - run: | |
85 | | - COMMIT_ID="${{ github.event.inputs.commit_id }}" |
86 | | - TARGET_BRANCH="${{ github.event.inputs.target_branch }}" |
87 | | -
|
88 | | - echo "🍒 Cherry-picking commit ${COMMIT_ID} into branch ${TARGET_BRANCH}" |
89 | | - if git cherry-pick "${COMMIT_ID}"; then |
90 | | - echo "✅ Cherry-pick successful" |
91 | | - else |
92 | | - echo "❌ Cherry-pick failed with conflicts" |
93 | | - echo "Conflict details:" |
94 | | - git status |
95 | | - # Optionally show conflicted files |
96 | | - git diff --name-only --diff-filter=U || true |
97 | | - exit 1 |
98 | | - fi |
99 | | -
|
100 | | - - name: Push changes directly to target branch (may be blocked by protected branch rules) |
101 | | - if: github.event.inputs.create_pr == 'false' |
102 | | - working-directory: ./repo |
103 | | - env: |
104 | | - GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }} |
105 | | - run: | |
106 | | - COMMIT_ID="${{ github.event.inputs.commit_id }}" |
107 | | - TARGET_BRANCH="${{ github.event.inputs.target_branch }}" |
108 | | -
|
109 | | - echo "📤 Pushing cherry-picked commit directly to ${TARGET_BRANCH}" |
110 | | - REPO_URL="https://x-access-token:${GH_TOKEN_EFFECTIVE}@github.com/${{ github.repository }}.git" |
111 | | - # Push current HEAD (target branch) without changing remote HEAD name |
112 | | - if git push "${REPO_URL}" "${TARGET_BRANCH}"; then |
113 | | - echo "✅ Successfully cherry-picked ${COMMIT_ID} to ${TARGET_BRANCH}" |
114 | | - else |
115 | | - echo "::error::Push to ${TARGET_BRANCH} failed. This branch may be protected. Consider re-running with 'create_pr: true'." |
116 | | - exit 1 |
117 | | - fi |
118 | | -
|
119 | | - - name: Push cherry-pick branch |
120 | | - if: github.event.inputs.create_pr == 'true' |
121 | | - working-directory: ./repo |
122 | | - env: |
123 | | - GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }} |
124 | | - run: | |
125 | | - BRANCH_NAME="${CHERRY_PICK_BRANCH}" |
126 | | - echo "📤 Pushing cherry-pick branch ${BRANCH_NAME}" |
127 | | - REPO_URL="https://x-access-token:${GH_TOKEN_EFFECTIVE}@github.com/${{ github.repository }}.git" |
128 | | - git push "${REPO_URL}" "${BRANCH_NAME}" |
129 | | -
|
130 | | - - name: Create Pull Request |
131 | | - if: github.event.inputs.create_pr == 'true' |
132 | | - working-directory: ./repo |
133 | | - env: |
134 | | - GH_TOKEN_EFFECTIVE: ${{ env.GH_TOKEN_EFFECTIVE }} |
135 | | - run: | |
136 | | - set -e |
137 | | - COMMIT_ID="${{ github.event.inputs.commit_id }}" |
138 | | - TARGET_BRANCH="${{ github.event.inputs.target_branch }}" |
139 | | - BRANCH_NAME="${CHERRY_PICK_BRANCH}" |
140 | | -
|
141 | | - ORIGINAL_COMMIT_MSG=$(git log --format=%s -n 1 "${COMMIT_ID}") |
142 | | - PR_TITLE="Cherry-pick ${COMMIT_ID} to ${TARGET_BRANCH}: ${ORIGINAL_COMMIT_MSG}" |
143 | | - PR_BODY="This PR cherry-picks commit ${COMMIT_ID} to the ${TARGET_BRANCH} branch. |
144 | | -
|
145 | | - **Original commit:** ${COMMIT_ID} |
146 | | - **Target branch:** ${TARGET_BRANCH} |
147 | | - **Original commit message:** ${ORIGINAL_COMMIT_MSG} |
148 | | -
|
149 | | - Please review the changes before merging." |
150 | | -
|
151 | | - echo "📋 Creating Pull Request from ${BRANCH_NAME} -> ${TARGET_BRANCH}" |
152 | | - if gh pr create \ |
153 | | - --title "${PR_TITLE}" \ |
154 | | - --body "${PR_BODY}" \ |
155 | | - --base "${TARGET_BRANCH}" \ |
156 | | - --head "${BRANCH_NAME}"; then |
157 | | - echo "✅ Successfully created PR for cherry-pick of ${COMMIT_ID} to ${TARGET_BRANCH}" |
158 | | - else |
159 | | - 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_PROJECT_V2_PAT )." |
160 | | - exit 1 |
161 | | - fi |
0 commit comments