mirror of
https://github.com/nick-fields/retry.git
synced 2026-02-10 07:05:29 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f8f3d9f0f | ||
|
|
bf1736e338 | ||
|
|
f7cf641580 | ||
|
|
002ef572db | ||
|
|
e80198a9da | ||
|
|
c77dc43532 | ||
|
|
0019811846 | ||
|
|
a63662d5a7 | ||
|
|
67e1bdfd8d | ||
|
|
45ba062d35 | ||
|
|
0470ad1628 | ||
|
|
2750220347 | ||
|
|
b00fd808da | ||
|
|
bebba89192 | ||
|
|
52b3fdbcaa | ||
|
|
f3f0bb1a3c | ||
|
|
7c68161adf | ||
|
|
025c480d85 | ||
|
|
3073a9f1e1 | ||
|
|
9e6dab8302 | ||
|
|
7463808b4e |
84
.github/workflows/ci_cd.yml
vendored
84
.github/workflows/ci_cd.yml
vendored
@@ -60,6 +60,35 @@ jobs:
|
||||
actual: ${{ steps.sad_path_wait_sec.outputs.exit_error }}
|
||||
comparison: contains
|
||||
|
||||
- name: new-command-on-retry
|
||||
id: new-command-on-retry
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 3
|
||||
command: node -e "process.exit(1)"
|
||||
new_command_on_retry: node -e "console.log('this is the new command on retry')"
|
||||
|
||||
- name: on-retry-cmd
|
||||
id: on-retry-cmd
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 3
|
||||
command: node -e "process.exit(1)"
|
||||
on_retry_command: node -e "console.log('this is a retry command')"
|
||||
|
||||
- name: on-retry-cmd (on-retry fails)
|
||||
id: on-retry-cmd-fails
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 3
|
||||
command: node -e "process.exit(1)"
|
||||
on_retry_command: node -e "throw new Error('This is an on-retry command error')"
|
||||
|
||||
- name: sad-path (error)
|
||||
id: sad_path_error
|
||||
uses: ./
|
||||
@@ -77,6 +106,41 @@ jobs:
|
||||
expected: failure
|
||||
actual: ${{ steps.sad_path_error.outcome }}
|
||||
|
||||
- name: happy-path (continue_on_error)
|
||||
id: happy_path_continue_on_error
|
||||
uses: ./
|
||||
with:
|
||||
command: node -e "process.exit(0)"
|
||||
timeout_minutes: 1
|
||||
continue_on_error: true
|
||||
- name: sad-path (continue_on_error)
|
||||
id: sad_path_continue_on_error
|
||||
uses: ./
|
||||
with:
|
||||
command: node -e "process.exit(33)"
|
||||
timeout_minutes: 1
|
||||
continue_on_error: true
|
||||
- name: Verify continue_on_error returns correct exit code on success
|
||||
uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: 0
|
||||
actual: ${{ steps.happy_path_continue_on_error.outputs.exit_code }}
|
||||
- name: Verify continue_on_error exits with correct outcome on success
|
||||
uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: success
|
||||
actual: ${{ steps.happy_path_continue_on_error.outcome }}
|
||||
- name: Verify continue_on_error returns correct exit code on error
|
||||
uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: 33
|
||||
actual: ${{ steps.sad_path_continue_on_error.outputs.exit_code }}
|
||||
- name: Verify continue_on_error exits with successful outcome when an error occurs
|
||||
uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: success
|
||||
actual: ${{ steps.sad_path_continue_on_error.outcome }}
|
||||
|
||||
- name: retry_on (timeout) fails early if error encountered
|
||||
id: retry_on_timeout_fail
|
||||
uses: ./
|
||||
@@ -121,7 +185,6 @@ jobs:
|
||||
expected: 2
|
||||
actual: ${{ steps.retry_on_error.outputs.exit_code }}
|
||||
|
||||
|
||||
# timeout tests (takes longer to run so run last)
|
||||
- name: sad-path (timeout)
|
||||
id: sad_path_timeout
|
||||
@@ -205,7 +268,7 @@ jobs:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
shell: cmd
|
||||
command: "dir"
|
||||
command: 'dir'
|
||||
- uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: 2
|
||||
@@ -249,6 +312,23 @@ jobs:
|
||||
max_attempts: 2
|
||||
shell: python
|
||||
command: print('1', '2', '3')
|
||||
- name: Multi-line multi-command Test
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
command: |
|
||||
Get-ComputerInfo
|
||||
Get-Date
|
||||
- name: Multi-line single-command Test
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
shell: cmd
|
||||
command: >-
|
||||
echo "this is
|
||||
a test"
|
||||
|
||||
# runs on push to master only
|
||||
cd:
|
||||
|
||||
@@ -8,6 +8,7 @@ module.exports = {
|
||||
{ type: 'minor', release: 'minor' },
|
||||
{ type: 'major', release: 'major' },
|
||||
{ type: 'patch', release: 'patch' },
|
||||
{ type: 'test', release: false },
|
||||
{ scope: 'no-release', release: false },
|
||||
],
|
||||
},
|
||||
|
||||
89
README.md
89
README.md
@@ -25,8 +25,8 @@ Retries an Action step on failure or timeout. This is currently intended to repl
|
||||
**Optional** Number of seconds to wait before attempting the next retry. Defaults to `10`
|
||||
|
||||
### `shell`
|
||||
|
||||
**Optional** Shell to use to execute `command`. Defaults to `powershell` on Windows, `bash` otherwise. Supports bash, python, pwsh, sh, cmd, and powershell per [docs](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell)
|
||||
|
||||
**Optional** Shell to use to execute `command`. Defaults to `powershell` on Windows, `bash` otherwise. Supports bash, python, pwsh, sh, cmd, and powershell per [docs](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell)
|
||||
|
||||
### `polling_interval_seconds`
|
||||
|
||||
@@ -40,6 +40,18 @@ Retries an Action step on failure or timeout. This is currently intended to repl
|
||||
|
||||
**Optional** Whether to output a warning on retry, or just output to info. Defaults to `true`.
|
||||
|
||||
### `on_retry_command`
|
||||
|
||||
**Optional** Command to run before a retry (such as a cleanup script). Any error thrown from retry command is caught and surfaced as a warning.
|
||||
|
||||
### `new_command_on_retry`
|
||||
|
||||
**Optional** Command to run if the first attempt fails. This command will be called on all subsequent attempts.
|
||||
|
||||
### `continue_on_error`
|
||||
|
||||
**Optional** Exit successfully even if an error occurs. Same as native continue-on-error behavior, but for use in composite actions. Defaults to `false`
|
||||
|
||||
## Outputs
|
||||
|
||||
### `total_attempts`
|
||||
@@ -109,7 +121,29 @@ with:
|
||||
command: npm run some-typically-fast-script
|
||||
```
|
||||
|
||||
### Retry but allow failure and do something with output
|
||||
### Retry using continue_on_error input (in composite action) but allow failure and do something with output
|
||||
|
||||
```yaml
|
||||
- uses: nick-invision/retry@v2
|
||||
id: retry
|
||||
with:
|
||||
timeout_seconds: 15
|
||||
max_attempts: 3
|
||||
continue_on_error: true
|
||||
command: node -e 'process.exit(99);'
|
||||
- name: Assert that step succeeded (despite failing command)
|
||||
uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: success
|
||||
actual: ${{ steps.retry.outcome }}
|
||||
- name: Assert that action exited with expected exit code
|
||||
uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: 99
|
||||
actual: ${{ steps.retry.outputs.exit_code }}
|
||||
```
|
||||
|
||||
### Retry using continue-on-error built-in command (in workflow action) but allow failure and do something with output
|
||||
|
||||
```yaml
|
||||
- uses: nick-invision/retry@v2
|
||||
@@ -138,6 +172,55 @@ with:
|
||||
actual: ${{ steps.retry.outputs.total_attempts }}
|
||||
```
|
||||
|
||||
### Run script after failure but before retry
|
||||
|
||||
```yaml
|
||||
uses: nick-invision/retry@v2
|
||||
with:
|
||||
timeout_seconds: 15
|
||||
max_attempts: 3
|
||||
command: npm run some-flaky-script-that-outputs-something
|
||||
on_retry_command: npm run cleanup-flaky-script-output
|
||||
```
|
||||
|
||||
### Run different command after first failure
|
||||
|
||||
```yaml
|
||||
uses: nick-invision/retry@v2
|
||||
with:
|
||||
timeout_seconds: 15
|
||||
max_attempts: 3
|
||||
command: npx jest
|
||||
new_command_on_retry: npx jest --onlyFailures
|
||||
```
|
||||
|
||||
### Run multi-line, multi-command script
|
||||
|
||||
```yaml
|
||||
name: Multi-line multi-command Test
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
command: |
|
||||
Get-ComputerInfo
|
||||
Get-Date
|
||||
```
|
||||
|
||||
### Run multi-line, single-command script
|
||||
|
||||
```yaml
|
||||
name: Multi-line single-command Test
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
shell: cmd
|
||||
command: >-
|
||||
echo "this is
|
||||
a test"
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
NodeJS is required for this action to run. This runs without issue on all GitHub hosted runners but if you are running into issues with this on self hosted runners ensure NodeJS is installed.
|
||||
|
||||
11
action.yml
11
action.yml
@@ -30,6 +30,15 @@ inputs:
|
||||
warning_on_retry:
|
||||
description: Whether to output a warning on retry, or just output to info. Defaults to true
|
||||
default: true
|
||||
on_retry_command:
|
||||
description: Command to run before a retry (such as a cleanup script). Any error thrown from retry command is caught and surfaced as a warning.
|
||||
required: false
|
||||
continue_on_error:
|
||||
description: Exits successfully even if an error occurs. Same as native continue-on-error behavior, but for use in composite actions. Default is false
|
||||
default: false
|
||||
new_command_on_retry:
|
||||
description: Command to run if the first attempt fails. This command will be called on all subsequent attempts.
|
||||
required: false
|
||||
outputs:
|
||||
total_attempts:
|
||||
description: The final number of attempts made
|
||||
@@ -39,4 +48,4 @@ outputs:
|
||||
description: The final error returned by the command
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'dist/index.js'
|
||||
main: 'dist/index.js'
|
||||
|
||||
256
dist/index.js
vendored
256
dist/index.js
vendored
@@ -51,6 +51,7 @@ module.exports =
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toCommandProperties = exports.toCommandValue = void 0;
|
||||
/**
|
||||
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
||||
* @param input input to sanitize into a string
|
||||
@@ -65,6 +66,25 @@ function toCommandValue(input) {
|
||||
return JSON.stringify(input);
|
||||
}
|
||||
exports.toCommandValue = toCommandValue;
|
||||
/**
|
||||
*
|
||||
* @param annotationProperties
|
||||
* @returns The command properties to send with the actual annotation command
|
||||
* See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646
|
||||
*/
|
||||
function toCommandProperties(annotationProperties) {
|
||||
if (!Object.keys(annotationProperties).length) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
title: annotationProperties.title,
|
||||
line: annotationProperties.startLine,
|
||||
endLine: annotationProperties.endLine,
|
||||
col: annotationProperties.startColumn,
|
||||
endColumn: annotationProperties.endColumn
|
||||
};
|
||||
}
|
||||
exports.toCommandProperties = toCommandProperties;
|
||||
//# sourceMappingURL=utils.js.map
|
||||
|
||||
/***/ }),
|
||||
@@ -82,14 +102,27 @@ module.exports = require("os");
|
||||
"use strict";
|
||||
|
||||
// For internal use, subject to change.
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.issueCommand = void 0;
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
@@ -253,6 +286,9 @@ var SHELL = core_1.getInput('shell');
|
||||
var POLLING_INTERVAL_SECONDS = getInputNumber('polling_interval_seconds', false) || 1;
|
||||
var RETRY_ON = core_1.getInput('retry_on') || 'any';
|
||||
var WARNING_ON_RETRY = core_1.getInput('warning_on_retry').toLowerCase() === 'true';
|
||||
var ON_RETRY_COMMAND = core_1.getInput('on_retry_command');
|
||||
var CONTINUE_ON_ERROR = getInputBoolean('continue_on_error');
|
||||
var NEW_COMMAND_ON_RETRY = core_1.getInput('new_command_on_retry');
|
||||
var OS = process.platform;
|
||||
var OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts';
|
||||
var OUTPUT_EXIT_CODE_KEY = 'exit_code';
|
||||
@@ -271,6 +307,13 @@ function getInputNumber(id, required) {
|
||||
}
|
||||
return num;
|
||||
}
|
||||
function getInputBoolean(id) {
|
||||
var input = core_1.getInput(id);
|
||||
if (!['true', 'false'].includes(input.toLowerCase())) {
|
||||
throw "Input " + id + " only accepts boolean values. Received " + input;
|
||||
}
|
||||
return input.toLowerCase() === 'true';
|
||||
}
|
||||
function retryWait() {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var waitStart;
|
||||
@@ -340,7 +383,33 @@ function getExecutable() {
|
||||
}
|
||||
return executable;
|
||||
}
|
||||
function runCmd() {
|
||||
function runRetryCmd() {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var error_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
// if no retry script, just continue
|
||||
if (!ON_RETRY_COMMAND) {
|
||||
return [2 /*return*/];
|
||||
}
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, child_process_1.execSync(ON_RETRY_COMMAND, { stdio: 'inherit' })];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
error_1 = _a.sent();
|
||||
core_1.info("WARNING: Retry command threw the error " + error_1.message);
|
||||
return [3 /*break*/, 4];
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function runCmd(attempt) {
|
||||
var _a, _b;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var end_time, executable, child;
|
||||
@@ -352,7 +421,9 @@ function runCmd() {
|
||||
exit = 0;
|
||||
done = false;
|
||||
core_1.debug("Running command " + COMMAND + " on " + OS + " using shell " + executable);
|
||||
child = child_process_1.exec(COMMAND, { 'shell': executable });
|
||||
child = attempt > 1 && NEW_COMMAND_ON_RETRY
|
||||
? child_process_1.exec(NEW_COMMAND_ON_RETRY, { 'shell': executable })
|
||||
: child_process_1.exec(COMMAND, { 'shell': executable });
|
||||
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) {
|
||||
process.stdout.write(data);
|
||||
});
|
||||
@@ -399,7 +470,7 @@ function runCmd() {
|
||||
}
|
||||
function runAction() {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var attempt, error_1;
|
||||
var attempt, error_2;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, validateInputs()];
|
||||
@@ -408,43 +479,44 @@ function runAction() {
|
||||
attempt = 1;
|
||||
_a.label = 2;
|
||||
case 2:
|
||||
if (!(attempt <= MAX_ATTEMPTS)) return [3 /*break*/, 7];
|
||||
if (!(attempt <= MAX_ATTEMPTS)) return [3 /*break*/, 12];
|
||||
_a.label = 3;
|
||||
case 3:
|
||||
_a.trys.push([3, 5, , 6]);
|
||||
_a.trys.push([3, 5, , 11]);
|
||||
// just keep overwriting attempts output
|
||||
core_1.setOutput(OUTPUT_TOTAL_ATTEMPTS_KEY, attempt);
|
||||
return [4 /*yield*/, runCmd()];
|
||||
return [4 /*yield*/, runCmd(attempt)];
|
||||
case 4:
|
||||
_a.sent();
|
||||
core_1.info("Command completed after " + attempt + " attempt(s).");
|
||||
return [3 /*break*/, 7];
|
||||
return [3 /*break*/, 12];
|
||||
case 5:
|
||||
error_1 = _a.sent();
|
||||
if (attempt === MAX_ATTEMPTS) {
|
||||
throw new Error("Final attempt failed. " + error_1.message);
|
||||
}
|
||||
else if (!done && RETRY_ON === 'error') {
|
||||
// error: timeout
|
||||
throw error_1;
|
||||
}
|
||||
else if (exit > 0 && RETRY_ON === 'timeout') {
|
||||
// error: error
|
||||
throw error_1;
|
||||
error_2 = _a.sent();
|
||||
if (!(attempt === MAX_ATTEMPTS)) return [3 /*break*/, 6];
|
||||
throw new Error("Final attempt failed. " + error_2.message);
|
||||
case 6:
|
||||
if (!(!done && RETRY_ON === 'error')) return [3 /*break*/, 7];
|
||||
// error: timeout
|
||||
throw error_2;
|
||||
case 7:
|
||||
if (!(exit > 0 && RETRY_ON === 'timeout')) return [3 /*break*/, 8];
|
||||
// error: error
|
||||
throw error_2;
|
||||
case 8: return [4 /*yield*/, runRetryCmd()];
|
||||
case 9:
|
||||
_a.sent();
|
||||
if (WARNING_ON_RETRY) {
|
||||
core_1.warning("Attempt " + attempt + " failed. Reason: " + error_2.message);
|
||||
}
|
||||
else {
|
||||
if (WARNING_ON_RETRY) {
|
||||
core_1.warning("Attempt " + attempt + " failed. Reason: " + error_1.message);
|
||||
}
|
||||
else {
|
||||
core_1.info("Attempt " + attempt + " failed. Reason: " + error_1.message);
|
||||
}
|
||||
core_1.info("Attempt " + attempt + " failed. Reason: " + error_2.message);
|
||||
}
|
||||
return [3 /*break*/, 6];
|
||||
case 6:
|
||||
_a.label = 10;
|
||||
case 10: return [3 /*break*/, 11];
|
||||
case 11:
|
||||
attempt++;
|
||||
return [3 /*break*/, 2];
|
||||
case 7: return [2 /*return*/];
|
||||
case 12: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -455,12 +527,20 @@ runAction()
|
||||
process.exit(0); // success
|
||||
})
|
||||
.catch(function (err) {
|
||||
core_1.error(err.message);
|
||||
// exact error code if available, otherwise just 1
|
||||
var exitCode = exit > 0 ? exit : 1;
|
||||
if (CONTINUE_ON_ERROR) {
|
||||
core_1.warning(err.message);
|
||||
}
|
||||
else {
|
||||
core_1.error(err.message);
|
||||
}
|
||||
// these can be helpful to know if continue-on-error is true
|
||||
core_1.setOutput(OUTPUT_EXIT_ERROR_KEY, err.message);
|
||||
core_1.setOutput(OUTPUT_EXIT_CODE_KEY, exit > 0 ? exit : 1);
|
||||
// exit with exact error code if available, otherwise just exit with 1
|
||||
process.exit(exit > 0 ? exit : 1);
|
||||
core_1.setOutput(OUTPUT_EXIT_CODE_KEY, exitCode);
|
||||
// if continue_on_error, exit with exact error code else exit gracefully
|
||||
// mimics native continue-on-error that is not supported in composite actions
|
||||
process.exit(CONTINUE_ON_ERROR ? 0 : exitCode);
|
||||
});
|
||||
|
||||
|
||||
@@ -471,14 +551,27 @@ runAction()
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.issue = exports.issueCommand = void 0;
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const utils_1 = __webpack_require__(82);
|
||||
/**
|
||||
@@ -557,6 +650,25 @@ function escapeProperty(s) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -566,14 +678,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;
|
||||
const command_1 = __webpack_require__(431);
|
||||
const file_command_1 = __webpack_require__(102);
|
||||
const utils_1 = __webpack_require__(82);
|
||||
@@ -640,7 +746,9 @@ function addPath(inputPath) {
|
||||
}
|
||||
exports.addPath = addPath;
|
||||
/**
|
||||
* Gets the value of an input. The value is also trimmed.
|
||||
* Gets the value of an input.
|
||||
* Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.
|
||||
* Returns an empty string if the value is not defined.
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
@@ -651,9 +759,49 @@ function getInput(name, options) {
|
||||
if (options && options.required && !val) {
|
||||
throw new Error(`Input required and not supplied: ${name}`);
|
||||
}
|
||||
if (options && options.trimWhitespace === false) {
|
||||
return val;
|
||||
}
|
||||
return val.trim();
|
||||
}
|
||||
exports.getInput = getInput;
|
||||
/**
|
||||
* Gets the values of an multiline input. Each value is also trimmed.
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns string[]
|
||||
*
|
||||
*/
|
||||
function getMultilineInput(name, options) {
|
||||
const inputs = getInput(name, options)
|
||||
.split('\n')
|
||||
.filter(x => x !== '');
|
||||
return inputs;
|
||||
}
|
||||
exports.getMultilineInput = getMultilineInput;
|
||||
/**
|
||||
* Gets the input value of the boolean type in the YAML 1.2 "core schema" specification.
|
||||
* Support boolean input list: `true | True | TRUE | false | False | FALSE` .
|
||||
* The return value is also in boolean type.
|
||||
* ref: https://yaml.org/spec/1.2/spec.html#id2804923
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns boolean
|
||||
*/
|
||||
function getBooleanInput(name, options) {
|
||||
const trueValue = ['true', 'True', 'TRUE'];
|
||||
const falseValue = ['false', 'False', 'FALSE'];
|
||||
const val = getInput(name, options);
|
||||
if (trueValue.includes(val))
|
||||
return true;
|
||||
if (falseValue.includes(val))
|
||||
return false;
|
||||
throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` +
|
||||
`Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
|
||||
}
|
||||
exports.getBooleanInput = getBooleanInput;
|
||||
/**
|
||||
* Sets the value of an output.
|
||||
*
|
||||
@@ -662,6 +810,7 @@ exports.getInput = getInput;
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function setOutput(name, value) {
|
||||
process.stdout.write(os.EOL);
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
@@ -708,19 +857,30 @@ exports.debug = debug;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message. Errors will be converted to string via toString()
|
||||
* @param properties optional properties to add to the annotation.
|
||||
*/
|
||||
function error(message) {
|
||||
command_1.issue('error', message instanceof Error ? message.toString() : message);
|
||||
function error(message, properties = {}) {
|
||||
command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.error = error;
|
||||
/**
|
||||
* Adds an warning issue
|
||||
* Adds a warning issue
|
||||
* @param message warning issue message. Errors will be converted to string via toString()
|
||||
* @param properties optional properties to add to the annotation.
|
||||
*/
|
||||
function warning(message) {
|
||||
command_1.issue('warning', message instanceof Error ? message.toString() : message);
|
||||
function warning(message, properties = {}) {
|
||||
command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.warning = warning;
|
||||
/**
|
||||
* Adds a notice issue
|
||||
* @param message notice issue message. Errors will be converted to string via toString()
|
||||
* @param properties optional properties to add to the annotation.
|
||||
*/
|
||||
function notice(message, properties = {}) {
|
||||
command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.notice = notice;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
|
||||
121
package-lock.json
generated
121
package-lock.json
generated
@@ -5,9 +5,9 @@
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
|
||||
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.5.0.tgz",
|
||||
"integrity": "sha512-eDOLH1Nq9zh+PJlYLqEMkS/jLQxhksPNmUGNBHfa4G+tQmnIhzpctxmchETtVGyBOvXgOVVpYuE40+eS4cUnwQ=="
|
||||
},
|
||||
"@babel/code-frame": {
|
||||
"version": "7.8.3",
|
||||
@@ -104,12 +104,6 @@
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
@@ -138,14 +132,6 @@
|
||||
"requires": {
|
||||
"@commitlint/types": "^11.0.0",
|
||||
"lodash": "^4.17.19"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@commitlint/execute-rule": {
|
||||
@@ -313,12 +299,6 @@
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"dev": true
|
||||
},
|
||||
"parse-json": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
|
||||
@@ -385,14 +365,6 @@
|
||||
"lodash": "^4.17.19",
|
||||
"resolve-from": "^5.0.0",
|
||||
"resolve-global": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@commitlint/rules": {
|
||||
@@ -1372,9 +1344,9 @@
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz",
|
||||
"integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
|
||||
"integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@@ -1512,9 +1484,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-package-data": {
|
||||
@@ -2123,9 +2095,9 @@
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz",
|
||||
"integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
|
||||
"integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@@ -2255,9 +2227,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-package-data": {
|
||||
@@ -2395,9 +2367,9 @@
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -2433,9 +2405,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"handlebars": {
|
||||
"version": "4.7.6",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
|
||||
"integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
|
||||
"version": "4.7.7",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
|
||||
"integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5",
|
||||
@@ -2473,9 +2445,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz",
|
||||
"integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==",
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"http-proxy-agent": {
|
||||
@@ -2630,9 +2602,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"dev": true
|
||||
},
|
||||
"into-stream": {
|
||||
@@ -2846,9 +2818,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash._reinterpolate": {
|
||||
@@ -3159,9 +3131,9 @@
|
||||
}
|
||||
},
|
||||
"normalize-url": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-5.3.0.tgz",
|
||||
"integrity": "sha512-9/nOVLYYe/dO/eJeQUNaGUF4m4Z5E7cb9oNTKabH+bNf19mqj60txTcveQxL0GlcWLXCxkOu2/LwL8oW0idIDA==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-5.3.1.tgz",
|
||||
"integrity": "sha512-K1c7+vaAP+Yh5bOGmA10PGPpp+6h7WZrl7GwqKhUflBc9flU9pzG27DDeB9+iuhZkE3BJZOcgN1P/2sS5pqrWw==",
|
||||
"dev": true
|
||||
},
|
||||
"npm": {
|
||||
@@ -4475,11 +4447,6 @@
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "3.8.1",
|
||||
"bundled": true,
|
||||
@@ -4571,11 +4538,6 @@
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"init-package-json": {
|
||||
"version": "1.10.3",
|
||||
"bundled": true,
|
||||
@@ -6567,11 +6529,6 @@
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
@@ -7163,9 +7120,9 @@
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz",
|
||||
"integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
|
||||
"integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@@ -7778,9 +7735,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/nick-invision/retry#readme",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/core": "^1.5.0",
|
||||
"milliseconds": "^1.0.3",
|
||||
"tree-kill": "^1.2.2"
|
||||
},
|
||||
|
||||
52
src/index.ts
52
src/index.ts
@@ -1,5 +1,5 @@
|
||||
import { getInput, error, warning, info, debug, setOutput } from '@actions/core';
|
||||
import { exec } from 'child_process';
|
||||
import { exec, execSync } from 'child_process';
|
||||
import ms from 'milliseconds';
|
||||
import kill from 'tree-kill';
|
||||
|
||||
@@ -15,6 +15,9 @@ const SHELL = getInput('shell');
|
||||
const POLLING_INTERVAL_SECONDS = getInputNumber('polling_interval_seconds', false) || 1;
|
||||
const RETRY_ON = getInput('retry_on') || 'any';
|
||||
const WARNING_ON_RETRY = getInput('warning_on_retry').toLowerCase() === 'true';
|
||||
const ON_RETRY_COMMAND = getInput('on_retry_command');
|
||||
const CONTINUE_ON_ERROR = getInputBoolean('continue_on_error');
|
||||
const NEW_COMMAND_ON_RETRY = getInput('new_command_on_retry');
|
||||
|
||||
const OS = process.platform;
|
||||
const OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts';
|
||||
@@ -40,6 +43,15 @@ function getInputNumber(id: string, required: boolean): number | undefined {
|
||||
return num;
|
||||
}
|
||||
|
||||
function getInputBoolean(id: string): Boolean {
|
||||
const input = getInput(id);
|
||||
|
||||
if (!['true','false'].includes(input.toLowerCase())) {
|
||||
throw `Input ${id} only accepts boolean values. Received ${input}`;
|
||||
}
|
||||
return input.toLowerCase() === 'true'
|
||||
}
|
||||
|
||||
async function retryWait() {
|
||||
const waitStart = Date.now();
|
||||
await wait(ms.seconds(RETRY_WAIT_SECONDS));
|
||||
@@ -98,7 +110,20 @@ function getExecutable(): string {
|
||||
return executable
|
||||
}
|
||||
|
||||
async function runCmd() {
|
||||
async function runRetryCmd(): Promise<void> {
|
||||
// if no retry script, just continue
|
||||
if (!ON_RETRY_COMMAND) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await execSync(ON_RETRY_COMMAND, { stdio: 'inherit' });
|
||||
} catch (error) {
|
||||
info(`WARNING: Retry command threw the error ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function runCmd(attempt: number) {
|
||||
const end_time = Date.now() + getTimeout();
|
||||
const executable = getExecutable();
|
||||
|
||||
@@ -106,7 +131,9 @@ async function runCmd() {
|
||||
done = false;
|
||||
|
||||
debug(`Running command ${COMMAND} on ${OS} using shell ${executable}`)
|
||||
var child = exec(COMMAND, { 'shell': executable });
|
||||
var child = attempt > 1 && NEW_COMMAND_ON_RETRY
|
||||
? exec(NEW_COMMAND_ON_RETRY, { 'shell': executable })
|
||||
: exec(COMMAND, { 'shell': executable });
|
||||
|
||||
child.stdout?.on('data', (data) => {
|
||||
process.stdout.write(data);
|
||||
@@ -151,7 +178,7 @@ async function runAction() {
|
||||
try {
|
||||
// just keep overwriting attempts output
|
||||
setOutput(OUTPUT_TOTAL_ATTEMPTS_KEY, attempt);
|
||||
await runCmd();
|
||||
await runCmd(attempt);
|
||||
info(`Command completed after ${attempt} attempt(s).`);
|
||||
break;
|
||||
} catch (error) {
|
||||
@@ -164,6 +191,7 @@ async function runAction() {
|
||||
// error: error
|
||||
throw error;
|
||||
} else {
|
||||
await runRetryCmd();
|
||||
if (WARNING_ON_RETRY) {
|
||||
warning(`Attempt ${attempt} failed. Reason: ${error.message}`);
|
||||
} else {
|
||||
@@ -180,12 +208,20 @@ runAction()
|
||||
process.exit(0); // success
|
||||
})
|
||||
.catch((err) => {
|
||||
error(err.message);
|
||||
// exact error code if available, otherwise just 1
|
||||
const exitCode = exit > 0 ? exit : 1;
|
||||
|
||||
if (CONTINUE_ON_ERROR) {
|
||||
warning(err.message);
|
||||
} else {
|
||||
error(err.message);
|
||||
}
|
||||
|
||||
// these can be helpful to know if continue-on-error is true
|
||||
setOutput(OUTPUT_EXIT_ERROR_KEY, err.message);
|
||||
setOutput(OUTPUT_EXIT_CODE_KEY, exit > 0 ? exit : 1);
|
||||
setOutput(OUTPUT_EXIT_CODE_KEY, exitCode);
|
||||
|
||||
// exit with exact error code if available, otherwise just exit with 1
|
||||
process.exit(exit > 0 ? exit : 1);
|
||||
// if continue_on_error, exit with exact error code else exit gracefully
|
||||
// mimics native continue-on-error that is not supported in composite actions
|
||||
process.exit(CONTINUE_ON_ERROR ? 0 : exitCode);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user