-
Notifications
You must be signed in to change notification settings - Fork 0
124 lines (102 loc) · 4.1 KB
/
Copy pathpr-commit-summary.yml
File metadata and controls
124 lines (102 loc) · 4.1 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
name: PR commit summary
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
update-pr-body:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.ref }}
- name: Collect commit list
id: commits
shell: bash
run: |
BASE_SHA="${{ github.event.pull_request.base.sha }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
git fetch --no-tags --prune origin "${{ github.event.pull_request.base.ref }}"
commits="$(git log --pretty=format:'- %s' "${BASE_SHA}..${HEAD_SHA}")"
if [ -z "$commits" ]; then
commits="- No commits found for this pull request."
fi
printf '%s\n' "$commits" > /tmp/pr_commits.txt
- name: Update PR body preserving checklist
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
PR_TITLE: ${{ github.event.pull_request.title }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
shell: python
run: |
import os
import re
import subprocess
from pathlib import Path
pr_number = os.environ['PR_NUMBER']
repo = os.environ['REPO']
pr_title = os.environ['PR_TITLE']
head_ref = os.environ['HEAD_REF']
body = subprocess.check_output(
['gh', 'api', f'repos/{repo}/pulls/{pr_number}', '--jq', '.body // ""'],
text=True,
) or ''
linked_task_start = '<!-- AUTO-LINKED-TASK:START -->'
linked_task_end = '<!-- AUTO-LINKED-TASK:END -->'
start_marker = '<!-- AUTO-COMMIT-SUMMARY:START -->'
end_marker = '<!-- AUTO-COMMIT-SUMMARY:END -->'
commit_lines = Path('/tmp/pr_commits.txt').read_text(encoding='utf-8').strip()
summary_content = f"{commit_lines}"
task_match = re.search(
r'(?im)^\s*(?:closes|fixes|resolves)\s+#(\d+)\b',
body,
)
if task_match is None:
task_match = re.search(r'(?<!\w)#(\d+)\b', pr_title)
if task_match is None:
task_match = re.match(r'(\d+)(?:[-_/]|$)', head_ref)
if task_match is None:
task_match = re.search(r'(?<!\w)#(\d+)\b', commit_lines)
linked_task_content = ''
if task_match is not None:
linked_task_content = f'Closes #{task_match.group(1)}'
marker_pattern = re.compile(
rf'{re.escape(start_marker)}.*?{re.escape(end_marker)}',
flags=re.S,
)
replacement = f"{start_marker}\n{summary_content}\n{end_marker}"
if marker_pattern.search(body):
# Markers already present (e.g. from the PR template): fill in place.
updated = marker_pattern.sub(lambda _match: replacement, body)
else:
# No markers found: fall back to appending the block at the end.
cleaned = body.rstrip()
updated = cleaned + '\n\n' + replacement + '\n' if cleaned else replacement + '\n'
linked_task_pattern = re.compile(
rf'{re.escape(linked_task_start)}.*?{re.escape(linked_task_end)}',
flags=re.S,
)
linked_task_replacement = (
f'{linked_task_start}\n{linked_task_content}\n{linked_task_end}'
)
if linked_task_pattern.search(updated):
updated = linked_task_pattern.sub(
lambda _match: linked_task_replacement,
updated,
)
subprocess.run(
[
'gh', 'api',
f'repos/{repo}/pulls/{pr_number}',
'--method', 'PATCH',
'--field', f'body={updated}',
],
check=True,
)
print('PR description updated with commit summary.')