This commit is contained in:
Julien Bouyoud 2025-06-16 11:48:52 +07:00 committed by GitHub
commit e58f77a10a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 370 additions and 36 deletions

View file

@ -4,7 +4,7 @@ import {getRetryOptions} from '../src/retry-options'
describe('getRequestOptions', () => {
test('retries disabled if retries == 0', async () => {
const [retryOptions, requestOptions] = getRetryOptions(
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
0,
[400, 500, 502],
[]
@ -14,10 +14,12 @@ describe('getRequestOptions', () => {
expect(retryOptions.doNotRetry).toBeFalsy()
expect(requestOptions?.retries).toBeFalsy()
expect(throttlingOptions?.onRateLimit).toBeFalsy()
expect(throttlingOptions?.onSecondaryRateLimit).toBeFalsy()
})
test('properties set if retries > 0', async () => {
const [retryOptions, requestOptions] = getRetryOptions(
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
1,
[400, 500, 502],
[]
@ -27,10 +29,12 @@ describe('getRequestOptions', () => {
expect(retryOptions.doNotRetry).toEqual([400, 500, 502])
expect(requestOptions?.retries).toEqual(1)
expect(throttlingOptions?.onRateLimit).toBeDefined()
expect(throttlingOptions?.onSecondaryRateLimit).toBeDefined()
})
test('properties set if retries > 0', async () => {
const [retryOptions, requestOptions] = getRetryOptions(
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
1,
[400, 500, 502],
[]
@ -40,24 +44,36 @@ describe('getRequestOptions', () => {
expect(retryOptions.doNotRetry).toEqual([400, 500, 502])
expect(requestOptions?.retries).toEqual(1)
expect(throttlingOptions?.onRateLimit).toBeDefined()
expect(throttlingOptions?.onSecondaryRateLimit).toBeDefined()
})
test('retryOptions.doNotRetry not set if exemptStatusCodes isEmpty', async () => {
const [retryOptions, requestOptions] = getRetryOptions(1, [], [])
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
1,
[],
[]
)
expect(retryOptions.enabled).toBe(true)
expect(retryOptions.doNotRetry).toBeUndefined()
expect(requestOptions?.retries).toEqual(1)
expect(throttlingOptions?.onRateLimit).toBeDefined()
expect(throttlingOptions?.onSecondaryRateLimit).toBeDefined()
})
test('requestOptions does not override defaults from @actions/github', async () => {
const [retryOptions, requestOptions] = getRetryOptions(1, [], {
request: {
agent: 'default-user-agent'
},
foo: 'bar'
})
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
1,
[],
{
request: {
agent: 'default-user-agent'
},
foo: 'bar'
}
)
expect(retryOptions.enabled).toBe(true)
expect(retryOptions.doNotRetry).toBeUndefined()
@ -65,5 +81,8 @@ describe('getRequestOptions', () => {
expect(requestOptions?.retries).toEqual(1)
expect(requestOptions?.agent).toEqual('default-user-agent')
expect(requestOptions?.foo).toBeUndefined() // this should not be in the `options.request` object, but at the same level as `request`
expect(throttlingOptions?.onRateLimit).toBeDefined()
expect(throttlingOptions?.onSecondaryRateLimit).toBeDefined()
})
})

276
dist/index.js vendored
View file

@ -9319,6 +9319,258 @@ retry.VERSION = VERSION;
0 && (0);
/***/ }),
/***/ 9968:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// pkg/dist-src/index.js
var dist_src_exports = {};
__export(dist_src_exports, {
throttling: () => throttling
});
module.exports = __toCommonJS(dist_src_exports);
var import_light = __toESM(__nccwpck_require__(1174));
var import_core = __nccwpck_require__(6762);
// pkg/dist-src/version.js
var VERSION = "8.2.0";
// pkg/dist-src/wrap-request.js
var noop = () => Promise.resolve();
function wrapRequest(state, request, options) {
return state.retryLimiter.schedule(doRequest, state, request, options);
}
async function doRequest(state, request, options) {
const isWrite = options.method !== "GET" && options.method !== "HEAD";
const { pathname } = new URL(options.url, "http://github.test");
const isSearch = options.method === "GET" && pathname.startsWith("/search/");
const isGraphQL = pathname.startsWith("/graphql");
const retryCount = ~~request.retryCount;
const jobOptions = retryCount > 0 ? { priority: 0, weight: 0 } : {};
if (state.clustering) {
jobOptions.expiration = 1e3 * 60;
}
if (isWrite || isGraphQL) {
await state.write.key(state.id).schedule(jobOptions, noop);
}
if (isWrite && state.triggersNotification(pathname)) {
await state.notifications.key(state.id).schedule(jobOptions, noop);
}
if (isSearch) {
await state.search.key(state.id).schedule(jobOptions, noop);
}
const req = state.global.key(state.id).schedule(jobOptions, request, options);
if (isGraphQL) {
const res = await req;
if (res.data.errors != null && res.data.errors.some((error) => error.type === "RATE_LIMITED")) {
const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), {
response: res,
data: res.data
});
throw error;
}
}
return req;
}
// pkg/dist-src/generated/triggers-notification-paths.js
var triggers_notification_paths_default = [
"/orgs/{org}/invitations",
"/orgs/{org}/invitations/{invitation_id}",
"/orgs/{org}/teams/{team_slug}/discussions",
"/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments",
"/repos/{owner}/{repo}/collaborators/{username}",
"/repos/{owner}/{repo}/commits/{commit_sha}/comments",
"/repos/{owner}/{repo}/issues",
"/repos/{owner}/{repo}/issues/{issue_number}/comments",
"/repos/{owner}/{repo}/pulls",
"/repos/{owner}/{repo}/pulls/{pull_number}/comments",
"/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies",
"/repos/{owner}/{repo}/pulls/{pull_number}/merge",
"/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers",
"/repos/{owner}/{repo}/pulls/{pull_number}/reviews",
"/repos/{owner}/{repo}/releases",
"/teams/{team_id}/discussions",
"/teams/{team_id}/discussions/{discussion_number}/comments"
];
// pkg/dist-src/route-matcher.js
function routeMatcher(paths) {
const regexes = paths.map(
(path) => path.split("/").map((c) => c.startsWith("{") ? "(?:.+?)" : c).join("/")
);
const regex2 = `^(?:${regexes.map((r) => `(?:${r})`).join("|")})[^/]*$`;
return new RegExp(regex2, "i");
}
// pkg/dist-src/index.js
var regex = routeMatcher(triggers_notification_paths_default);
var triggersNotification = regex.test.bind(regex);
var groups = {};
var createGroups = function(Bottleneck, common) {
groups.global = new Bottleneck.Group({
id: "octokit-global",
maxConcurrent: 10,
...common
});
groups.search = new Bottleneck.Group({
id: "octokit-search",
maxConcurrent: 1,
minTime: 2e3,
...common
});
groups.write = new Bottleneck.Group({
id: "octokit-write",
maxConcurrent: 1,
minTime: 1e3,
...common
});
groups.notifications = new Bottleneck.Group({
id: "octokit-notifications",
maxConcurrent: 1,
minTime: 3e3,
...common
});
};
function throttling(octokit, octokitOptions) {
const {
enabled = true,
Bottleneck = import_light.default,
id = "no-id",
timeout = 1e3 * 60 * 2,
// Redis TTL: 2 minutes
connection
} = octokitOptions.throttle || {};
if (!enabled) {
return {};
}
const common = { connection, timeout };
if (groups.global == null) {
createGroups(Bottleneck, common);
}
const state = Object.assign(
{
clustering: connection != null,
triggersNotification,
fallbackSecondaryRateRetryAfter: 60,
retryAfterBaseValue: 1e3,
retryLimiter: new Bottleneck(),
id,
...groups
},
octokitOptions.throttle
);
if (typeof state.onSecondaryRateLimit !== "function" || typeof state.onRateLimit !== "function") {
throw new Error(`octokit/plugin-throttling error:
You must pass the onSecondaryRateLimit and onRateLimit error handlers.
See https://octokit.github.io/rest.js/#throttling
const octokit = new Octokit({
throttle: {
onSecondaryRateLimit: (retryAfter, options) => {/* ... */},
onRateLimit: (retryAfter, options) => {/* ... */}
}
})
`);
}
const events = {};
const emitter = new Bottleneck.Events(events);
events.on("secondary-limit", state.onSecondaryRateLimit);
events.on("rate-limit", state.onRateLimit);
events.on(
"error",
(e) => octokit.log.warn("Error in throttling-plugin limit handler", e)
);
state.retryLimiter.on("failed", async function(error, info) {
const [state2, request, options] = info.args;
const { pathname } = new URL(options.url, "http://github.test");
const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401;
if (!(shouldRetryGraphQL || error.status === 403)) {
return;
}
const retryCount = ~~request.retryCount;
request.retryCount = retryCount;
options.request.retryCount = retryCount;
const { wantRetry, retryAfter = 0 } = await async function() {
if (/\bsecondary rate\b/i.test(error.message)) {
const retryAfter2 = Number(error.response.headers["retry-after"]) || state2.fallbackSecondaryRateRetryAfter;
const wantRetry2 = await emitter.trigger(
"secondary-limit",
retryAfter2,
options,
octokit,
retryCount
);
return { wantRetry: wantRetry2, retryAfter: retryAfter2 };
}
if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0" || (error.response.data?.errors ?? []).some(
(error2) => error2.type === "RATE_LIMITED"
)) {
const rateLimitReset = new Date(
~~error.response.headers["x-ratelimit-reset"] * 1e3
).getTime();
const retryAfter2 = Math.max(
// Add one second so we retry _after_ the reset time
// https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#exceeding-the-rate-limit
Math.ceil((rateLimitReset - Date.now()) / 1e3) + 1,
0
);
const wantRetry2 = await emitter.trigger(
"rate-limit",
retryAfter2,
options,
octokit,
retryCount
);
return { wantRetry: wantRetry2, retryAfter: retryAfter2 };
}
return {};
}();
if (wantRetry) {
request.retryCount++;
return retryAfter * state2.retryAfterBaseValue;
}
});
octokit.hook.wrap("request", wrapRequest.bind(null, state));
return {};
}
throttling.VERSION = VERSION;
throttling.triggersNotification = triggersNotification;
// Annotate the CommonJS export names for ESM import in node:
0 && (0);
/***/ }),
/***/ 537:
@ -36181,6 +36433,8 @@ var io = __nccwpck_require__(7436);
var dist_node = __nccwpck_require__(8883);
// EXTERNAL MODULE: ./node_modules/@octokit/plugin-retry/dist-node/index.js
var plugin_retry_dist_node = __nccwpck_require__(6298);
// EXTERNAL MODULE: ./node_modules/@octokit/plugin-throttling/dist-node/index.js
var plugin_throttling_dist_node = __nccwpck_require__(9968);
;// CONCATENATED MODULE: ./src/async-function.ts
const AsyncFunction = Object.getPrototypeOf(async () => null).constructor;
function callAsyncFunction(args, source) {
@ -36193,7 +36447,7 @@ function callAsyncFunction(args, source) {
function getRetryOptions(retries, exemptStatusCodes, defaultOptions) {
var _a;
if (retries <= 0) {
return [{ enabled: false }, defaultOptions.request];
return [{ enabled: false }, defaultOptions.request, undefined];
}
const retryOptions = {
enabled: true
@ -36208,8 +36462,18 @@ function getRetryOptions(retries, exemptStatusCodes, defaultOptions) {
...defaultOptions.request,
retries
};
const throttleOptions = {
onRateLimit: (retryAfter, options, octokit, retryCount) => {
core.debug(`Request quota exhausted for request ${options.method} ${options.url}`);
return retryCount < retries;
},
onSecondaryRateLimit: (retryAfter, options, octokit, retryCount) => {
core.debug(`Secondary quota detected for request ${options.method} ${options.url}`);
return retryCount < retries;
}
};
core.debug(`GitHub client configured with: (retries: ${requestOptions.retries}, retry-exempt-status-code: ${(_a = retryOptions.doNotRetry) !== null && _a !== void 0 ? _a : 'octokit default: [400, 401, 403, 404, 422]'})`);
return [retryOptions, requestOptions];
return [retryOptions, requestOptions, throttleOptions];
}
function parseNumberArray(listString) {
if (!listString) {
@ -36256,6 +36520,7 @@ const wrapRequire = new Proxy(require, {
process.on('unhandledRejection', handleError);
main().catch(handleError);
async function main() {
@ -36266,20 +36531,21 @@ async function main() {
const baseUrl = core.getInput('base-url');
const retries = parseInt(core.getInput('retries'));
const exemptStatusCodes = parseNumberArray(core.getInput('retry-exempt-status-codes'));
const [retryOpts, requestOpts] = getRetryOptions(retries, exemptStatusCodes, utils.defaults);
const [retryOpts, requestOpts, throttleOpts] = getRetryOptions(retries, exemptStatusCodes, utils.defaults);
const opts = {
log: debug ? console : undefined,
userAgent: userAgent || undefined,
previews: previews ? previews.split(',') : undefined,
retry: retryOpts,
request: requestOpts
request: requestOpts,
throttle: throttleOpts
};
// Setting `baseUrl` to undefined will prevent the default value from being used
// https://github.com/actions/github-script/issues/436
if (baseUrl) {
opts.baseUrl = baseUrl;
}
const github = (0,lib_github.getOctokit)(token, opts, plugin_retry_dist_node.retry, dist_node.requestLog);
const github = (0,lib_github.getOctokit)(token, opts, plugin_retry_dist_node.retry, dist_node.requestLog, plugin_throttling_dist_node.throttling);
const script = core.getInput('script', { required: true });
// Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors.
const result = await callAsyncFunction({

53
package-lock.json generated
View file

@ -17,6 +17,7 @@
"@octokit/core": "^5.0.1",
"@octokit/plugin-request-log": "^4.0.0",
"@octokit/plugin-retry": "^6.0.1",
"@octokit/plugin-throttling": "^8.2.0",
"@types/node": "^20.9.0"
},
"devDependencies": {
@ -1345,9 +1346,9 @@
}
},
"node_modules/@octokit/openapi-types": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "9.0.0",
@ -1404,6 +1405,21 @@
"@octokit/core": ">=5"
}
},
"node_modules/@octokit/plugin-throttling": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.2.0.tgz",
"integrity": "sha512-nOpWtLayKFpgqmgD0y3GqXafMFuKcA4tRPZIfu7BArd2lEZeb1988nhWhwx4aZWmjDmUfdgVf7W+Tt4AmvRmMQ==",
"dependencies": {
"@octokit/types": "^12.2.0",
"bottleneck": "^2.15.3"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "^5.0.0"
}
},
"node_modules/@octokit/request": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
@ -1459,11 +1475,11 @@
}
},
"node_modules/@octokit/types": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
"integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"dependencies": {
"@octokit/openapi-types": "^19.0.0"
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@pkgr/utils": {
@ -8372,9 +8388,9 @@
}
},
"@octokit/openapi-types": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
},
"@octokit/plugin-paginate-rest": {
"version": "9.0.0",
@ -8408,6 +8424,15 @@
"bottleneck": "^2.15.3"
}
},
"@octokit/plugin-throttling": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.2.0.tgz",
"integrity": "sha512-nOpWtLayKFpgqmgD0y3GqXafMFuKcA4tRPZIfu7BArd2lEZeb1988nhWhwx4aZWmjDmUfdgVf7W+Tt4AmvRmMQ==",
"requires": {
"@octokit/types": "^12.2.0",
"bottleneck": "^2.15.3"
}
},
"@octokit/request": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
@ -8461,11 +8486,11 @@
}
},
"@octokit/types": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
"integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"requires": {
"@octokit/openapi-types": "^19.0.0"
"@octokit/openapi-types": "^20.0.0"
}
},
"@pkgr/utils": {

View file

@ -47,6 +47,7 @@
"@octokit/core": "^5.0.1",
"@octokit/plugin-request-log": "^4.0.0",
"@octokit/plugin-retry": "^6.0.1",
"@octokit/plugin-throttling": "^8.2.0",
"@types/node": "^20.9.0"
},
"devDependencies": {
@ -64,4 +65,4 @@
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
}
}
}

