fix(actions): respect ratelimits on split docs upload (#10697)

* fix(actions): respect ratelimits on split docs upload

* fix: set failed on missing uploads
This commit is contained in:
ckohen
2025-01-12 10:05:35 -08:00
committed by GitHub
parent 9a400730f5
commit 01e64b4e9a
3 changed files with 53 additions and 9 deletions

View File

@@ -48,6 +48,7 @@
"@vercel/postgres": "^0.9.0", "@vercel/postgres": "^0.9.0",
"meilisearch": "^0.38.0", "meilisearch": "^0.38.0",
"p-limit": "^6.2.0", "p-limit": "^6.2.0",
"p-queue": "^8.0.1",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"undici": "6.21.0" "undici": "6.21.0"
}, },

View File

@@ -1,16 +1,18 @@
import { readFile } from 'node:fs/promises'; import { readFile } from 'node:fs/promises';
import { basename, dirname, relative, sep } from 'node:path'; import { basename, dirname, relative, sep } from 'node:path';
import { cwd } from 'node:process'; import { cwd } from 'node:process';
import { getInput } from '@actions/core'; import { setTimeout as sleep } from 'node:timers/promises';
import { setFailed, getInput } from '@actions/core';
import { create } from '@actions/glob'; import { create } from '@actions/glob';
import { put } from '@vercel/blob'; import { put } from '@vercel/blob';
import pLimit from 'p-limit'; import PQueue from 'p-queue';
const pkg = getInput('package') || '*'; const pkg = getInput('package') || '*';
const version = getInput('version') || 'main'; const version = getInput('version') || 'main';
const limit = pLimit(10); const queue = new PQueue({ concurrency: 10, interval: 60_000, intervalCap: 1_000 });
const promises = []; const promises = [];
const failedUploads: string[] = [];
const globber = await create(`packages/${pkg}/docs/${pkg}/split/*.api.json`); const globber = await create(`packages/${pkg}/docs/${pkg}/split/*.api.json`);
console.log('Glob: ', await globber.glob()); console.log('Glob: ', await globber.glob());
@@ -20,13 +22,33 @@ for await (const file of globber.globGenerator()) {
try { try {
promises.push( promises.push(
// eslint-disable-next-line @typescript-eslint/no-loop-func // eslint-disable-next-line @typescript-eslint/no-loop-func
limit(async () => { queue.add(async () => {
console.log(`Uploading ${file} with ${version} from ${pkgName}...`); console.log(`Uploading ${file} with ${version} from ${pkgName}...`);
const name = basename(file).replace('main.', ''); const name = basename(file).replace('main.', '');
await put(`rewrite/${pkgName}/${version}.${name}`, data, { async function upload(retries = 0) {
access: 'public', try {
addRandomSuffix: false, await put(`rewrite/${pkgName}/${version}.${name}`, data, {
}); access: 'public',
addRandomSuffix: false,
});
} catch (error) {
if (retries > 3) {
console.error(`Could not upload ${file} after 3 retries`, error);
failedUploads.push(name);
return;
}
if (typeof error === 'object' && error && 'retryAfter' in error && typeof error.retryAfter === 'number') {
await sleep(error.retryAfter * 1_000);
return upload(retries + 1);
} else {
console.error(`Could not upload ${file}`, error);
failedUploads.push(name);
}
}
}
await upload();
}), }),
); );
} catch (error) { } catch (error) {
@@ -36,6 +58,9 @@ for await (const file of globber.globGenerator()) {
try { try {
await Promise.all(promises); await Promise.all(promises);
if (failedUploads.length) {
setFailed(`Failed to upload ${failedUploads.length} files: ${failedUploads.join(', ')}`);
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

20
pnpm-lock.yaml generated
View File

@@ -404,6 +404,9 @@ importers:
p-limit: p-limit:
specifier: ^6.2.0 specifier: ^6.2.0
version: 6.2.0 version: 6.2.0
p-queue:
specifier: ^8.0.1
version: 8.0.1
tslib: tslib:
specifier: ^2.8.1 specifier: ^2.8.1
version: 2.8.1 version: 2.8.1
@@ -10650,10 +10653,18 @@ packages:
resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==}
engines: {node: '>=18'} engines: {node: '>=18'}
p-queue@8.0.1:
resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==}
engines: {node: '>=18'}
p-timeout@5.1.0: p-timeout@5.1.0:
resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==}
engines: {node: '>=12'} engines: {node: '>=12'}
p-timeout@6.1.4:
resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==}
engines: {node: '>=14.16'}
p-try@2.2.0: p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
@@ -17790,7 +17801,7 @@ snapshots:
'@types/conventional-commits-parser@5.0.1': '@types/conventional-commits-parser@5.0.1':
dependencies: dependencies:
'@types/node': 22.10.2 '@types/node': 20.17.10
'@types/cookiejar@2.1.5': {} '@types/cookiejar@2.1.5': {}
@@ -25153,8 +25164,15 @@ snapshots:
p-map@7.0.3: {} p-map@7.0.3: {}
p-queue@8.0.1:
dependencies:
eventemitter3: 5.0.1
p-timeout: 6.1.4
p-timeout@5.1.0: {} p-timeout@5.1.0: {}
p-timeout@6.1.4: {}
p-try@2.2.0: {} p-try@2.2.0: {}
pac-proxy-agent@7.1.0: pac-proxy-agent@7.1.0: