Skip to content

Commit 1a7ce3a

Browse files
chore: improve rc discussion post
1 parent 5255abb commit 1a7ce3a

1 file changed

Lines changed: 95 additions & 28 deletions

File tree

scripts/rc_discussion.mjs

Lines changed: 95 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Maintains a single rolling RC discussion per upcoming release (vX.Y.Z)
33
// - Creates the discussion once (if missing)
44
// - Adds a comment for each RC (rc.1, rc.2, ...)
5-
// - Skips for stable releases
5+
// - Finalizes the thread on stable release
66

77
const GQL_URL = 'https://api.github.com/graphql';
88

@@ -54,12 +54,12 @@ async function main() {
5454
const repoFull = process.env.GITHUB_REPOSITORY;
5555
const nextVersion = process.argv[2] || process.env.SEMREL_NEXT_VERSION;
5656
if (!token || !repoFull || !nextVersion) return;
57-
if (!isRc(nextVersion)) return; // RCs only
5857
const [owner, name] = repoFull.split('/');
5958

6059
// Derive base version without rc suffix
6160
const baseVersion = nextVersion.replace(/-rc\..*$/, '');
6261
const title = `Release Candidate: v${baseVersion}`;
62+
const today = new Date().toISOString().slice(0, 10);
6363

6464
// Determine last stable tag for proper compare link and cumulative notes
6565
let lastStableTag = '';
@@ -96,6 +96,16 @@ async function main() {
9696
const compareUrl = lastStableTag
9797
? `https://github.com/${owner}/${name}/compare/${lastStableTag}...v${nextVersion}`
9898
: '';
99+
// Try to find previous RC for delta link
100+
let prevRcTag = '';
101+
try {
102+
const tags = run('git tag --sort=-v:refname').split('\n');
103+
const rcTags = tags.filter((t) => t.startsWith(`v${baseVersion}-rc.`));
104+
const currentRcNum = Number((nextVersion.match(/-rc\.(\d+)$/) || [])[1] || '0');
105+
const prevTarget = `v${baseVersion}-rc.${currentRcNum - 1}`;
106+
if (currentRcNum > 1 && rcTags.includes(prevTarget)) prevRcTag = prevTarget;
107+
} catch {}
108+
const deltaUrl = prevRcTag ? `https://github.com/${owner}/${name}/compare/${prevRcTag}...v${nextVersion}` : '';
99109

100110
// Try to fetch auto-generated release notes from GitHub API (cumulative from last stable)
101111
let generatedNotes = '';
@@ -113,25 +123,47 @@ async function main() {
113123
generatedNotes = body?.body || '';
114124
} catch {}
115125

116-
const note = `Updated to v${nextVersion}. Release: ${releaseUrl}${compareUrl ? ` | Full changelog: ${compareUrl}` : ''}`;
126+
const note = `Released ${today}: v${nextVersion} ${releaseUrl}${deltaUrl ? ` | Delta since ${prevRcTag}: ${deltaUrl}` : ''}${compareUrl ? ` | Since last stable: ${compareUrl}` : ''}`;
117127

118-
const bodyTemplate = (v) => {
128+
129+
const bodyTemplateRc = (v) => {
119130
return [
120131
`Tracking thread for the upcoming release v${baseVersion}.`,
121132
'',
122-
`Latest RC: v${v}`,
123-
`Release: ${releaseUrl}`,
124-
compareUrl ? `Full changelog: ${compareUrl}` : undefined,
133+
`Date: ${today}`,
134+
'',
135+
`## Latest build`,
136+
`- RC: v${v}`,
137+
`- Release: ${releaseUrl}`,
138+
compareUrl ? `- Since last stable: ${compareUrl}` : undefined,
139+
deltaUrl ? `- Delta since previous RC (${prevRcTag}): ${deltaUrl}` : undefined,
125140
'',
141+
`## Notes`,
142+
`Feedback welcome — report issues here: https://github.com/${owner}/${name}/issues/new?title=${encodeURIComponent(
143+
`RC v${v} feedback:`
144+
)}`,
126145
generatedNotes
127-
? `<details><summary>Auto-generated release notes</summary>\n\n${generatedNotes}\n\n</details>`
146+
? `\n<details><summary>Auto-generated release notes</summary>\n\n${generatedNotes}\n\n</details>`
128147
: undefined,
129148
]
130149
.filter(Boolean)
131150
.join('\n');
132151
};
133152

134-
if (!existing) {
153+
const bodyTemplateStable = (v, finalDeltaUrl) => {
154+
return [
155+
`Status: Released v${v} on ${today}.`,
156+
'',
157+
`## Links`,
158+
`- Stable: https://github.com/${owner}/${name}/releases/tag/v${v}`,
159+
finalDeltaUrl ? `- Delta from last RC: ${finalDeltaUrl}` : undefined,
160+
lastStableTag ? `- Since previous stable: https://github.com/${owner}/${name}/compare/${lastStableTag}...v${v}` : undefined,
161+
]
162+
.filter(Boolean)
163+
.join('\n');
164+
};
165+
166+
if (isRc(nextVersion) && !existing) {
135167
// Create the rolling RC discussion once
136168
await gqlFetch(
137169
token,
@@ -140,31 +172,66 @@ async function main() {
140172
discussion { id number url }
141173
}
142174
}`,
143-
{ repoId: repo.id, catId: category.id, title, body: bodyTemplate(nextVersion) }
175+
{ repoId: repo.id, catId: category.id, title, body: bodyTemplateRc(nextVersion) }
144176
);
145177
// No further comment needed on first creation
146178
return;
147179
}
148180

149-
// Update the discussion body with latest RC details
150-
await gqlFetch(
151-
token,
152-
`mutation UpdateDiscussion($id: ID!, $body: String!) {
153-
updateDiscussion(input: { discussionId: $id, body: $body }) { discussion { id url } }
154-
}`,
155-
{ id: existing.id, body: bodyTemplate(nextVersion) }
156-
);
181+
if (isRc(nextVersion) && existing) {
182+
// Update the discussion body with latest RC details
183+
await gqlFetch(
184+
token,
185+
`mutation UpdateDiscussion($id: ID!, $body: String!) {
186+
updateDiscussion(input: { discussionId: $id, body: $body }) { discussion { id url } }
187+
}`,
188+
{ id: existing.id, body: bodyTemplateRc(nextVersion) }
189+
);
190+
// Add a comment to the existing rolling thread
191+
await gqlFetch(
192+
token,
193+
`mutation AddComment($discId: ID!, $body: String!) {
194+
addDiscussionComment(input: { discussionId: $discId, body: $body }) {
195+
comment { url }
196+
}
197+
}`,
198+
{ discId: existing.id, body: note }
199+
);
200+
return;
201+
}
157202

158-
// Add a comment to the existing rolling thread
159-
await gqlFetch(
160-
token,
161-
`mutation AddComment($discId: ID!, $body: String!) {
162-
addDiscussionComment(input: { discussionId: $discId, body: $body }) {
163-
comment { url }
164-
}
165-
}`,
166-
{ discId: existing.id, body: note }
167-
);
203+
// Stable release: finalize thread (if exists)
204+
if (!isRc(nextVersion) && existing) {
205+
// Compute delta from last RC to stable
206+
let lastRcTag = '';
207+
try {
208+
const tags = run('git tag --sort=-v:refname').split('\n');
209+
const rcTags = tags.filter((t) => t.startsWith(`v${baseVersion}-rc.`));
210+
lastRcTag = rcTags[0] || '';
211+
} catch {}
212+
const finalDeltaUrl = lastRcTag
213+
? `https://github.com/${owner}/${name}/compare/${lastRcTag}...v${nextVersion}`
214+
: '';
215+
216+
// Update body to show Released status and links
217+
await gqlFetch(
218+
token,
219+
`mutation UpdateDiscussion($id: ID!, $body: String!) {
220+
updateDiscussion(input: { discussionId: $id, body: $body }) { discussion { id url } }
221+
}`,
222+
{ id: existing.id, body: bodyTemplateStable(nextVersion, finalDeltaUrl) }
223+
);
224+
// Post final comment
225+
await gqlFetch(
226+
token,
227+
`mutation AddComment($discId: ID!, $body: String!) {
228+
addDiscussionComment(input: { discussionId: $discId, body: $body }) {
229+
comment { url }
230+
}
231+
}`,
232+
{ discId: existing.id, body: `Stable released ${today}: v${nextVersion} — https://github.com/${owner}/${name}/releases/tag/v${nextVersion}${finalDeltaUrl ? ` | Delta from last RC: ${finalDeltaUrl}` : ''}` }
233+
);
234+
}
168235
}
169236

170237
main().catch(() => {

0 commit comments

Comments
 (0)