Skip to content

Commit 3cb8578

Browse files
ci: retry GitHub API calls in changelog generator (#21305)
The release job calls @changesets/get-github-info to build changelog entries; a single dropped GraphQL connection ("Premature close") failed the whole release. Wrap the lookups in retry-with-backoff.
1 parent 086b229 commit 3cb8578

1 file changed

Lines changed: 42 additions & 12 deletions

File tree

.changeset/changelog-generator.mjs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,30 @@ function readEnv() {
1111
return { GITHUB_SERVER_URL };
1212
}
1313

14+
// Retry GitHub API calls so a transient drop (e.g. GraphQL "Premature close") doesn't fail the release.
15+
/**
16+
* @template T
17+
* @param {() => Promise<T>} fn operation to retry
18+
* @returns {Promise<T>} result
19+
*/
20+
async function withRetry(fn) {
21+
const maxAttempts = 5;
22+
let lastError;
23+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
24+
try {
25+
return await fn();
26+
} catch (err) {
27+
lastError = err;
28+
if (attempt === maxAttempts) break;
29+
const delay = Math.min(1000 * 2 ** (attempt - 1), 8000);
30+
await new Promise((resolve) => {
31+
setTimeout(resolve, delay);
32+
});
33+
}
34+
}
35+
throw lastError;
36+
}
37+
1438
/** @type {ChangelogFunctions} */
1539
const changelogFunctions = {
1640
getDependencyReleaseLine: async (
@@ -29,10 +53,12 @@ const changelogFunctions = {
2953
await Promise.all(
3054
changesets.map(async (cs) => {
3155
if (cs.commit) {
32-
const { links } = await getInfo({
33-
repo: options.repo,
34-
commit: cs.commit
35-
});
56+
const { links } = await withRetry(() =>
57+
getInfo({
58+
repo: options.repo,
59+
commit: cs.commit
60+
})
61+
);
3662
return links.commit;
3763
}
3864
})
@@ -84,10 +110,12 @@ const changelogFunctions = {
84110

85111
const links = await (async () => {
86112
if (prFromSummary !== undefined) {
87-
let { links } = await getInfoFromPullRequest({
88-
repo: options.repo,
89-
pull: prFromSummary
90-
});
113+
let { links } = await withRetry(() =>
114+
getInfoFromPullRequest({
115+
repo: options.repo,
116+
pull: prFromSummary
117+
})
118+
);
91119
if (commitFromSummary) {
92120
const shortCommitId = commitFromSummary.slice(0, 7);
93121
links = {
@@ -99,10 +127,12 @@ const changelogFunctions = {
99127
}
100128
const commitToFetchFrom = commitFromSummary || changeset.commit;
101129
if (commitToFetchFrom) {
102-
const { links } = await getInfo({
103-
repo: options.repo,
104-
commit: commitToFetchFrom
105-
});
130+
const { links } = await withRetry(() =>
131+
getInfo({
132+
repo: options.repo,
133+
commit: commitToFetchFrom
134+
})
135+
);
106136
return links;
107137
}
108138
return {

0 commit comments

Comments
 (0)