Skip to content

Commit 91fae2a

Browse files
authored
Automatic backporting workflow from 4.1 to 4.2 (#16271)
Motivation: We often backport PRs from 4.2 to 4.1. Because these branches are very similar, cherry-picking often applies cleanly. Modification: Add a workflow that triggers on PRs merged into 4.2 with the needs-cherry-pick-4.1 label, and tries to cherry-pick the merge commit onto 4.1 and create a pull-request. Finally, the workflow adds a comment to the original PR, linking the backport PR if the cherry-pick succeeded, or reporting failure if it didn't. The back port branch are pushed back to the netty/netty repository using the same SSH key we use to push release tags. The PRs and comments are created using a personal access token stored in a `PAT_TOKEN_READ_WRITE_PR` org secret. The PAT token must have "pull_request read/write" permission for it to work. Result: Easier to keep 4.1 up to date with bug fixes we do in 4.2. This PR attempts to fix the issues encountered with #16269
1 parent e7d3b48 commit 91fae2a

1 file changed

Lines changed: 114 additions & 0 deletions

File tree

.github/workflows/backport-41.yml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: Auto Backport to 4.1
2+
on:
3+
pull_request:
4+
types:
5+
- closed
6+
- labeled
7+
branches:
8+
- '4.2'
9+
10+
jobs:
11+
backport:
12+
if: github.event.pull_request.merged && (
13+
github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'needs-cherry-pick-4.1') ||
14+
github.event.action == 'labeled' && contains(github.event.label.name, 'needs-cherry-pick-4.1'))
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v6
19+
with:
20+
fetch-depth: '0' # Cherry-pick needs full history
21+
token: '${{ secrets.GITHUB_TOKEN }}'
22+
23+
- name: Setup git configuration
24+
run: |
25+
git config --global user.email "netty-project-bot@users.noreply.github.com"
26+
git config --global user.name "Netty Project Bot"
27+
28+
- name: Install SSH key
29+
uses: shimataro/ssh-key-action@v2
30+
with:
31+
key: ${{ secrets.SSH_PRIVATE_KEY_PEM }}
32+
known_hosts: ${{ secrets.SSH_KNOWN_HOSTS }}
33+
34+
- name: Create backport PR branch and cherry-pick
35+
id: cherry-pick
36+
run: |
37+
MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}"
38+
echo "Backporting commit: $MERGE_COMMIT"
39+
40+
BACKPORT_BRANCH="backport-pr-${{ github.event.pull_request.number }}-to-4.1"
41+
git fetch origin 4.1:4.1
42+
git checkout -b "$BACKPORT_BRANCH" 4.1
43+
44+
if git cherry-pick -x "$MERGE_COMMIT"; then
45+
echo "Cherry-pick successful"
46+
echo "success=true" >> "$GITHUB_OUTPUT"
47+
else
48+
echo "Cherry-pick failed - conflicts detected"
49+
echo "success=false" >> "$GITHUB_OUTPUT"
50+
git cherry-pick --abort
51+
exit 1
52+
fi
53+
echo "branch=$BACKPORT_BRANCH" >> "$GITHUB_OUTPUT"
54+
55+
- name: Push backport branch
56+
id: push
57+
if: steps.cherry-pick.outputs.success == 'true'
58+
run: |
59+
if ! git push origin "${{ steps.cherry-pick.outputs.branch }}"; then
60+
echo "Backport branch push failed"
61+
echo "push_failed=true" >> "$GITHUB_OUTPUT"
62+
exit 1
63+
fi
64+
65+
- name: Create pull request
66+
if: steps.cherry-pick.outputs.success == 'true'
67+
uses: actions/github-script@v8
68+
with:
69+
github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}'
70+
script: |
71+
const { data: pr } = await github.rest.pulls.create({
72+
owner: context.repo.owner,
73+
repo: context.repo.repo,
74+
title: `Backport 4.1: ${context.payload.pull_request.title}`,
75+
head: '${{ steps.cherry-pick.outputs.branch }}',
76+
base: '4.1',
77+
body: `Backport of #${context.payload.pull_request.number} to 4.1\n` +
78+
`Cherry-picked commit: ${context.payload.pull_request.merge_commit_sha}\n\n---\n` +
79+
`${context.payload.pull_request.body || ''}`
80+
});
81+
console.log(`Created backport PR: ${pr.html_url}`);
82+
await github.rest.issues.createComment({
83+
owner: context.repo.owner,
84+
repo: context.repo.repo,
85+
issue_number: context.payload.pull_request.number,
86+
body: `Backport PR for 4.1: #${pr.number}`
87+
});
88+
89+
- name: Report cherry-pick conflicts
90+
if: failure() && steps.cherry-pick.outputs.success == 'false'
91+
uses: actions/github-script@v8
92+
with:
93+
github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}'
94+
script: |
95+
await github.rest.issues.createComment({
96+
owner: context.repo.owner,
97+
repo: context.repo.repo,
98+
issue_number: context.payload.pull_request.number,
99+
body: `Could not create automatic backport PR.\nGot conflicts when cherry-picking onto 4.1.`
100+
});
101+
102+
- name: Report backport branch push failure
103+
if: failure() && steps.push.outputs.push_failed == 'true'
104+
uses: actions/github-script@v8
105+
with:
106+
github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}'
107+
script: |
108+
await github.rest.issues.createComment({
109+
owner: context.repo.owner,
110+
repo: context.repo.repo,
111+
issue_number: context.payload.pull_request.number,
112+
body: `Could not create automatic backport PR.\n`+
113+
`I could cherry-pick onto 4.1 just fine, but pushing the new branch failed.`
114+
});

0 commit comments

Comments
 (0)