View file

@ -6,6 +6,7 @@ import * as glob from '@actions/glob'
import * as io from '@actions/io'
import {requestLog} from '@octokit/plugin-request-log'
import {retry} from '@octokit/plugin-retry'
import {throttling, ThrottlingOptions} from '@octokit/plugin-throttling'
import {RequestRequestOptions} from '@octokit/types'
import {callAsyncFunction} from './async-function'
import {RetryOptions, getRetryOptions, parseNumberArray} from './retry-options'
@ -20,6 +21,7 @@ type Options = {
baseUrl?: string
previews?: string[]
retry?: RetryOptions
throttle?: ThrottlingOptions
request?: RequestRequestOptions
}
@ -33,7 +35,7 @@ async function main(): Promise<void> {
const exemptStatusCodes = parseNumberArray(
core.getInput('retry-exempt-status-codes')
)
const [retryOpts, requestOpts] = getRetryOptions(
const [retryOpts, requestOpts, throttleOpts] = getRetryOptions(
retries,
exemptStatusCodes,
defaultGitHubOptions
@ -44,7 +46,8 @@ async function main(): Promise<void> {
userAgent: userAgent || undefined,
previews: previews ? previews.split(',') : undefined,
retry: retryOpts,
request: requestOpts
request: requestOpts,
throttle: throttleOpts
}
// Setting `baseUrl` to undefined will prevent the default value from being used
@ -53,7 +56,7 @@ async function main(): Promise<void> {
opts.baseUrl = baseUrl
}
const github = getOctokit(token, opts, retry, requestLog)
const github = getOctokit(token, opts, retry, requestLog, throttling)
const script = core.getInput('script', {required: true})
// Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors.

View file

@ -1,5 +1,6 @@
import * as core from '@actions/core'
import {OctokitOptions} from '@octokit/core/dist-types/types'
import {ThrottlingOptions} from '@octokit/plugin-throttling'
import {RequestRequestOptions} from '@octokit/types'
export type RetryOptions = {
@ -11,9 +12,13 @@ export function getRetryOptions(
retries: number,
exemptStatusCodes: number[],
defaultOptions: OctokitOptions
): [RetryOptions, RequestRequestOptions | undefined] {
): [
RetryOptions,
RequestRequestOptions | undefined,
ThrottlingOptions | undefined
] {
if (retries <= 0) {
return [{enabled: false}, defaultOptions.request]
return [{enabled: false}, defaultOptions.request, undefined]
}
const retryOptions: RetryOptions = {
@ -32,6 +37,21 @@ export function getRetryOptions(
retries
}
const throttleOptions: ThrottlingOptions = {
onRateLimit: (retryAfter, options, octokit, retryCount) => {
core.debug(
`Request quota exhausted for request ${options.method} ${options.url}`
)
return retryCount < retries
},
onSecondaryRateLimit: (retryAfter, options, octokit, retryCount) => {
core.debug(
`Secondary quota detected for request ${options.method} ${options.url}`
)
return retryCount < retries
}
}
core.debug(
`GitHub client configured with: (retries: ${
requestOptions.retries
@ -40,7 +60,7 @@ export function getRetryOptions(
})`
)
return [retryOptions, requestOptions]
return [retryOptions, requestOptions, throttleOptions]
}
export function parseNumberArray(listString: string): number[] {