Skip to content

Commit 0bef340

Browse files
author
silas.jiang
committed
support auto cherry pick
Signed-off-by: silas.jiang <silas.jiang@zilliz.com>
1 parent da333ee commit 0bef340

File tree

3 files changed

+225
-0
lines changed

3 files changed

+225
-0
lines changed
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
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+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
auto-backport:
25+
if: github.event_name == 'pull_request_target' && github.event.pull_request.merged == true
26+
permissions:
27+
contents: write
28+
pull-requests: write
29+
runs-on: ubuntu-latest
30+
steps:
31+
- name: Checkout
32+
uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 0
35+
36+
- name: Configure Git
37+
run: |
38+
git config user.name "github-actions[bot]"
39+
git config user.email "github-actions[bot]@users.noreply.github.com"
40+
41+
- name: Check Restricted Paths
42+
id: check_files
43+
env:
44+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
PR_NUMBER: ${{ github.event.pull_request.number }}
46+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
47+
run: |
48+
CHANGED_FILES=$(gh pr view $PR_NUMBER --json files --jq '.files[].path')
49+
50+
if echo "$CHANGED_FILES" | grep -q "^proto_gen/"; then
51+
echo "should_skip=true" >> $GITHUB_OUTPUT
52+
gh pr comment $PR_NUMBER --body "⚠️ **Backport Skipped**
53+
Hi @$PR_AUTHOR, this PR modifies \`proto_gen/\`. Please backport manually."
54+
else
55+
echo "should_skip=false" >> $GITHUB_OUTPUT
56+
fi
57+
58+
- name: Check Target Branch Existence
59+
id: check_branch
60+
if: steps.check_files.outputs.should_skip != 'true'
61+
env:
62+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63+
PR_NUMBER: ${{ github.event.pull_request.number }}
64+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
65+
run: |
66+
LABELS=$(gh pr view $PR_NUMBER --json labels -q '.labels[].name' | grep '^backport-to-')
67+
68+
if [ -z "$LABELS" ]; then
69+
echo "should_skip=true" >> $GITHUB_OUTPUT
70+
exit 0
71+
fi
72+
73+
INVALID_BRANCHES=""
74+
while IFS= read -r label; do
75+
BRANCH_NAME=${label#backport-to-}
76+
if ! git ls-remote --exit-code --heads origin "$BRANCH_NAME" > /dev/null; then
77+
INVALID_BRANCHES="$INVALID_BRANCHES \`$BRANCH_NAME\`"
78+
fi
79+
done <<< "$LABELS"
80+
81+
if [ -n "$INVALID_BRANCHES" ]; then
82+
echo "should_skip=true" >> $GITHUB_OUTPUT
83+
gh pr comment $PR_NUMBER --body "❌ **Backport Failed (Configuration Error)**
84+
Hi @$PR_AUTHOR, I cannot find the target branch(es): $INVALID_BRANCHES.
85+
Please check your label spelling."
86+
else
87+
echo "should_skip=false" >> $GITHUB_OUTPUT
88+
fi
89+
90+
- name: Backport
91+
id: backport_step
92+
if: steps.check_files.outputs.should_skip != 'true' && steps.check_branch.outputs.should_skip != 'true'
93+
uses: korthout/backport-action@v3
94+
with:
95+
label_pattern: '^backport-to-(.*)$'
96+
pull_title: '[Backport ${target_branch}] ${pull_title}'
97+
pull_description: 'Backport of #${pull_number} to `${target_branch}`.'
98+
add_labels: 'backport'
99+
100+
- name: Label Original PR
101+
if: steps.backport_step.outcome == 'success'
102+
env:
103+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104+
PR_NUMBER: ${{ github.event.pull_request.number }}
105+
run: |
106+
gh pr edit $PR_NUMBER --add-label "backported"
107+
108+
manual-backport:
109+
if: github.event_name == 'workflow_dispatch'
110+
permissions:
111+
contents: write
112+
pull-requests: write
113+
runs-on: ubuntu-latest
114+
steps:
115+
- name: Checkout
116+
uses: actions/checkout@v4
117+
with:
118+
fetch-depth: 0
119+
120+
- name: Configure Git
121+
run: |
122+
git config user.name "github-actions[bot]"
123+
git config user.email "github-actions[bot]@users.noreply.github.com"
124+
125+
- name: Execute Manual Backport
126+
env:
127+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
128+
PR_NUMBER: ${{ inputs.pr_number }}
129+
TARGET_BRANCH: ${{ inputs.target_branch }}
130+
ACTOR: ${{ github.actor }}
131+
run: |
132+
TARGET_BRANCH=$(echo "$TARGET_BRANCH" | xargs)
133+
134+
echo "Processing Manual Backport: PR #$PR_NUMBER -> $TARGET_BRANCH"
135+
136+
PR_DATA=$(gh pr view $PR_NUMBER --json mergeCommit,title,files,author,state --jq .)
137+
MERGE_COMMIT=$(echo "$PR_DATA" | jq -r .mergeCommit.oid)
138+
PR_TITLE=$(echo "$PR_DATA" | jq -r .title)
139+
PR_AUTHOR=$(echo "$PR_DATA" | jq -r .author.login)
140+
PR_STATE=$(echo "$PR_DATA" | jq -r .state)
141+
CHANGED_FILES=$(echo "$PR_DATA" | jq -r .files[].path)
142+
143+
if [ "$PR_STATE" != "MERGED" ]; then
144+
echo "::error::PR is not merged."
145+
gh pr comment $PR_NUMBER --body "❌ **Manual Backport Failed**
146+
PR #$PR_NUMBER is not merged yet. Please merge it first."
147+
exit 1
148+
fi
149+
150+
if echo "$CHANGED_FILES" | grep -q "^proto_gen/"; then
151+
echo "::error::Skipping. PR modifies proto_gen/."
152+
gh pr comment $PR_NUMBER --body "⚠️ **Manual Backport Skipped**
153+
Hi @$PR_AUTHOR, this PR modifies \`proto_gen/\`. Please backport manually."
154+
exit 1
155+
fi
156+
157+
if ! git ls-remote --exit-code --heads origin $TARGET_BRANCH; then
158+
echo "::error::Target branch '$TARGET_BRANCH' does not exist."
159+
gh pr comment $PR_NUMBER --body "❌ **Manual Backport Failed**
160+
Target branch \`$TARGET_BRANCH\` does not exist. Please check the branch name."
161+
exit 1
162+
fi
163+
164+
NEW_BRANCH="backport-$PR_NUMBER-to-manual-$(date +%s)"
165+
166+
git checkout -b $NEW_BRANCH origin/$TARGET_BRANCH
167+
168+
CP_ARGS="-s"
169+
if git rev-parse -q --verify "$MERGE_COMMIT^2" >/dev/null; then
170+
CP_ARGS="-s -m 1"
171+
fi
172+
173+
if git cherry-pick $CP_ARGS $MERGE_COMMIT; then
174+
git push origin $NEW_BRANCH
175+
176+
NEW_PR_URL=$(gh pr create \
177+
--base $TARGET_BRANCH \
178+
--head $NEW_BRANCH \
179+
--title "[Backport $TARGET_BRANCH] $PR_TITLE" \
180+
--body "Manual backport of #$PR_NUMBER to \`$TARGET_BRANCH\`." \
181+
--label "backport" \
182+
--assignee $ACTOR)
183+
184+
gh pr comment $PR_NUMBER --body "✅ **Manual Backport Success**
185+
backported to \`$TARGET_BRANCH\` via manual trigger: $NEW_PR_URL"
186+
187+
gh pr edit $PR_NUMBER --add-label "backported"
188+
else
189+
echo "::error::Cherry-pick failed due to conflicts."
190+
git cherry-pick --abort || true
191+
192+
gh pr comment $PR_NUMBER --body "❌ **Manual Backport Failed**
193+
Hi @$PR_AUTHOR, I could not cherry-pick this to \`$TARGET_BRANCH\` due to **merge conflicts**.
194+
195+
Please perform the backport locally:
196+
\`\`\`bash
197+
git checkout $TARGET_BRANCH
198+
git pull
199+
git cherry-pick -x $MERGE_COMMIT
200+
# Resolve conflicts...
201+
git push ...
202+
\`\`\`"
203+
exit 1
204+
fi

CONTRIBUTING.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ Note: the problems, features, and questions mentioned here are not limited to Py
6767

6868
`setup.py`: Package script for PyMilvus.
6969

70+
## Backporting (Cherry-pick)
71+
72+
We use a bot to automate backporting bug fixes to branches.
73+
74+
**How to use:**
75+
Simply add a label `backport-to-<branch-name>` to your Pull Request (e.g., `backport-to-2.6`).
76+
***Success**: The bot will create a new backport PR automatically.
77+
***Failure**: The bot will comment on your PR if there are conflicts or restricted files (`proto_gen/`).
78+
79+
If the bot fails due to conflicts, please backport manually.
80+
7081
## Congratulations! You are now the contributor to the Milvus community!
7182

7283
Apart from dealing with codes and machines, you are always welcome to communicate with any member from the Milvus community. New faces join us every day, and they may as well encounter the same challenges as you faced beore. Feel free to help them. You can pass on the collaborative spirit from the assistance you acquired when you first joined the community. Let us build a collaborative, open-source, exuberant, and tolerant community together!

CONTRIBUTING_CN.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ PyMilvus 的 Github issue 列表中,打上了 [good-first-issue](https://githu
9191

9292
### 通过所有 Github Actions
9393

94+
## Cherry-pick
95+
96+
使用方法: 只需为你的 Pull Request 添加 backport-to-<branch-name> 格式的标签即可(例如:backport-to-2.6)。
97+
98+
✅ 成功:机器人会自动创建一个新的 Backport PR。
99+
100+
❌ 失败:如果存在代码冲突或修改了受限文件(如 proto_gen/),机器人会在 PR 中留言提醒。
101+
102+
如果机器人因冲突执行失败,请手动进行 Backport 操作。
103+
94104
## 恭喜你!你已经成为了 Milvus 社区的贡献者!
95105

96106
除了和代码、机器打交道,你还可以和 Milvus 社区中的人交流。社区中每天都有很多新面孔加入,当他们遇到的困难正好是你所了解的地方,请尽情的帮助这些人。回想你初次接触 Milvus 接受过的帮助,你也可以将这样的交流互助精神不断传递下去,我们一起共创一个协作、开源、开放、包容的社区。

0 commit comments

Comments
 (0)