mirror of
https://github.com/actions/github-script.git
synced 2026-02-08 03:57:27 +00:00
Merge 691bd6b113 into f28e40c7f3
This commit is contained in:
commit
e58f77a10a
6 changed files with 370 additions and 36 deletions
|
|
@ -4,7 +4,7 @@ import {getRetryOptions} from '../src/retry-options'
|
||||||
|
|
||||||
describe('getRequestOptions', () => {
|
describe('getRequestOptions', () => {
|
||||||
test('retries disabled if retries == 0', async () => {
|
test('retries disabled if retries == 0', async () => {
|
||||||
const [retryOptions, requestOptions] = getRetryOptions(
|
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
|
||||||
0,
|
0,
|
||||||
[400, 500, 502],
|
[400, 500, 502],
|
||||||
[]
|
[]
|
||||||
|
|
@ -14,10 +14,12 @@ describe('getRequestOptions', () => {
|
||||||
expect(retryOptions.doNotRetry).toBeFalsy()
|
expect(retryOptions.doNotRetry).toBeFalsy()
|
||||||
|
|
||||||
expect(requestOptions?.retries).toBeFalsy()
|
expect(requestOptions?.retries).toBeFalsy()
|
||||||
|
expect(throttlingOptions?.onRateLimit).toBeFalsy()
|
||||||
|
expect(throttlingOptions?.onSecondaryRateLimit).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('properties set if retries > 0', async () => {
|
test('properties set if retries > 0', async () => {
|
||||||
const [retryOptions, requestOptions] = getRetryOptions(
|
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
|
||||||
1,
|
1,
|
||||||
[400, 500, 502],
|
[400, 500, 502],
|
||||||
[]
|
[]
|
||||||
|
|
@ -27,10 +29,12 @@ describe('getRequestOptions', () => {
|
||||||
expect(retryOptions.doNotRetry).toEqual([400, 500, 502])
|
expect(retryOptions.doNotRetry).toEqual([400, 500, 502])
|
||||||
|
|
||||||
expect(requestOptions?.retries).toEqual(1)
|
expect(requestOptions?.retries).toEqual(1)
|
||||||
|
expect(throttlingOptions?.onRateLimit).toBeDefined()
|
||||||
|
expect(throttlingOptions?.onSecondaryRateLimit).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('properties set if retries > 0', async () => {
|
test('properties set if retries > 0', async () => {
|
||||||
const [retryOptions, requestOptions] = getRetryOptions(
|
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
|
||||||
1,
|
1,
|
||||||
[400, 500, 502],
|
[400, 500, 502],
|
||||||
[]
|
[]
|
||||||
|
|
@ -40,24 +44,36 @@ describe('getRequestOptions', () => {
|
||||||
expect(retryOptions.doNotRetry).toEqual([400, 500, 502])
|
expect(retryOptions.doNotRetry).toEqual([400, 500, 502])
|
||||||
|
|
||||||
expect(requestOptions?.retries).toEqual(1)
|
expect(requestOptions?.retries).toEqual(1)
|
||||||
|
expect(throttlingOptions?.onRateLimit).toBeDefined()
|
||||||
|
expect(throttlingOptions?.onSecondaryRateLimit).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('retryOptions.doNotRetry not set if exemptStatusCodes isEmpty', async () => {
|
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.enabled).toBe(true)
|
||||||
expect(retryOptions.doNotRetry).toBeUndefined()
|
expect(retryOptions.doNotRetry).toBeUndefined()
|
||||||
|
|
||||||
expect(requestOptions?.retries).toEqual(1)
|
expect(requestOptions?.retries).toEqual(1)
|
||||||
|
expect(throttlingOptions?.onRateLimit).toBeDefined()
|
||||||
|
expect(throttlingOptions?.onSecondaryRateLimit).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('requestOptions does not override defaults from @actions/github', async () => {
|
test('requestOptions does not override defaults from @actions/github', async () => {
|
||||||
const [retryOptions, requestOptions] = getRetryOptions(1, [], {
|
const [retryOptions, requestOptions, throttlingOptions] = getRetryOptions(
|
||||||
request: {
|
1,
|
||||||
agent: 'default-user-agent'
|
[],
|
||||||
},
|
{
|
||||||
foo: 'bar'
|
request: {
|
||||||
})
|
agent: 'default-user-agent'
|
||||||
|
},
|
||||||
|
foo: 'bar'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
expect(retryOptions.enabled).toBe(true)
|
expect(retryOptions.enabled).toBe(true)
|
||||||
expect(retryOptions.doNotRetry).toBeUndefined()
|
expect(retryOptions.doNotRetry).toBeUndefined()
|
||||||
|
|
@ -65,5 +81,8 @@ describe('getRequestOptions', () => {
|
||||||
expect(requestOptions?.retries).toEqual(1)
|
expect(requestOptions?.retries).toEqual(1)
|
||||||
expect(requestOptions?.agent).toEqual('default-user-agent')
|
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(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
276
dist/index.js
vendored
|
|
@ -9319,6 +9319,258 @@ retry.VERSION = VERSION;
|
||||||
0 && (0);
|
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:
|
/***/ 537:
|
||||||
|
|
@ -36181,6 +36433,8 @@ var io = __nccwpck_require__(7436);
|
||||||
var dist_node = __nccwpck_require__(8883);
|
var dist_node = __nccwpck_require__(8883);
|
||||||
// EXTERNAL MODULE: ./node_modules/@octokit/plugin-retry/dist-node/index.js
|
// EXTERNAL MODULE: ./node_modules/@octokit/plugin-retry/dist-node/index.js
|
||||||
var plugin_retry_dist_node = __nccwpck_require__(6298);
|
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
|
;// CONCATENATED MODULE: ./src/async-function.ts
|
||||||
const AsyncFunction = Object.getPrototypeOf(async () => null).constructor;
|
const AsyncFunction = Object.getPrototypeOf(async () => null).constructor;
|
||||||
function callAsyncFunction(args, source) {
|
function callAsyncFunction(args, source) {
|
||||||
|
|
@ -36193,7 +36447,7 @@ function callAsyncFunction(args, source) {
|
||||||
function getRetryOptions(retries, exemptStatusCodes, defaultOptions) {
|
function getRetryOptions(retries, exemptStatusCodes, defaultOptions) {
|
||||||
var _a;
|
var _a;
|
||||||
if (retries <= 0) {
|
if (retries <= 0) {
|
||||||
return [{ enabled: false }, defaultOptions.request];
|
return [{ enabled: false }, defaultOptions.request, undefined];
|
||||||
}
|
}
|
||||||
const retryOptions = {
|
const retryOptions = {
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
@ -36208,8 +36462,18 @@ function getRetryOptions(retries, exemptStatusCodes, defaultOptions) {
|
||||||
...defaultOptions.request,
|
...defaultOptions.request,
|
||||||
retries
|
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]'})`);
|
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) {
|
function parseNumberArray(listString) {
|
||||||
if (!listString) {
|
if (!listString) {
|
||||||
|
|
@ -36256,6 +36520,7 @@ const wrapRequire = new Proxy(require, {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
process.on('unhandledRejection', handleError);
|
process.on('unhandledRejection', handleError);
|
||||||
main().catch(handleError);
|
main().catch(handleError);
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|
@ -36266,20 +36531,21 @@ async function main() {
|
||||||
const baseUrl = core.getInput('base-url');
|
const baseUrl = core.getInput('base-url');
|
||||||
const retries = parseInt(core.getInput('retries'));
|
const retries = parseInt(core.getInput('retries'));
|
||||||
const exemptStatusCodes = parseNumberArray(core.getInput('retry-exempt-status-codes'));
|
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 = {
|
const opts = {
|
||||||
log: debug ? console : undefined,
|
log: debug ? console : undefined,
|
||||||
userAgent: userAgent || undefined,
|
userAgent: userAgent || undefined,
|
||||||
previews: previews ? previews.split(',') : undefined,
|
previews: previews ? previews.split(',') : undefined,
|
||||||
retry: retryOpts,
|
retry: retryOpts,
|
||||||
request: requestOpts
|
request: requestOpts,
|
||||||
|
throttle: throttleOpts
|
||||||
};
|
};
|
||||||
// Setting `baseUrl` to undefined will prevent the default value from being used
|
// Setting `baseUrl` to undefined will prevent the default value from being used
|
||||||
// https://github.com/actions/github-script/issues/436
|
// https://github.com/actions/github-script/issues/436
|
||||||
if (baseUrl) {
|
if (baseUrl) {
|
||||||
opts.baseUrl = 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 });
|
const script = core.getInput('script', { required: true });
|
||||||
// Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors.
|
// Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors.
|
||||||
const result = await callAsyncFunction({
|
const result = await callAsyncFunction({
|
||||||
|
|
|
||||||
53
package-lock.json
generated
53
package-lock.json
generated
|
|
@ -17,6 +17,7 @@
|
||||||
"@octokit/core": "^5.0.1",
|
"@octokit/core": "^5.0.1",
|
||||||
"@octokit/plugin-request-log": "^4.0.0",
|
"@octokit/plugin-request-log": "^4.0.0",
|
||||||
"@octokit/plugin-retry": "^6.0.1",
|
"@octokit/plugin-retry": "^6.0.1",
|
||||||
|
"@octokit/plugin-throttling": "^8.2.0",
|
||||||
"@types/node": "^20.9.0"
|
"@types/node": "^20.9.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -1345,9 +1346,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/openapi-types": {
|
||||||
"version": "19.0.0",
|
"version": "20.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||||
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
|
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-paginate-rest": {
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
|
|
@ -1404,6 +1405,21 @@
|
||||||
"@octokit/core": ">=5"
|
"@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": {
|
"node_modules/@octokit/request": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
|
||||||
|
|
@ -1459,11 +1475,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/types": {
|
"node_modules/@octokit/types": {
|
||||||
"version": "12.0.0",
|
"version": "12.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||||
"integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
|
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/openapi-types": "^19.0.0"
|
"@octokit/openapi-types": "^20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@pkgr/utils": {
|
"node_modules/@pkgr/utils": {
|
||||||
|
|
@ -8372,9 +8388,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/openapi-types": {
|
"@octokit/openapi-types": {
|
||||||
"version": "19.0.0",
|
"version": "20.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||||
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
|
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
|
||||||
},
|
},
|
||||||
"@octokit/plugin-paginate-rest": {
|
"@octokit/plugin-paginate-rest": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
|
|
@ -8408,6 +8424,15 @@
|
||||||
"bottleneck": "^2.15.3"
|
"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": {
|
"@octokit/request": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
|
||||||
|
|
@ -8461,11 +8486,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/types": {
|
"@octokit/types": {
|
||||||
"version": "12.0.0",
|
"version": "12.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||||
"integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
|
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@octokit/openapi-types": "^19.0.0"
|
"@octokit/openapi-types": "^20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@pkgr/utils": {
|
"@pkgr/utils": {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
"@octokit/core": "^5.0.1",
|
"@octokit/core": "^5.0.1",
|
||||||
"@octokit/plugin-request-log": "^4.0.0",
|
"@octokit/plugin-request-log": "^4.0.0",
|
||||||
"@octokit/plugin-retry": "^6.0.1",
|
"@octokit/plugin-retry": "^6.0.1",
|
||||||
|
"@octokit/plugin-throttling": "^8.2.0",
|
||||||
"@types/node": "^20.9.0"
|
"@types/node": "^20.9.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -64,4 +65,4 @@
|
||||||
"ts-jest": "^29.1.1",
|
"ts-jest": "^29.1.1",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import * as glob from '@actions/glob'
|
||||||
import * as io from '@actions/io'
|
import * as io from '@actions/io'
|
||||||
import {requestLog} from '@octokit/plugin-request-log'
|
import {requestLog} from '@octokit/plugin-request-log'
|
||||||
import {retry} from '@octokit/plugin-retry'
|
import {retry} from '@octokit/plugin-retry'
|
||||||
|
import {throttling, ThrottlingOptions} from '@octokit/plugin-throttling'
|
||||||
import {RequestRequestOptions} from '@octokit/types'
|
import {RequestRequestOptions} from '@octokit/types'
|
||||||
import {callAsyncFunction} from './async-function'
|
import {callAsyncFunction} from './async-function'
|
||||||
import {RetryOptions, getRetryOptions, parseNumberArray} from './retry-options'
|
import {RetryOptions, getRetryOptions, parseNumberArray} from './retry-options'
|
||||||
|
|
@ -20,6 +21,7 @@ type Options = {
|
||||||
baseUrl?: string
|
baseUrl?: string
|
||||||
previews?: string[]
|
previews?: string[]
|
||||||
retry?: RetryOptions
|
retry?: RetryOptions
|
||||||
|
throttle?: ThrottlingOptions
|
||||||
request?: RequestRequestOptions
|
request?: RequestRequestOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,7 +35,7 @@ async function main(): Promise<void> {
|
||||||
const exemptStatusCodes = parseNumberArray(
|
const exemptStatusCodes = parseNumberArray(
|
||||||
core.getInput('retry-exempt-status-codes')
|
core.getInput('retry-exempt-status-codes')
|
||||||
)
|
)
|
||||||
const [retryOpts, requestOpts] = getRetryOptions(
|
const [retryOpts, requestOpts, throttleOpts] = getRetryOptions(
|
||||||
retries,
|
retries,
|
||||||
exemptStatusCodes,
|
exemptStatusCodes,
|
||||||
defaultGitHubOptions
|
defaultGitHubOptions
|
||||||
|
|
@ -44,7 +46,8 @@ async function main(): Promise<void> {
|
||||||
userAgent: userAgent || undefined,
|
userAgent: userAgent || undefined,
|
||||||
previews: previews ? previews.split(',') : undefined,
|
previews: previews ? previews.split(',') : undefined,
|
||||||
retry: retryOpts,
|
retry: retryOpts,
|
||||||
request: requestOpts
|
request: requestOpts,
|
||||||
|
throttle: throttleOpts
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting `baseUrl` to undefined will prevent the default value from being used
|
// Setting `baseUrl` to undefined will prevent the default value from being used
|
||||||
|
|
@ -53,7 +56,7 @@ async function main(): Promise<void> {
|
||||||
opts.baseUrl = baseUrl
|
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})
|
const script = core.getInput('script', {required: true})
|
||||||
|
|
||||||
// Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors.
|
// Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {OctokitOptions} from '@octokit/core/dist-types/types'
|
import {OctokitOptions} from '@octokit/core/dist-types/types'
|
||||||
|
import {ThrottlingOptions} from '@octokit/plugin-throttling'
|
||||||
import {RequestRequestOptions} from '@octokit/types'
|
import {RequestRequestOptions} from '@octokit/types'
|
||||||
|
|
||||||
export type RetryOptions = {
|
export type RetryOptions = {
|
||||||
|
|
@ -11,9 +12,13 @@ export function getRetryOptions(
|
||||||
retries: number,
|
retries: number,
|
||||||
exemptStatusCodes: number[],
|
exemptStatusCodes: number[],
|
||||||
defaultOptions: OctokitOptions
|
defaultOptions: OctokitOptions
|
||||||
): [RetryOptions, RequestRequestOptions | undefined] {
|
): [
|
||||||
|
RetryOptions,
|
||||||
|
RequestRequestOptions | undefined,
|
||||||
|
ThrottlingOptions | undefined
|
||||||
|
] {
|
||||||
if (retries <= 0) {
|
if (retries <= 0) {
|
||||||
return [{enabled: false}, defaultOptions.request]
|
return [{enabled: false}, defaultOptions.request, undefined]
|
||||||
}
|
}
|
||||||
|
|
||||||
const retryOptions: RetryOptions = {
|
const retryOptions: RetryOptions = {
|
||||||
|
|
@ -32,6 +37,21 @@ export function getRetryOptions(
|
||||||
retries
|
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(
|
core.debug(
|
||||||
`GitHub client configured with: (retries: ${
|
`GitHub client configured with: (retries: ${
|
||||||
requestOptions.retries
|
requestOptions.retries
|
||||||
|
|
@ -40,7 +60,7 @@ export function getRetryOptions(
|
||||||
})`
|
})`
|
||||||
)
|
)
|
||||||
|
|
||||||
return [retryOptions, requestOptions]
|
return [retryOptions, requestOptions, throttleOptions]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseNumberArray(listString: string): number[] {
|
export function parseNumberArray(listString: string): number[] {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue