Improve README and action.yml

This commit is contained in:
Michal Dorner 2021-01-23 11:51:25 +01:00
parent 8fdf2aead9
commit 92cb68e21e
No known key found for this signature in database
GPG key ID: 9EEE04B48DA36786
7 changed files with 299 additions and 80 deletions

View file

@ -1,7 +1,7 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2020 Michal Dorner and contributors Copyright (c) 2021 Michal Dorner and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -19,4 +19,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.

186
README.md
View file

@ -1,12 +1,180 @@
**WIP** # Test Reporter
# Test Check Report This [Github Action](https://github.com/features/actions) displays test results from popular testing frameworks directly in GitHub.
- [x] Parses test results in XML or JSON format and creates nice report (Github Check Run)
- [x] Annotates code where it failed based on message and stack trace captured during test execution
- [x] Sets output variable conclusion to `success` if all tests passed or `failure` if any test failed
Goal of this project is to create [Github Action](https://github.com/features/actions) **Supported languages / frameworks:**
that could presents test results from popular testing frameworks as Github check run with code annotation in places where test failed. - .NET / [xUnit](https://xunit.net/) / [NUnit](https://nunit.org/) / [MSTest](https://github.com/Microsoft/testfx-docs)
- Dart / [test](https://pub.dev/packages/test)
- Flutter / [test](https://pub.dev/packages/test)
- JavaScript / [JEST](https://jestjs.io/)
Support for following test reports are planned for initial release: For more information see [Supported formats](#supported-formats) section.
- [ ] dart-json: [`dart test --file-reporter=\"json:test-results.json`](https://pub.dev/packages/test)
- [ ] dotnet-trx: [`dotnet test --logger "trx;LogFileName=test-results.trx"`](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test#examples) **Support is planned for:**
- [ ] flutter-machine: [`flutter test --machine > test-results.json`](https://flutter.dev/docs/cookbook/testing/unit/introduction) - Java / [JUnit 5](https://junit.org/junit5/)
- [ ] jest-junit: [`jest --ci --reporters=jest-junit`](https://github.com/jest-community/jest-junit#readme)
Do you miss support for your favorite language or framework?
Please create [Issue](https://github.com/dorny/test-reporter/issues/new) or contribute with PR.
## Example
```yaml
jobs:
build-test:
name: 'Build & Test'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2 # checkout the repo
- run: npm ci # install packages
- run: npm test # run tests (configured to use jest-junit reporter)
- name: 'Test Report'
uses: dorny/test-reporter@v1
if: always() # run this step even if previous step failed
with:
name: 'JEST Tests' # Name of the check run which will be created
path: '__reports__/jest-*.xml' # Path to test report
reporter: 'jest-junit' # Format of test report
```
## Usage
```yaml
- uses: dorny/test-reporter@v1
with:
# Name of the Check Run which will be created
name: ''
# Path to test report
# Supports wildcards via [fast-glob](https://github.com/mrmlnc/fast-glob)
# Path may match multiple result files of same format
path: ''
# Format of test report. Supported options:
# dart-json
# dotnet-trx
# flutter-machine
# jest-junit
reporter: ''
# Enables code annotations with error message and stack trace
annotations: 'true'
# Set action as failed if test report contain any failed test
fail-on-error: 'true'
# Relative path under $GITHUB_WORKSPACE where the repository was checked out.
working-directory: ''
# Personal access token used to interact with Github API
# Default: ${{ github.token }}
token: ''
```
## Supported formats
<details>
<summary>dart-json</summary>
Test run must be configured to use [JSON](https://github.com/dart-lang/test/blob/master/pkgs/test/doc/configuration.md#reporter) reporter.
You can configure it in `dart_test.yaml`:
```yml
file_reporters:
json: reports/test-results.json
```
Or with CLI arguments:
[`dart test --file-reporter="json:test-results.json"`](https://pub.dev/packages/test)
For more information see:
- [test package](https://pub.dev/packages/test)
- [test configuration](https://github.com/dart-lang/test/blob/master/pkgs/test/doc/configuration.md)
</details>
<details>
<summary>dotnet-trx</summary>
Test execution must be configured to produce *Visual Studio Test Results* files (TRX).
To get test results in TRX format you can execute your tests with CLI arguments:
`dotnet test --logger "trx;LogFileName=test-results.trx"`
Or you can configure TRX test output in `*.csproj` or `Directory.Build.props`:
```xml
<PropertyGroup>
<VSTestLogger>trx%3bLogFileName=$(MSBuildProjectName).trx</VSTestLogger>
<VSTestResultsDirectory>$(MSBuildThisFileDirectory)/reports</VSTestResultsDirectory>
</PropertyGroup>
```
Supported testing frameworks:
- [xUnit](https://xunit.net/)
- [NUnit](https://nunit.org/)
- [MSTest](https://github.com/Microsoft/testfx-docs)
For more information see [dotnet test](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test#examples)
</details>
<details>
<summary>flutter-machine</summary>
Test run must be configured to use [JSON](https://github.com/dart-lang/test/blob/master/pkgs/test/doc/configuration.md#reporter) reporter.
You can configure it in `dart_test.yaml`:
```yml
file_reporters:
json: reports/test-results.json
```
Or with (undocumented) CLI argument:
`flutter test --machine > test-results.json`
According to documentation `dart_test.yaml` should be at the root of the package, next to the package's pubspec.
It works in dart projects but the file is ignored by flutter. With flutter it works when `dart_test.yaml` is placed inside your `test` folder.
For more information see:
- [test package](https://pub.dev/packages/test)
- [test configuration](https://github.com/dart-lang/test/blob/master/pkgs/test/doc/configuration.md)
- [flutter-cli](https://flutter.dev/docs/reference/flutter-cli)
- [unit testing introduction](https://flutter.dev/docs/cookbook/testing/unit/introduction)
</details>
<details>
<summary>jest-junit</summary>
[JEST](https://jestjs.io/) testing framework support requires usage of [jest-junit](https://github.com/jest-community/jest-junit) reporter.
It will create test results in junit XML format which can be then processed by this action.
You can use following example configuration in `package.json`:
```json
"scripts": {
"test": "jest --ci --reporters=default --reporters=jest-junit"
},
"devDependencies": {
"jest": "^26.5.3",
"jest-junit": "^12.0.0"
},
"jest-junit": {
"outputDirectory": "__reports__",
"outputName": "jest-junit.xml",
"ancestorSeparator": " ",
"uniqueOutputName": "false",
"suiteNameTemplate": "{filepath}",
"classNameTemplate": "{classname}",
"titleTemplate": "{title}"
}
```
Configuration of `uniqueOutputName`, `suiteNameTemplate`, `classNameTemplate`, `titleTemplate` is important for proper visualization of test results.
</details>
## License
The scripts and documentation in this project are released under the [MIT License](https://github.com/dorny/test-reporter/blob/master/LICENSE)

View file

@ -1,26 +1,22 @@
name: 'Test Check Reporter' name: Test Reporter
description: | description: |
Presents test results from popular testing frameworks as Github check run. Displays test results from popular testing frameworks directly in GitHub.
Supports: Supports .NET (xUnit, NUnit, MSTest), Dart, Flutter and JavaScript (JEST).
- dotnet (trx logger) author: Michal Dorner <dorner.michal@gmail.com>
- flutter (JSON output with '--machine' flag )
- jest (jest-junit reporter)
author: 'Michal Dorner <dorner.michal@gmail.com>'
inputs: inputs:
annotations: annotations:
description: 'Annotate code where exceptions in tests were thrown' description: Enables code annotations with error message and stack trace captured during test execution
required: true required: true
default: 'true' default: 'true'
fail-on-error: fail-on-error:
description: 'Set this action as failed if test report contains any failed test' description: Set this action as failed if test report contain any failed test
required: true required: true
default: 'true' default: 'true'
name: name:
description: 'Name of the check run' description: Name of the check run
required: true required: true
path: path:
description: 'Path to test report' description: Path to test report
required: true required: true
reporter: reporter:
description: | description: |
@ -31,11 +27,11 @@ inputs:
- jest-junit - jest-junit
required: true required: true
token: token:
description: 'GitHub Access Token' description: GitHub Access Token
required: false required: false
default: ${{ github.token }} default: ${{ github.token }}
working-directory: working-directory:
description: 'Relative path under $GITHUB_WORKSPACE where the repository was checked out.' description: Relative path under $GITHUB_WORKSPACE where the repository was checked out
required: false required: false
outputs: outputs:
conclusion: conclusion:

95
dist/index.js generated vendored
View file

@ -3536,6 +3536,7 @@ function copyFile(srcFile, destFile, force) {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
const fs = __nccwpck_require__(5747); const fs = __nccwpck_require__(5747);
exports.FILE_SYSTEM_ADAPTER = { exports.FILE_SYSTEM_ADAPTER = {
lstat: fs.lstat, lstat: fs.lstat,
@ -3562,6 +3563,7 @@ exports.createFileSystemAdapter = createFileSystemAdapter;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = void 0;
const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.');
const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10);
const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10);
@ -3583,6 +3585,7 @@ exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_B
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Settings = exports.scandirSync = exports.scandir = void 0;
const async = __nccwpck_require__(4507); const async = __nccwpck_require__(4507);
const sync = __nccwpck_require__(9560); const sync = __nccwpck_require__(9560);
const settings_1 = __nccwpck_require__(8662); const settings_1 = __nccwpck_require__(8662);
@ -3615,10 +3618,12 @@ function getSettings(settingsOrOptions = {}) {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.readdir = exports.readdirWithFileTypes = exports.read = void 0;
const fsStat = __nccwpck_require__(109); const fsStat = __nccwpck_require__(109);
const rpl = __nccwpck_require__(5288); const rpl = __nccwpck_require__(5288);
const constants_1 = __nccwpck_require__(8838); const constants_1 = __nccwpck_require__(8838);
const utils = __nccwpck_require__(6297); const utils = __nccwpck_require__(6297);
const common = __nccwpck_require__(3847);
function read(directory, settings, callback) { function read(directory, settings, callback) {
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
return readdirWithFileTypes(directory, settings, callback); return readdirWithFileTypes(directory, settings, callback);
@ -3634,7 +3639,7 @@ function readdirWithFileTypes(directory, settings, callback) {
const entries = dirents.map((dirent) => ({ const entries = dirents.map((dirent) => ({
dirent, dirent,
name: dirent.name, name: dirent.name,
path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator)
})); }));
if (!settings.followSymbolicLinks) { if (!settings.followSymbolicLinks) {
return callSuccessCallback(callback, entries); return callSuccessCallback(callback, entries);
@ -3671,7 +3676,7 @@ function readdir(directory, settings, callback) {
if (readdirError !== null) { if (readdirError !== null) {
return callFailureCallback(callback, readdirError); return callFailureCallback(callback, readdirError);
} }
const filepaths = names.map((name) => `${directory}${settings.pathSegmentSeparator}${name}`); const filepaths = names.map((name) => common.joinPathSegments(directory, name, settings.pathSegmentSeparator));
const tasks = filepaths.map((filepath) => { const tasks = filepaths.map((filepath) => {
return (done) => fsStat.stat(filepath, settings.fsStatSettings, done); return (done) => fsStat.stat(filepath, settings.fsStatSettings, done);
}); });
@ -3705,6 +3710,27 @@ function callSuccessCallback(callback, result) {
} }
/***/ }),
/***/ 3847:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.joinPathSegments = void 0;
function joinPathSegments(a, b, separator) {
/**
* The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`).
*/
if (a.endsWith(separator)) {
return a + b;
}
return a + separator + b;
}
exports.joinPathSegments = joinPathSegments;
/***/ }), /***/ }),
/***/ 9560: /***/ 9560:
@ -3713,9 +3739,11 @@ function callSuccessCallback(callback, result) {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.readdir = exports.readdirWithFileTypes = exports.read = void 0;
const fsStat = __nccwpck_require__(109); const fsStat = __nccwpck_require__(109);
const constants_1 = __nccwpck_require__(8838); const constants_1 = __nccwpck_require__(8838);
const utils = __nccwpck_require__(6297); const utils = __nccwpck_require__(6297);
const common = __nccwpck_require__(3847);
function read(directory, settings) { function read(directory, settings) {
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
return readdirWithFileTypes(directory, settings); return readdirWithFileTypes(directory, settings);
@ -3729,7 +3757,7 @@ function readdirWithFileTypes(directory, settings) {
const entry = { const entry = {
dirent, dirent,
name: dirent.name, name: dirent.name,
path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator)
}; };
if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) {
try { try {
@ -3749,7 +3777,7 @@ exports.readdirWithFileTypes = readdirWithFileTypes;
function readdir(directory, settings) { function readdir(directory, settings) {
const names = settings.fs.readdirSync(directory); const names = settings.fs.readdirSync(directory);
return names.map((name) => { return names.map((name) => {
const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`; const entryPath = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
const stats = fsStat.statSync(entryPath, settings.fsStatSettings); const stats = fsStat.statSync(entryPath, settings.fsStatSettings);
const entry = { const entry = {
name, name,
@ -3791,7 +3819,7 @@ class Settings {
}); });
} }
_getValue(option, value) { _getValue(option, value) {
return option === undefined ? value : option; return option !== null && option !== void 0 ? option : value;
} }
} }
exports.default = Settings; exports.default = Settings;
@ -3805,6 +3833,7 @@ exports.default = Settings;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createDirentFromStats = void 0;
class DirentFromStats { class DirentFromStats {
constructor(name, stats) { constructor(name, stats) {
this.name = name; this.name = name;
@ -3831,6 +3860,7 @@ exports.createDirentFromStats = createDirentFromStats;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.fs = void 0;
const fs = __nccwpck_require__(883); const fs = __nccwpck_require__(883);
exports.fs = fs; exports.fs = fs;
@ -3843,6 +3873,7 @@ exports.fs = fs;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
const fs = __nccwpck_require__(5747); const fs = __nccwpck_require__(5747);
exports.FILE_SYSTEM_ADAPTER = { exports.FILE_SYSTEM_ADAPTER = {
lstat: fs.lstat, lstat: fs.lstat,
@ -3867,6 +3898,7 @@ exports.createFileSystemAdapter = createFileSystemAdapter;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.statSync = exports.stat = exports.Settings = void 0;
const async = __nccwpck_require__(4147); const async = __nccwpck_require__(4147);
const sync = __nccwpck_require__(4527); const sync = __nccwpck_require__(4527);
const settings_1 = __nccwpck_require__(2410); const settings_1 = __nccwpck_require__(2410);
@ -3899,6 +3931,7 @@ function getSettings(settingsOrOptions = {}) {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.read = void 0;
function read(path, settings, callback) { function read(path, settings, callback) {
settings.fs.lstat(path, (lstatError, lstat) => { settings.fs.lstat(path, (lstatError, lstat) => {
if (lstatError !== null) { if (lstatError !== null) {
@ -3938,6 +3971,7 @@ function callSuccessCallback(callback, result) {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.read = void 0;
function read(path, settings) { function read(path, settings) {
const lstat = settings.fs.lstatSync(path); const lstat = settings.fs.lstatSync(path);
if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
@ -3978,7 +4012,7 @@ class Settings {
this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
} }
_getValue(option, value) { _getValue(option, value) {
return option === undefined ? value : option; return option !== null && option !== void 0 ? option : value;
} }
} }
exports.default = Settings; exports.default = Settings;
@ -3992,6 +4026,7 @@ exports.default = Settings;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Settings = exports.walkStream = exports.walkSync = exports.walk = void 0;
const async_1 = __nccwpck_require__(7523); const async_1 = __nccwpck_require__(7523);
const stream_1 = __nccwpck_require__(6737); const stream_1 = __nccwpck_require__(6737);
const sync_1 = __nccwpck_require__(3068); const sync_1 = __nccwpck_require__(3068);
@ -4080,7 +4115,11 @@ class StreamProvider {
this._stream = new stream_1.Readable({ this._stream = new stream_1.Readable({
objectMode: true, objectMode: true,
read: () => { }, read: () => { },
destroy: this._reader.destroy.bind(this._reader) destroy: () => {
if (!this._reader.isDestroyed) {
this._reader.destroy();
}
}
}); });
} }
read() { read() {
@ -4158,6 +4197,9 @@ class AsyncReader extends reader_1.default {
}); });
return this._emitter; return this._emitter;
} }
get isDestroyed() {
return this._isDestroyed;
}
destroy() { destroy() {
if (this._isDestroyed) { if (this._isDestroyed) {
throw new Error('The reader is already destroyed'); throw new Error('The reader is already destroyed');
@ -4194,7 +4236,7 @@ class AsyncReader extends reader_1.default {
}); });
} }
_handleError(error) { _handleError(error) {
if (!common.isFatalError(this._settings, error)) { if (this._isDestroyed || !common.isFatalError(this._settings, error)) {
return; return;
} }
this._isFatalError = true; this._isFatalError = true;
@ -4231,6 +4273,7 @@ exports.default = AsyncReader;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.joinPathSegments = exports.replacePathSegmentSeparator = exports.isAppliedFilter = exports.isFatalError = void 0;
function isFatalError(settings, error) { function isFatalError(settings, error) {
if (settings.errorFilter === null) { if (settings.errorFilter === null) {
return true; return true;
@ -4243,13 +4286,19 @@ function isAppliedFilter(filter, value) {
} }
exports.isAppliedFilter = isAppliedFilter; exports.isAppliedFilter = isAppliedFilter;
function replacePathSegmentSeparator(filepath, separator) { function replacePathSegmentSeparator(filepath, separator) {
return filepath.split(/[\\/]/).join(separator); return filepath.split(/[/\\]/).join(separator);
} }
exports.replacePathSegmentSeparator = replacePathSegmentSeparator; exports.replacePathSegmentSeparator = replacePathSegmentSeparator;
function joinPathSegments(a, b, separator) { function joinPathSegments(a, b, separator) {
if (a === '') { if (a === '') {
return b; return b;
} }
/**
* The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`).
*/
if (a.endsWith(separator)) {
return a + b;
}
return a + separator + b; return a + separator + b;
} }
exports.joinPathSegments = joinPathSegments; exports.joinPathSegments = joinPathSegments;
@ -4369,7 +4418,7 @@ class Settings {
}); });
} }
_getValue(option, value) { _getValue(option, value) {
return option === undefined ? value : option; return option !== null && option !== void 0 ? option : value;
} }
} }
exports.default = Settings; exports.default = Settings;
@ -9700,7 +9749,11 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0; exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
const fs = __nccwpck_require__(5747); const fs = __nccwpck_require__(5747);
const os = __nccwpck_require__(2087); const os = __nccwpck_require__(2087);
const CPU_COUNT = os.cpus().length; /**
* The `os.cpus` method can return zero. We expect the number of cores to be greater than zero.
* https://github.com/nodejs/node/blob/7faeddf23a98c53896f8b574a6e66589e8fb1eb8/lib/os.js#L106-L107
*/
const CPU_COUNT = Math.max(os.cpus().length, 1);
exports.DEFAULT_FILE_SYSTEM_ADAPTER = { exports.DEFAULT_FILE_SYSTEM_ADAPTER = {
lstat: fs.lstat, lstat: fs.lstat,
lstatSync: fs.lstatSync, lstatSync: fs.lstatSync,
@ -10089,10 +10142,15 @@ function fastqueue (context, worker, concurrency) {
context = null context = null
} }
if (concurrency < 1) {
throw new Error('fastqueue concurrency must be greater than 1')
}
var cache = reusify(Task) var cache = reusify(Task)
var queueHead = null var queueHead = null
var queueTail = null var queueTail = null
var _running = 0 var _running = 0
var errorHandler = null
var self = { var self = {
push: push, push: push,
@ -10109,7 +10167,8 @@ function fastqueue (context, worker, concurrency) {
unshift: unshift, unshift: unshift,
empty: noop, empty: noop,
kill: kill, kill: kill,
killAndDrain: killAndDrain killAndDrain: killAndDrain,
error: error
} }
return self return self
@ -10166,6 +10225,7 @@ function fastqueue (context, worker, concurrency) {
current.release = release current.release = release
current.value = value current.value = value
current.callback = done || noop current.callback = done || noop
current.errorHandler = errorHandler
if (_running === self.concurrency || self.paused) { if (_running === self.concurrency || self.paused) {
if (queueTail) { if (queueTail) {
@ -10241,6 +10301,10 @@ function fastqueue (context, worker, concurrency) {
self.drain() self.drain()
self.drain = noop self.drain = noop
} }
function error (handler) {
errorHandler = handler
}
} }
function noop () {} function noop () {}
@ -10251,13 +10315,19 @@ function Task () {
this.next = null this.next = null
this.release = noop this.release = noop
this.context = null this.context = null
this.errorHandler = null
var self = this var self = this
this.worked = function worked (err, result) { this.worked = function worked (err, result) {
var callback = self.callback var callback = self.callback
var errorHandler = self.errorHandler
var val = self.value
self.value = null self.value = null
self.callback = noop self.callback = noop
if (self.errorHandler) {
errorHandler(err, val)
}
callback.call(self.context, err, result) callback.call(self.context, err, result)
self.release(self) self.release(self)
} }
@ -14395,6 +14465,7 @@ module.exports = reusify
/***/ 5288: /***/ 5288:
/***/ ((module) => { /***/ ((module) => {
/*! run-parallel. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
module.exports = runParallel module.exports = runParallel
function runParallel (tasks, cb) { function runParallel (tasks, cb) {

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

67
package-lock.json generated
View file

@ -1814,28 +1814,25 @@
} }
}, },
"@nodelib/fs.scandir": { "@nodelib/fs.scandir": {
"version": "2.1.3", "version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
"dev": true,
"requires": { "requires": {
"@nodelib/fs.stat": "2.0.3", "@nodelib/fs.stat": "2.0.4",
"run-parallel": "^1.1.9" "run-parallel": "^1.1.9"
} }
}, },
"@nodelib/fs.stat": { "@nodelib/fs.stat": {
"version": "2.0.3", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q=="
"dev": true
}, },
"@nodelib/fs.walk": { "@nodelib/fs.walk": {
"version": "1.2.4", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
"dev": true,
"requires": { "requires": {
"@nodelib/fs.scandir": "2.1.3", "@nodelib/fs.scandir": "2.1.4",
"fastq": "^1.6.0" "fastq": "^1.6.0"
} }
}, },
@ -4417,10 +4414,9 @@
"dev": true "dev": true
}, },
"fast-glob": { "fast-glob": {
"version": "3.2.4", "version": "3.2.5",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
"integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
"dev": true,
"requires": { "requires": {
"@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3", "@nodelib/fs.walk": "^1.2.3",
@ -4434,7 +4430,6 @@
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": { "requires": {
"fill-range": "^7.0.1" "fill-range": "^7.0.1"
} }
@ -4443,7 +4438,6 @@
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": { "requires": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
} }
@ -4451,14 +4445,12 @@
"is-number": { "is-number": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
"dev": true
}, },
"micromatch": { "micromatch": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
"dev": true,
"requires": { "requires": {
"braces": "^3.0.1", "braces": "^3.0.1",
"picomatch": "^2.0.5" "picomatch": "^2.0.5"
@ -4468,7 +4460,6 @@
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": { "requires": {
"is-number": "^7.0.0" "is-number": "^7.0.0"
} }
@ -4488,10 +4479,9 @@
"dev": true "dev": true
}, },
"fastq": { "fastq": {
"version": "1.8.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz",
"integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==",
"dev": true,
"requires": { "requires": {
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
@ -4696,7 +4686,6 @@
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"dev": true,
"requires": { "requires": {
"is-glob": "^4.0.1" "is-glob": "^4.0.1"
} }
@ -5101,8 +5090,7 @@
"is-extglob": { "is-extglob": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
"dev": true
}, },
"is-generator-fn": { "is-generator-fn": {
"version": "2.1.0", "version": "2.1.0",
@ -5114,7 +5102,6 @@
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": { "requires": {
"is-extglob": "^2.1.1" "is-extglob": "^2.1.1"
} }
@ -8813,8 +8800,7 @@
"merge2": { "merge2": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
"dev": true
}, },
"micromatch": { "micromatch": {
"version": "3.1.10", "version": "3.1.10",
@ -9308,8 +9294,7 @@
"picomatch": { "picomatch": {
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
"dev": true
}, },
"pify": { "pify": {
"version": "2.3.0", "version": "2.3.0",
@ -9708,8 +9693,7 @@
"reusify": { "reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
"dev": true
}, },
"rimraf": { "rimraf": {
"version": "3.0.2", "version": "3.0.2",
@ -9727,10 +9711,9 @@
"dev": true "dev": true
}, },
"run-parallel": { "run-parallel": {
"version": "1.1.9", "version": "1.1.10",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz",
"integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw=="
"dev": true
}, },
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",

View file

@ -32,6 +32,7 @@
"@actions/core": "^1.2.6", "@actions/core": "^1.2.6",
"@actions/exec": "^1.0.4", "@actions/exec": "^1.0.4",
"@actions/github": "^4.0.0", "@actions/github": "^4.0.0",
"fast-glob": "^3.2.5",
"xml2js": "^0.4.23" "xml2js": "^0.4.23"
}, },
"devDependencies": { "devDependencies": {