From 4dca78049b8a32dfc9c5d151dd124c76fb93796c Mon Sep 17 00:00:00 2001 From: Clansty Date: Mon, 2 Sep 2024 23:46:54 +0800 Subject: [PATCH] add options to set max attempts and intervals --- README.md | 12 ++++++++++++ __test__/retry-helper.test.ts | 24 ++++++++++++++++++++++++ action.yml | 9 +++++++++ dist/index.js | 14 ++++++++++++-- src/git-source-settings.ts | 15 +++++++++++++++ src/input-helper.ts | 5 +++++ src/main.ts | 2 ++ src/retry-helper.ts | 7 ++++++- 8 files changed, 85 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e1ea032..fe7aecf 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,18 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/ # running from unless specified. Example URLs are https://github.com or # https://my-ghes-server.example.com github-server-url: '' + + # Maximum number of attempts + # Default: 3 + max-attempts: '' + + # Minimum number of seconds to wait before retrying + # Default: 10 + min-retry-interval: '' + + # Maximum number of seconds to wait before retrying + # Default: 20 + max-retry-interval: '' ``` diff --git a/__test__/retry-helper.test.ts b/__test__/retry-helper.test.ts index a5d3f79..cf8cad2 100644 --- a/__test__/retry-helper.test.ts +++ b/__test__/retry-helper.test.ts @@ -84,4 +84,28 @@ describe('retry-helper tests', () => { expect(info[2]).toBe('some error 2') expect(info[3]).toMatch(/Waiting .+ seconds before trying again/) }) + + it('should be able to set max attempts', async () => { + let attempts = 0 + let error: Error = null as unknown as Error + try { + retryHelper.config(5, 1, 5) + await retryHelper.execute(() => { + throw new Error(`some error ${++attempts}`) + }) + } catch (err) { + error = err as Error + } + expect(error.message).toBe('some error 5') + expect(attempts).toBe(5) + expect(info).toHaveLength(6) + expect(info[0]).toBe('some error 1') + expect(info[1]).toMatch(/Waiting .+ seconds before trying again/) + expect(info[2]).toBe('some error 2') + expect(info[3]).toMatch(/Waiting .+ seconds before trying again/) + expect(info[4]).toBe('some error 3') + expect(info[5]).toMatch(/Waiting .+ seconds before trying again/) + expect(info[6]).toBe('some error 4') + expect(info[7]).toMatch(/Waiting .+ seconds before trying again/) + }) }) diff --git a/action.yml b/action.yml index 75d5ae2..6a37d5e 100644 --- a/action.yml +++ b/action.yml @@ -98,6 +98,15 @@ inputs: github-server-url: description: The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com required: false + max-attempts: + description: Maximum number of attempts + default: 3 + min-retry-interval: + description: Minimum number of seconds to wait before retrying + default: 10 + max-retry-interval: + description: Maximum number of seconds to wait before retrying + default: 20 runs: using: node20 main: dist/index.js diff --git a/dist/index.js b/dist/index.js index 9d959a9..eb0ab92 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1835,6 +1835,10 @@ function getInputs() { // Determine the GitHub URL that the repository is being hosted from result.githubServerUrl = core.getInput('github-server-url'); core.debug(`GitHub Host URL = ${result.githubServerUrl}`); + // Retry + result.maxAttempts = parseInt(core.getInput('max-attempts') || '3'); + result.minRetryInterval = parseInt(core.getInput('min-retry-interval') || '10'); + result.maxRetryInterval = parseInt(core.getInput('max-retry-interval') || '20'); return result; }); } @@ -1887,11 +1891,13 @@ const gitSourceProvider = __importStar(__nccwpck_require__(9210)); const inputHelper = __importStar(__nccwpck_require__(5480)); const path = __importStar(__nccwpck_require__(1017)); const stateHelper = __importStar(__nccwpck_require__(4866)); +const retryHelper = __importStar(__nccwpck_require__(2155)); function run() { return __awaiter(this, void 0, void 0, function* () { var _a; try { const sourceSettings = yield inputHelper.getInputs(); + retryHelper.config(sourceSettings.maxAttempts, sourceSettings.minRetryInterval, sourceSettings.maxRetryInterval); try { // Register problem matcher coreCommand.issueCommand('add-matcher', {}, path.join(__dirname, 'problem-matcher.json')); @@ -2265,7 +2271,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.execute = exports.RetryHelper = void 0; +exports.config = exports.execute = exports.RetryHelper = void 0; const core = __importStar(__nccwpck_require__(2186)); const defaultMaxAttempts = 3; const defaultMinSeconds = 10; @@ -2311,13 +2317,17 @@ class RetryHelper { } } exports.RetryHelper = RetryHelper; +let retryHelper = new RetryHelper(); function execute(action) { return __awaiter(this, void 0, void 0, function* () { - const retryHelper = new RetryHelper(); return yield retryHelper.execute(action); }); } exports.execute = execute; +function config(maxAttempts, minSeconds, maxSeconds) { + retryHelper = new RetryHelper(maxAttempts, minSeconds, maxSeconds); +} +exports.config = config; /***/ }), diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts index 4e41ac3..9c6b663 100644 --- a/src/git-source-settings.ts +++ b/src/git-source-settings.ts @@ -118,4 +118,19 @@ export interface IGitSourceSettings { * User override on the GitHub Server/Host URL that hosts the repository to be cloned */ githubServerUrl: string | undefined + + /** + * Retry helper max attempts + */ + maxAttempts: number + + /** + * Retry helper min interval seconds + */ + minRetryInterval: number + + /** + * Retry helper max interval seconds + */ + maxRetryInterval: number } diff --git a/src/input-helper.ts b/src/input-helper.ts index 059232f..a5f3ecc 100644 --- a/src/input-helper.ts +++ b/src/input-helper.ts @@ -161,5 +161,10 @@ export async function getInputs(): Promise { result.githubServerUrl = core.getInput('github-server-url') core.debug(`GitHub Host URL = ${result.githubServerUrl}`) + // Retry + result.maxAttempts = parseInt(core.getInput('max-attempts') || '3') + result.minRetryInterval = parseInt(core.getInput('min-retry-interval') || '10') + result.maxRetryInterval = parseInt(core.getInput('max-retry-interval') || '20') + return result } diff --git a/src/main.ts b/src/main.ts index 97a27af..80a7dbd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,10 +4,12 @@ import * as gitSourceProvider from './git-source-provider' import * as inputHelper from './input-helper' import * as path from 'path' import * as stateHelper from './state-helper' +import * as retryHelper from './retry-helper' async function run(): Promise { try { const sourceSettings = await inputHelper.getInputs() + retryHelper.config(sourceSettings.maxAttempts, sourceSettings.minRetryInterval, sourceSettings.maxRetryInterval) try { // Register problem matcher diff --git a/src/retry-helper.ts b/src/retry-helper.ts index 323e75d..71b1b15 100644 --- a/src/retry-helper.ts +++ b/src/retry-helper.ts @@ -55,7 +55,12 @@ export class RetryHelper { } } +let retryHelper = new RetryHelper() + export async function execute(action: () => Promise): Promise { - const retryHelper = new RetryHelper() return await retryHelper.execute(action) } + +export function config(maxAttempts: number, minSeconds: number, maxSeconds: number): void { + retryHelper = new RetryHelper(maxAttempts, minSeconds, maxSeconds) +}