-
Notifications
You must be signed in to change notification settings - Fork 1
189 lines (159 loc) · 5.95 KB
/
Copy pathrelease-pr.yml
File metadata and controls
189 lines (159 loc) · 5.95 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
name: Sync Release Pull Request
on:
push:
branches:
- develop
jobs:
sync-release-pr:
name: Create or update develop → main PR
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Open or update release PR
env:
GH_TOKEN: ${{ secrets.RELEASE_PR_TOKEN }}
DEFAULT_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_TITLE: "Release: develop → main"
GITHUB_REPOSITORY: ${{ github.repository }}
run: |
set -euo pipefail
export GH_TOKEN="${GH_TOKEN:-$DEFAULT_GH_TOKEN}"
git fetch origin main --prune
COMMIT_COUNT="$(git rev-list --count origin/main..HEAD)"
if [ "$COMMIT_COUNT" -eq 0 ]; then
echo "No commits to merge from develop into main. Skipping release PR sync."
exit 0
fi
BODY_FILE="$(mktemp)"
export BODY_FILE
python3 - <<'PY'
import os
import subprocess
body_file_path = os.environ["BODY_FILE"]
repository = os.environ["GITHUB_REPOSITORY"]
# Get commits that are in develop but not in main
log = subprocess.check_output(
["git", "log", "--pretty=format:%s (%h)", "origin/main..HEAD", "--no-merges"],
text=True,
).strip().splitlines()
# Filter out empty lines
log = [line for line in log if line.strip()]
max_items = 60
items = log[:max_items]
extra = max(len(log) - len(items), 0)
if items:
bullets = [f"- {line}" for line in items]
if extra:
bullets.append(f"- ...and {extra} more commits")
else:
bullets = ["- No new changes since last release"]
summary_lines = [
"This PR syncs `develop` into `main` for the next production release.",
f"It includes **{len(log)}** commit(s) ahead of `main`.",
]
compare_url = f"https://github.com/{repository}/compare/main...develop"
final_lines = [
"## Release Notes",
"",
*summary_lines,
"",
"## Changes",
"",
*bullets,
"",
"## Compare",
"",
f"- Full diff: {compare_url}",
]
with open(body_file_path, "w", encoding="utf-8") as f:
f.write("\n".join(final_lines).rstrip() + "\n")
# Debug: print the generated body
print("Generated PR body:")
print("-" * 40)
with open(body_file_path, "r") as f:
print(f.read())
print("-" * 40)
PY
PR_NUMBER="$(gh pr list --base main --head develop --state open --json number --jq '.[0].number // empty')"
if [ -n "$PR_NUMBER" ]; then
echo "Updating existing PR #$PR_NUMBER"
set +e
EDIT_OUTPUT="$(
gh pr edit "$PR_NUMBER" \
--title "$PR_TITLE" \
--body-file "$BODY_FILE" 2>&1
)"
EDIT_EXIT=$?
set -e
if [ "$EDIT_EXIT" -eq 0 ]; then
echo "$EDIT_OUTPUT"
exit 0
fi
if echo "$EDIT_OUTPUT" | grep -q "Resource not accessible by personal access token"; then
echo "::warning::RELEASE_PR_TOKEN could not edit PR. Falling back to GITHUB_TOKEN."
export GH_TOKEN="$DEFAULT_GH_TOKEN"
gh pr edit "$PR_NUMBER" \
--title "$PR_TITLE" \
--body-file "$BODY_FILE"
exit 0
fi
echo "$EDIT_OUTPUT"
exit "$EDIT_EXIT"
else
echo "Creating new release PR"
set +e
CREATE_OUTPUT="$(
gh pr create \
--base main \
--head develop \
--title "$PR_TITLE" \
--body-file "$BODY_FILE" 2>&1
)"
CREATE_EXIT=$?
set -e
if [ "$CREATE_EXIT" -eq 0 ]; then
echo "$CREATE_OUTPUT"
exit 0
fi
if echo "$CREATE_OUTPUT" | grep -q "No commits between main and develop"; then
echo "No commits between main and develop. Skipping PR creation."
exit 0
fi
if echo "$CREATE_OUTPUT" | grep -q "Resource not accessible by integration"; then
echo "::warning::Unable to create release PR with GitHub Actions token. Add RELEASE_PR_TOKEN secret (PAT with repo scope) to enable automatic creation."
echo "$CREATE_OUTPUT"
exit 0
fi
if echo "$CREATE_OUTPUT" | grep -q "Resource not accessible by personal access token"; then
echo "::warning::RELEASE_PR_TOKEN could not create PR. Falling back to GITHUB_TOKEN."
export GH_TOKEN="$DEFAULT_GH_TOKEN"
set +e
CREATE_OUTPUT_FALLBACK="$(
gh pr create \
--base main \
--head develop \
--title "$PR_TITLE" \
--body-file "$BODY_FILE" 2>&1
)"
CREATE_EXIT_FALLBACK=$?
set -e
if [ "$CREATE_EXIT_FALLBACK" -eq 0 ]; then
echo "$CREATE_OUTPUT_FALLBACK"
exit 0
fi
if echo "$CREATE_OUTPUT_FALLBACK" | grep -q "Resource not accessible by integration"; then
echo "::warning::Unable to create release PR with fallback GITHUB_TOKEN."
echo "$CREATE_OUTPUT_FALLBACK"
exit 0
fi
echo "$CREATE_OUTPUT_FALLBACK"
exit "$CREATE_EXIT_FALLBACK"
fi
echo "$CREATE_OUTPUT"
exit "$CREATE_EXIT"
fi