-
Notifications
You must be signed in to change notification settings - Fork 149
181 lines (154 loc) · 6.95 KB
/
Copy pathcherry-pick-via-comment.yml
File metadata and controls
181 lines (154 loc) · 6.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
name: Cherry-pick via Comment
on:
issue_comment:
types: [created]
jobs:
cherry-pick:
# Only process comments on merged PRs that start with /cherry-pick
if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/cherry-pick') }}
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Post Start Comment
if: always()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number }}
PR_LIST: ${{ steps.cherry-pick.outputs.pr_list }}
run: |
# Build the URL to the current workflow run
workflow_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
comment="✅ Cherry-pick operation is running! Check the progress in this action:\n\n- [Workflow Run]($workflow_url)"
curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/issues/$PR_NUMBER/comments" \
-d "{\"body\": \"$comment\"}"
- name: Checkout Repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0 # Get complete history for cherry-pick
- name: Setup Git
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
- name: Get PR and Comment Info
env:
COMMENT_BODY: ${{ github.event.comment.body }}
PR_NUMBER: ${{ github.event.issue.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Comment: $COMMENT_BODY"
echo "PR Number: $PR_NUMBER"
- name: Extract Target Branches
id: extract-branches
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
# Use regex to extract branch names
if [[ "$COMMENT_BODY" =~ /cherry-pick[[:space:]]+([^,]+(,[[:space:]]*[^,]+)*) ]]; then
branches="${BASH_REMATCH[1]}"
# Convert comma-separated to space-separated
branches="${branches//,/ }"
echo "Extracted branches: $branches"
echo 2
# Remove any carriage return characters to ensure valid output format
echo "branches=$(echo "$branches" | tr -d '\r')" >> $GITHUB_OUTPUT
echo 3
else
echo "No target branches found"
echo "branches=" >> $GITHUB_OUTPUT
fi
- name: Get Merged Commit SHA
id: get-commit
env:
PR_NUMBER: ${{ github.event.issue.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
# Build correct API URL
API_URL="https://api.github.com/repos/$REPO/pulls/$PR_NUMBER"
echo "API URL: $API_URL"
# Use GitHub API to get merged PR info
response=$(curl -s "$API_URL")
# echo "Raw response: $response"
merge_commit_sha=$(echo "$response" | python3 -c "import sys, json; print(json.load(sys.stdin)['merge_commit_sha'])")
is_merged=$(echo "$response" | python3 -c "import sys, json; print(json.load(sys.stdin)['merged'])")
echo "Merge commit SHA: $merge_commit_sha"
echo "Is merged: $is_merged"
if [ -z "$merge_commit_sha" ] || [[ "$is_merged" != "True" && "$is_merged" != "true" ]]; then
echo "Error: PR is not merged or cannot get merge commit SHA"
exit 1
fi
echo "Merge commit SHA: $merge_commit_sha"
echo "commit_sha=$merge_commit_sha" >> $GITHUB_OUTPUT
- name: Cherry-pick to Target Branches
id: cherry-pick
env:
TARGET_BRANCHES: ${{ steps.extract-branches.outputs.branches }}
MERGE_COMMIT_SHA: ${{ steps.get-commit.outputs.commit_sha }}
PR_NUMBER: ${{ github.event.issue.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
created_prs=""
for branch in $TARGET_BRANCHES; do
echo "Processing branch: $branch"
# Check if target branch exists
if ! git show-ref --verify --quiet refs/remotes/origin/$branch; then
echo "Warning: Branch $branch does not exist, skipping"
continue
fi
# Create new branch name with timestamp to avoid duplicates
timestamp=$(date +%s)
new_branch="cherry-pick-$branch-pr-$PR_NUMBER-$timestamp"
# Create and switch to new branch
git checkout -b "$new_branch" "origin/$branch"
# Execute cherry-pick
if git cherry-pick -x "$MERGE_COMMIT_SHA"; then
echo "Successfully cherry-picked to $branch"
# Push new branch
git push origin "$new_branch"
# Create PR
pr_response=$(curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/pulls" \
-d "{
\"title\": \"Cherry-pick PR #$PR_NUMBER to $branch\",
\"body\": \"Automatically generated PR to cherry-pick #$PR_NUMBER to $branch branch.\n\nSource PR: #$PR_NUMBER\nSource Commit: $MERGE_COMMIT_SHA\",
\"head\": \"$new_branch\",
\"base\": \"$branch\"
}")
pr_url=$(echo "$pr_response" | grep -o '"html_url":"[^"]*' | cut -d'"' -f4)
echo "Created PR: $pr_url"
created_prs="$created_prs\n- $pr_url"
else
echo "Failed to cherry-pick to $branch, conflicts may exist"
git cherry-pick --abort
fi
# Return to initial state
git checkout -
done
# Output created PR list
if [ -n "$created_prs" ]; then
echo "pr_list=$created_prs" >> $GITHUB_OUTPUT
fi
- name: Post Result Comment
if: always()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number }}
PR_LIST: ${{ steps.cherry-pick.outputs.pr_list }}
run: |
sleep 2 # wait 2 seconds to ensure the PR is updated
if [ -n "$PR_LIST" ]; then
comment="✅ Cherry-pick operation completed!"
else
comment="❌ Cherry-pick operation did not create any PRs, please check if the target branches exist or if there are conflicts."
fi
curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/issues/$PR_NUMBER/comments" \
-d "{\"body\": \"$comment\"}"