Skip to content

Commit a022ad6

Browse files
author
Leleat
committed
ci: link PR in commit messages
This is inspired by marge bot's feature. It will link the PR in the commit messages and merge the PR when the label `auto-merge` is added. It's allows you to jump to the PR from the commit message (terminal) to see the surrounding disscussion of the PR.
1 parent c53b0a1 commit a022ad6

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Link and merge PR
2+
run-name: Link and merge PR
3+
4+
on:
5+
pull_request:
6+
types:
7+
- labeled
8+
9+
jobs:
10+
auto-merge:
11+
if: github.event.label.name == 'auto-merge'
12+
runs-on: ubuntu-latest
13+
permissions:
14+
# Permission to merge the pr
15+
contents: write
16+
# Permission to update the pr
17+
pull-requests: write
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
# We need to check out the correct ref (instead of the default one).
24+
# Otherwise, there will be an extra merge commit: https://github.com/ad-m/github-push-action/issues/20
25+
ref: refs/heads/${{ github.head_ref }}
26+
- name: Install git-filter-repo
27+
run: pip install git-filter-repo
28+
- name: Link PR in commit messages
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
run: |
32+
git filter-repo --message-callback '
33+
import re
34+
35+
trailer = b"Part-of: ${{ github.event.pull_request.html_url }}"
36+
lines = message.strip().splitlines()
37+
last_line_is_trailer = lines and re.search(b"^\w+: ", lines[-1]) is not None
38+
39+
if not lines:
40+
return b"\n" + trailer
41+
elif last_line_is_trailer:
42+
return message.strip() + b"\n" + trailer
43+
else:
44+
return message.strip() + b"\n\n" + trailer
45+
' --refs ${{github.event.pull_request.base.sha}}..HEAD
46+
47+
git push -f origin HEAD:${{ github.head_ref }}
48+
- name: Merge PR
49+
id: merge
50+
continue-on-error: true
51+
env:
52+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53+
run: |
54+
SUBJECT="Merging #${{ github.event.pull_request.number }} from ${{ github.actor }}/${{ github.head_ref}}"
55+
BODY="${{ github.event.pull_request.title }}
56+
57+
Part-of: ${{ github.event.pull_request.html_url }}"
58+
59+
# There seems to be something racey where the PR can't be merged yet
60+
# after force-pushing. Retry a few times.
61+
for i in {1..5}; do
62+
if gh pr merge ${{ github.event.pull_request.number }} --auto --merge --delete-branch --subject "$SUBJECT" --body "$BODY"; then
63+
break
64+
fi
65+
66+
if [[ $i -eq 5 ]]; then
67+
echo "Failed to merge PR"
68+
exit 1
69+
fi
70+
71+
echo "Failed to merge PR... retrying in 5 seconds"
72+
73+
sleep 5
74+
done
75+
- name: Merge failed, restore original commits
76+
if: steps.merge.outcome != 'success'
77+
env:
78+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
79+
run: |
80+
git reset --hard ${{ github.event.pull_request.head.sha }}
81+
git push -f origin HEAD:${{ github.head_ref }}
82+
83+
gh issue edit ${{ github.event.pull_request.number }} --remove-label auto-merge
84+
85+
echo "Failed to merge PR, restored original commits..."
86+
87+
exit 1

0 commit comments

Comments
 (0)