mirror of
https://github.com/softprops/action-gh-release.git
synced 2025-11-23 11:50:51 +00:00
fix: use manual pagination to prevent hitting 10k result limit
Replace github.paginate.iterator with manual pagination to have full control over when to stop. This prevents the iterator from hitting GitHub's 10,000 result limit before our code can stop it.
This commit is contained in:
parent
dad5ef3629
commit
3d29d2e17b
1 changed files with 82 additions and 28 deletions
|
|
@ -361,39 +361,35 @@ async function findTagByPagination(
|
||||||
repo: string,
|
repo: string,
|
||||||
tag: string,
|
tag: string,
|
||||||
): Promise<Release | undefined> {
|
): Promise<Release | undefined> {
|
||||||
// Limit pagination to avoid hitting GitHub's 10,000 result limit
|
// Manually paginate to avoid hitting GitHub's 10,000 result limit
|
||||||
// Stop aggressively on empty pages to prevent CI blocking
|
// The github.paginate.iterator can hit the limit before we can stop it
|
||||||
let pageCount = 0;
|
// So we manually paginate with strict limits
|
||||||
const maxPages = 30; // Stop after 30 pages (3000 releases max) to avoid hitting limits
|
const maxPages = 30; // Stop after 30 pages (3000 releases max) to avoid hitting limits
|
||||||
const minPagesBeforeEmptyPageStop = 5; // After checking at least 5 pages, stop immediately on first empty page
|
const minPagesBeforeEmptyPageStop = 5; // After checking at least 5 pages, stop immediately on first empty page
|
||||||
|
const perPage = 100;
|
||||||
|
|
||||||
|
// Use the GitHub API directly for manual pagination
|
||||||
|
const github = (releaser as GitHubReleaser).github;
|
||||||
|
if (!github) {
|
||||||
|
// Fallback to iterator if we can't access github directly
|
||||||
|
let pageCount = 0;
|
||||||
for await (const { data: releases } of releaser.allReleases({
|
for await (const { data: releases } of releaser.allReleases({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
})) {
|
})) {
|
||||||
pageCount++;
|
pageCount++;
|
||||||
|
|
||||||
// Stop if we've checked too many pages
|
|
||||||
if (pageCount > maxPages) {
|
if (pageCount > maxPages) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`⚠️ Stopped pagination after ${maxPages} pages to avoid hitting GitHub's result limit`,
|
`⚠️ Stopped pagination after ${maxPages} pages to avoid hitting GitHub's result limit`,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (releases.length === 0 && pageCount >= minPagesBeforeEmptyPageStop) {
|
||||||
// If we get an empty page, stop immediately if we've already checked enough pages
|
|
||||||
// This prevents getting stuck on empty pages (like pages 300-1000) which blocks CI
|
|
||||||
if (releases.length === 0) {
|
|
||||||
if (pageCount >= minPagesBeforeEmptyPageStop) {
|
|
||||||
console.log(
|
console.log(
|
||||||
`Stopped pagination after encountering empty page at page ${pageCount} (to avoid hitting GitHub's result limit)`,
|
`Stopped pagination after encountering empty page at page ${pageCount}`,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// If we haven't checked many pages yet, continue (might be at the very end)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const release = releases.find((release) => release.tag_name === tag);
|
const release = releases.find((release) => release.tag_name === tag);
|
||||||
if (release) {
|
if (release) {
|
||||||
return release;
|
return release;
|
||||||
|
|
@ -402,6 +398,64 @@ async function findTagByPagination(
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manual pagination with full control
|
||||||
|
let page = 1;
|
||||||
|
let consecutiveEmptyPages = 0;
|
||||||
|
|
||||||
|
while (page <= maxPages) {
|
||||||
|
try {
|
||||||
|
const response = await github.rest.repos.listReleases({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
per_page: perPage,
|
||||||
|
page: page,
|
||||||
|
});
|
||||||
|
|
||||||
|
const releases = response.data;
|
||||||
|
|
||||||
|
// If we get an empty page, stop immediately if we've already checked enough pages
|
||||||
|
if (releases.length === 0) {
|
||||||
|
consecutiveEmptyPages++;
|
||||||
|
if (page >= minPagesBeforeEmptyPageStop) {
|
||||||
|
console.log(
|
||||||
|
`Stopped pagination after encountering empty page at page ${page} (to avoid hitting GitHub's result limit)`,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// If we haven't checked many pages yet, continue (might be at the very end)
|
||||||
|
page++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset empty page counter when we find releases
|
||||||
|
consecutiveEmptyPages = 0;
|
||||||
|
|
||||||
|
const release = releases.find((release) => release.tag_name === tag);
|
||||||
|
if (release) {
|
||||||
|
return release;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got fewer results than per_page, we've reached the end
|
||||||
|
if (releases.length < perPage) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
page++;
|
||||||
|
} catch (error: any) {
|
||||||
|
// If we hit the 10,000 result limit, stop immediately
|
||||||
|
if (error.status === 422 && error.message?.includes('10000')) {
|
||||||
|
console.warn(
|
||||||
|
`⚠️ Stopped pagination at page ${page} due to GitHub's 10,000 result limit`,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a release by tag name from all a repository's releases.
|
* Finds a release by tag name from all a repository's releases.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue