Skip to content

Commit 54bf256

Browse files
author
silas.jiang
committed
support auto cherry pick
Signed-off-by: jac <jacllovey@qq.com>
1 parent da333ee commit 54bf256

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Backport
2+
3+
on:
4+
pull_request_target:
5+
types:
6+
- closed
7+
- labeled
8+
workflow_dispatch:
9+
inputs:
10+
pr_number:
11+
description: 'PR number'
12+
required: true
13+
type: string
14+
target_branch:
15+
description: 'Target branch'
16+
required: true
17+
type: string
18+
19+
jobs:
20+
auto-backport:
21+
if: github.event_name == 'pull_request_target' && github.event.pull_request.merged == true
22+
permissions:
23+
contents: write
24+
pull-requests: write
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@v4
29+
30+
- name: Check Restricted Paths
31+
id: check_files
32+
env:
33+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34+
PR_NUMBER: ${{ github.event.pull_request.number }}
35+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
36+
run: |
37+
CHANGED_FILES=$(gh pr view $PR_NUMBER --json files --jq '.files[].path')
38+
39+
if echo "$CHANGED_FILES" | grep -q "^proto_gen/"; then
40+
echo "should_skip=true" >> $GITHUB_OUTPUT
41+
gh pr comment $PR_NUMBER --body "⚠️ **Backport Skipped**
42+
43+
Hi @$PR_AUTHOR, this PR modifies \`proto_gen/\`. Please backport manually."
44+
else
45+
echo "should_skip=false" >> $GITHUB_OUTPUT
46+
fi
47+
48+
- name: Backport
49+
if: steps.check_files.outputs.should_skip != 'true'
50+
uses: korthout/backport-action@v3
51+
with:
52+
label_pattern: '^backport-to-(.*)$'
53+
pull_title: '[Backport ${target_branch}] ${pull_title}'
54+
pull_description: 'Backport of #${pull_number} to `${target_branch}`.'
55+
add_labels: 'backport'
56+
57+
manual-backport:
58+
if: github.event_name == 'workflow_dispatch'
59+
permissions:
60+
contents: write
61+
pull-requests: write
62+
runs-on: ubuntu-latest
63+
steps:
64+
- name: Checkout
65+
uses: actions/checkout@v4
66+
with:
67+
fetch-depth: 0
68+
69+
- name: Configure Git
70+
run: |
71+
git config user.name "github-actions[bot]"
72+
git config user.email "github-actions[bot]@users.noreply.github.com"
73+
74+
- name: Execute Manual Backport
75+
env:
76+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77+
PR_NUMBER: ${{ inputs.pr_number }}
78+
TARGET_BRANCH: ${{ inputs.target_branch }}
79+
run: |
80+
TARGET_BRANCH=$(echo "$TARGET_BRANCH" | xargs)
81+
82+
echo "Processing Manual Backport: PR #$PR_NUMBER -> $TARGET_BRANCH"
83+
84+
PR_DATA=$(gh pr view $PR_NUMBER --json mergeCommit,title,files,author,state --jq .)
85+
MERGE_COMMIT=$(echo "$PR_DATA" | jq -r .mergeCommit.oid)
86+
PR_TITLE=$(echo "$PR_DATA" | jq -r .title)
87+
PR_AUTHOR=$(echo "$PR_DATA" | jq -r .author.login)
88+
PR_STATE=$(echo "$PR_DATA" | jq -r .state)
89+
CHANGED_FILES=$(echo "$PR_DATA" | jq -r .files[].path)
90+
91+
if [ "$PR_STATE" != "MERGED" ]; then
92+
echo "::error::PR is not merged."
93+
gh pr comment $PR_NUMBER --body "❌ **Manual Backport Failed**
94+
PR #$PR_NUMBER is not merged yet."
95+
exit 1
96+
fi
97+
98+
if echo "$CHANGED_FILES" | grep -q "^proto_gen/"; then
99+
echo "::error::Skipping. PR modifies proto_gen/."
100+
gh pr comment $PR_NUMBER --body "⚠️ **Manual Backport Skipped**
101+
Hi @$PR_AUTHOR, this PR modifies \`proto_gen/\`. Automated handling is disabled."
102+
exit 1
103+
fi
104+
105+
if ! git ls-remote --exit-code --heads origin $TARGET_BRANCH; then
106+
echo "::error::Target branch '$TARGET_BRANCH' does not exist."
107+
gh pr comment $PR_NUMBER --body "❌ **Manual Backport Failed**
108+
Target branch \`$TARGET_BRANCH\` does not exist. Please check the branch name."
109+
exit 1
110+
fi
111+
112+
NEW_BRANCH="backport-$PR_NUMBER-to-manual-$(date +%s)"
113+
114+
git checkout -b $NEW_BRANCH origin/$TARGET_BRANCH
115+
116+
CP_ARGS="-s"
117+
if git rev-parse -q --verify "$MERGE_COMMIT^2" >/dev/null; then
118+
CP_ARGS="-s -m 1"
119+
fi
120+
121+
if git cherry-pick $CP_ARGS $MERGE_COMMIT; then
122+
git push origin $NEW_BRANCH
123+
124+
NEW_PR_URL=$(gh pr create \
125+
--base $TARGET_BRANCH \
126+
--head $NEW_BRANCH \
127+
--title "[Backport $TARGET_BRANCH] $PR_TITLE" \
128+
--body "Manual backport of #$PR_NUMBER to \`$TARGET_BRANCH\`." \
129+
--label "backport")
130+
131+
gh pr comment $PR_NUMBER --body "✅ **Manual Backport Success**
132+
Cherry-picked to \`$TARGET_BRANCH\` via manual trigger: $NEW_PR_URL"
133+
else
134+
echo "::error::Cherry-pick failed due to conflicts."
135+
git cherry-pick --abort || true
136+
137+
gh pr comment $PR_NUMBER --body "❌ **Manual Backport Failed**
138+
Hi @$PR_AUTHOR, I could not cherry-pick this to \`$TARGET_BRANCH\` due to **merge conflicts**.
139+
140+
Please perform the backport locally:
141+
\`\`\`bash
142+
git checkout $TARGET_BRANCH
143+
git pull
144+
git cherry-pick -x $MERGE_COMMIT
145+
# Resolve conflicts...
146+
git push ...
147+
\`\`\`"
148+
exit 1
149+
fi

0 commit comments

Comments
 (0)