99 Commits

Author SHA1 Message Date
dependabot[bot]
58ae73b360 Bump typescript from 4.5.2 to 4.6.3 (#189)
Some checks failed
Test / check_pr (push) Has been cancelled
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.5.2 to 4.6.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.5.2...v4.6.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-31 17:12:44 -04:00
Nick Cipollo
ffcd2d4c10 Fixes #185 Add omitDraftDuringUpdate input (#190) 2022-03-31 17:07:42 -04:00
Nick Cipollo
c309084e8b tweak repo spelling 2022-03-31 11:11:59 -04:00
Nick Cipollo
819589c886 Update readme inputs table. 2022-03-31 11:11:18 -04:00
Nick Cipollo
6297172c9f Generate JS from typescript 2022-03-31 10:58:25 -04:00
Eder Matos
918a7af1fe Update README.md (#188) 2022-03-31 10:56:55 -04:00
dependabot[bot]
6ba4f20c9a Bump typescript from 4.5.2 to 4.6.2 (#177)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.5.2 to 4.6.2.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.5.2...v4.6.2)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-31 10:44:37 -04:00
dependabot[bot]
97a630fc75 Bump minimist from 1.2.5 to 1.2.6 (#187)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-31 10:43:26 -04:00
dependabot[bot]
3f844db37a Bump jest-circus from 27.4.5 to 27.5.1 (#179)
Bumps [jest-circus](https://github.com/facebook/jest/tree/HEAD/packages/jest-circus) from 27.4.5 to 27.5.1.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v27.5.1/packages/jest-circus)

---
updated-dependencies:
- dependency-name: jest-circus
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-11 10:28:52 -05:00
dependabot[bot]
9e1799683e Bump node-fetch from 2.6.1 to 2.6.7 (#183)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-11 10:28:42 -05:00
dependabot[bot]
6553b535a3 Bump @types/node from 17.0.7 to 17.0.21 (#178)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 17.0.7 to 17.0.21.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-07 09:07:05 -05:00
dependabot[bot]
132ba9b615 Bump jest from 27.4.5 to 27.5.1 (#176)
Bumps [jest](https://github.com/facebook/jest) from 27.4.5 to 27.5.1.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v27.4.5...v27.5.1)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-07 09:06:09 -05:00
dependabot[bot]
99014f6c59 Bump ts-jest from 27.1.2 to 27.1.3 (#169)
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 27.1.2 to 27.1.3.
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/kulshekhar/ts-jest/compare/v27.1.2...v27.1.3)

---
updated-dependencies:
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-07 09:05:59 -05:00
dependabot[bot]
e663819a51 Bump actions/checkout from 2.4.0 to 3 (#180)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.4.0 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.4.0...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-07 09:05:45 -05:00
dependabot[bot]
69242acd76 Bump jest from 27.4.2 to 27.4.5 (#160)
Bumps [jest](https://github.com/facebook/jest) from 27.4.2 to 27.4.5.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v27.4.2...v27.4.5)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 20:05:38 -05:00
dependabot[bot]
09a8e66990 Bump jest-circus from 27.4.2 to 27.4.5 (#161)
Bumps [jest-circus](https://github.com/facebook/jest/tree/HEAD/packages/jest-circus) from 27.4.2 to 27.4.5.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v27.4.5/packages/jest-circus)

---
updated-dependencies:
- dependency-name: jest-circus
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 20:02:16 -05:00
dependabot[bot]
6f8234ce3e Bump @types/node from 16.11.12 to 17.0.7 (#165)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.11.12 to 17.0.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 19:58:04 -05:00
dependabot[bot]
8131ae1c5d Bump ts-jest from 27.0.7 to 27.1.2 (#159)
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 27.0.7 to 27.1.2.
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/kulshekhar/ts-jest/compare/v27.0.7...v27.1.2)

---
updated-dependencies:
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 19:57:40 -05:00
dependabot[bot]
2c158d72a4 Bump @types/jest from 27.0.3 to 27.4.0 (#162)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 27.0.3 to 27.4.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 19:55:19 -05:00
Anton Larionov
404de39364 Update README example with permissions block (#164)
Documentation:
- https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/
- https://docs.github.com/en/actions/security-guides/automatic-token-authentication
2022-01-03 19:55:03 -05:00
dependabot[bot]
b9600947f7 Bump @types/node from 16.11.6 to 16.11.12 (#156)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.11.6 to 16.11.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-08 08:35:35 -05:00
dependabot[bot]
e31291f6a4 Bump jest-circus from 27.3.1 to 27.4.2 (#155)
Bumps [jest-circus](https://github.com/facebook/jest/tree/HEAD/packages/jest-circus) from 27.3.1 to 27.4.2.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v27.4.2/packages/jest-circus)

---
updated-dependencies:
- dependency-name: jest-circus
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-08 08:35:25 -05:00
dependabot[bot]
e5cc18bd59 Bump @types/jest from 27.0.2 to 27.0.3 (#154)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 27.0.2 to 27.0.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-08 08:13:48 -05:00
dependabot[bot]
6cddb7ed31 Bump typescript from 4.4.4 to 4.5.2 (#153)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.4.4 to 4.5.2.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.4.4...v4.5.2)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-08 08:13:36 -05:00
dependabot[bot]
8d640a794c Bump jest from 27.3.1 to 27.4.2 (#151)
Bumps [jest](https://github.com/facebook/jest) from 27.3.1 to 27.4.2.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v27.3.1...v27.4.2)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-08 08:10:56 -05:00
Nick Cipollo
268f2377f2 Fix test which is failing when pushing a tag 2021-11-26 17:26:50 -05:00
Nick Cipollo
40bb172bd0 Fixes #135 Add support for generate_release_notes
Some checks failed
Test / check_pr (push) Has been cancelled
2021-11-26 16:55:04 -05:00
Nick Cipollo
66aaa1eb00 Setup to use ncc 2021-11-26 14:48:25 -05:00
dependabot[bot]
8aada7312c Bump actions/checkout from 2.3.5 to 2.4.0 (#146)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.5 to 2.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.5...v2.4.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-08 08:44:34 -05:00
dependabot[bot]
ec76ac98f7 Bump typescript from 4.4.3 to 4.4.4 (#145)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.4.3 to 4.4.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.4.3...v4.4.4)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-08 08:44:23 -05:00
dependabot[bot]
e709279ee8 Bump @types/node from 16.10.2 to 16.11.6 (#138)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.10.2 to 16.11.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-08 08:43:37 -05:00
dependabot[bot]
b7a6e45e99 Bump jest-circus from 27.2.4 to 27.3.1 (#137)
Bumps [jest-circus](https://github.com/facebook/jest/tree/HEAD/packages/jest-circus) from 27.2.4 to 27.3.1.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v27.3.1/packages/jest-circus)

---
updated-dependencies:
- dependency-name: jest-circus
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-08 08:43:25 -05:00
dependabot[bot]
986121c24a Bump jest from 27.2.4 to 27.3.1 (#139)
Bumps [jest](https://github.com/facebook/jest) from 27.2.4 to 27.3.1.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v27.2.4...v27.3.1)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-02 08:03:28 -04:00
dependabot[bot]
2be34cfeec Bump @types/glob from 7.1.4 to 7.2.0 (#140)
Bumps [@types/glob](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/glob) from 7.1.4 to 7.2.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/glob)

---
updated-dependencies:
- dependency-name: "@types/glob"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-02 08:03:18 -04:00
dependabot[bot]
592ac51c49 Bump ts-jest from 27.0.5 to 27.0.7 (#141)
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 27.0.5 to 27.0.7.
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/kulshekhar/ts-jest/compare/v27.0.5...v27.0.7)

---
updated-dependencies:
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-01 11:46:25 -04:00
Nick Cipollo
01e1051edf Fixes #136 Globber now also supports new line as separator. 2021-10-25 08:03:03 -04:00
dependabot[bot]
15ede536e2 Bump actions/checkout from 2.3.4 to 2.3.5 (#132)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.3.5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.3.5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-21 07:48:09 -04:00
Nick Cipollo
3e88dac4cf Update build artifacts 2021-10-03 18:47:56 -04:00
Nick Cipollo
95aae1ba96 Fixes #120 Artifacts can be removed even when new ones aren't provided 2021-10-03 18:46:12 -04:00
Nick Cipollo
821cbcc349 Bump typescript, fix build errors around catch blocks. 2021-10-03 17:21:27 -04:00
dependabot[bot]
4531373c80 Bump typescript from 4.3.5 to 4.4.3 (#125)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.3.5 to 4.4.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.3.5...v4.4.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-03 17:12:40 -04:00
dependabot[bot]
be8fb09624 Bump @types/node from 16.7.11 to 16.10.2 (#126)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.7.11 to 16.10.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-03 16:46:16 -04:00
dependabot[bot]
0d72fe9393 Bump jest-circus from 27.1.0 to 27.2.4 (#124)
Bumps [jest-circus](https://github.com/facebook/jest/tree/HEAD/packages/jest-circus) from 27.1.0 to 27.2.4.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v27.2.4/packages/jest-circus)

---
updated-dependencies:
- dependency-name: jest-circus
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-03 16:46:05 -04:00
dependabot[bot]
045b513398 Bump glob from 7.1.7 to 7.2.0 (#123)
Bumps [glob](https://github.com/isaacs/node-glob) from 7.1.7 to 7.2.0.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/master/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v7.1.7...v7.2.0)

---
updated-dependencies:
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-03 16:45:54 -04:00
dependabot[bot]
b57e76011b Bump @actions/core from 1.5.0 to 1.6.0 (#122)
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-03 16:45:43 -04:00
Nick Cipollo
62f9f43ceb Bump jest 2021-09-30 22:54:12 -04:00
dependabot[bot]
61fe7e2b7b Bump ansi-regex from 5.0.0 to 5.0.1 (#121)
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-28 09:39:04 -04:00
dependabot[bot]
b37dba0653 Bump tmpl from 1.0.4 to 1.0.5 (#119)
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-28 09:37:51 -04:00
Nick Cipollo
cba6a1b4f8 Update readme to provide examples for owner and repo. 2021-09-12 19:03:06 -04:00
Nick Cipollo
e97ceb3e08 Fixes #69 Indicate the scope required for personal access tokens. 2021-09-12 18:06:38 -04:00
dependabot[bot]
c18d31567a Bump jest-circus from 27.0.6 to 27.1.0 (#114)
Bumps [jest-circus](https://github.com/facebook/jest/tree/HEAD/packages/jest-circus) from 27.0.6 to 27.1.0.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v27.1.0/packages/jest-circus)

---
updated-dependencies:
- dependency-name: jest-circus
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-12 17:43:35 -04:00
dependabot[bot]
91233e9c66 Bump @types/node from 16.4.12 to 16.7.11 (#116)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.4.12 to 16.7.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-12 17:43:27 -04:00
dependabot[bot]
a4548f83be Bump @actions/core from 1.4.0 to 1.5.0 (#113)
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-06 21:32:23 -04:00
dependabot[bot]
2162d1bc14 Bump @types/jest from 26.0.24 to 27.0.1 (#112)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.24 to 27.0.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-06 21:32:10 -04:00
Rosalie
f597c8ad62 Add removeArtifacts (#109) 2021-09-06 18:57:37 -04:00
dependabot[bot]
a4f828a4e5 Bump path-parse from 1.0.6 to 1.0.7 (#105)
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-11 10:48:06 -04:00
anatawa12
4fd91f8b23 set default value for token action input (#104) 2021-08-06 14:39:07 -04:00
dependabot[bot]
b60bd83d11 Bump @types/node from 16.4.10 to 16.4.12 (#102)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.4.10 to 16.4.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-05 14:12:54 -04:00
Nick Cipollo
8f144e5a49 Reduce dependbot frequency 2021-08-05 14:12:13 -04:00
dependabot[bot]
e05d100273 Bump @types/node from 16.4.1 to 16.4.10 (#100)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.4.1 to 16.4.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-03 10:55:44 -04:00
Jashandeep Sohi
7461bfe839 Add option to ignore prerelease on update (#96) 2021-08-01 15:41:55 -04:00
dependabot[bot]
dee715a153 Bump @types/node from 16.0.0 to 16.4.1
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.0.0 to 16.4.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-23 12:27:07 -04:00
Function
b102518a6c Update README.md
Mark artifact property as deprecated as per current action output.
2021-07-07 16:24:44 -04:00
dependabot[bot]
508dab8aab Bump @types/jest from 26.0.23 to 26.0.24
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.23 to 26.0.24.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-07 14:53:17 -04:00
dependabot[bot]
39a94f584a Bump @types/glob from 7.1.3 to 7.1.4
Bumps [@types/glob](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/glob) from 7.1.3 to 7.1.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/glob)

---
updated-dependencies:
- dependency-name: "@types/glob"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-07 14:50:09 -04:00
dependabot[bot]
6b6b0348be Bump @types/node from 15.14.0 to 16.0.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 15.14.0 to 16.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-07 14:49:49 -04:00
dependabot[bot]
441e966601 Bump @types/node from 15.12.5 to 15.14.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 15.12.5 to 15.14.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-02 18:04:04 -04:00
dependabot[bot]
92352a1956 Bump jest-circus from 26.6.3 to 27.0.6
Bumps [jest-circus](https://github.com/facebook/jest/tree/HEAD/packages/jest-circus) from 26.6.3 to 27.0.6.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v27.0.6/packages/jest-circus)

---
updated-dependencies:
- dependency-name: jest-circus
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-01 08:40:15 -04:00
dependabot[bot]
ea4c59cdea Bump @types/node from 14.14.25 to 15.12.5
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.25 to 15.12.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-01 08:39:18 -04:00
dependabot[bot]
f1984b06a2 Bump typescript from 4.3.4 to 4.3.5
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.3.4 to 4.3.5.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.3.4...v4.3.5)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-01 08:38:45 -04:00
Nick Cipollo
92158b2aee Disable integration test. 2021-06-30 16:36:19 -04:00
Nick Cipollo
289da33bfb Bump github types to 5.0.0 2021-06-30 16:34:09 -04:00
dependabot[bot]
793ce4c6b0 Bump glob from 7.1.6 to 7.1.7
Bumps [glob](https://github.com/isaacs/node-glob) from 7.1.6 to 7.1.7.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/master/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v7.1.6...v7.1.7)

---
updated-dependencies:
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-30 16:21:26 -04:00
dependabot[bot]
7bba931a39 Bump @actions/core from 1.2.6 to 1.4.0
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.2.6 to 1.4.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-30 16:21:15 -04:00
dependabot[bot]
6fb3846972 Bump typescript from 4.1.4 to 4.3.4
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.1.4 to 4.3.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.1.4...v4.3.4)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-30 16:21:04 -04:00
dependabot[bot]
f2bb959dcd Bump @types/jest from 26.0.20 to 26.0.23
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.20 to 26.0.23.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-30 16:20:48 -04:00
dependabot[bot]
73272faa39 Bump actions/checkout from 1 to 2.3.4
Bumps [actions/checkout](https://github.com/actions/checkout) from 1 to 2.3.4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v1...v2.3.4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-30 16:19:56 -04:00
HonkingGoose
403e4fc8af Dependabot configuration 2021-06-30 16:18:26 -04:00
HonkingGoose
971e60a37e Small improvements to README (#67)
* Small improvements to README

- Capitalize proper noun GitHub
- Use mono-spaced font for some defaults
- Use actions/checkout@v2 in example as that is the latest stable release
- Improve grammar of some sentences
2021-06-29 17:56:09 -04:00
dependabot[bot]
a5a057b707 Bump ws from 7.4.3 to 7.4.6
Bumps [ws](https://github.com/websockets/ws) from 7.4.3 to 7.4.6.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.3...7.4.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-29 13:35:57 -04:00
Nick Cipollo
d1125b4510 Fix typescript build 2021-05-24 11:23:05 -04:00
Nick Cipollo
15abc13cc4 Fixes #55 Add artifact validation which check to ensure it's not a directory 2021-05-24 11:21:34 -04:00
Nick Cipollo
616708020f Fixes #50 Add plugin outputs which contain release information. 2021-05-12 11:36:59 -04:00
dependabot[bot]
085dc21232 Bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 19:11:16 -04:00
Nick Cipollo
06fefc702f Bump jest 2021-05-10 19:10:49 -04:00
dependabot[bot]
a84d04e910 Bump lodash from 4.17.20 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 19:05:50 -04:00
ph1ll
ec90733eaa Use pagination for listing release assets 2021-04-15 13:15:38 -04:00
Nick Cipollo
839c2ee3df Skip integration test 2021-04-07 17:38:35 -04:00
Nick Cipollo
a43fb1aa82 Fixes #37 Add discussion category action argument. 2021-04-07 17:36:43 -04:00
Nick Cipollo
8f0b206fd3 Cleanup error classes and CI 2021-03-23 17:43:38 -04:00
Nick Cipollo
9b14e2e2d3 Respect artifactErrorsFailBuild in production builds 2021-03-21 20:00:17 -04:00
Nick Cipollo
af980963d6 Fixes #33 Add artifactErrorsFailBuild flag 2021-03-21 19:47:27 -04:00
Nick Cipollo
5b1448e480 Fixes #32 Globber will now expand tilde and warn if no results are found 2021-03-12 12:44:12 -05:00
Nick Cipollo
f7b694c6d5 Update issue templates 2021-03-08 17:02:36 -05:00
Pier-Luc Gendreau
e78d6f8d64 chore(deps): remove add and global 2021-02-26 14:01:41 -05:00
Nick Cipollo
c3a232b7b2 Fix release mode 2021-02-10 12:12:01 -05:00
Nick Cipollo
a9ffe7f597 Update release notes 2021-02-10 11:53:50 -05:00
Nick Cipollo
09eb035337 Fixes #26 Update dependencies and fix octokit types
Fixes #27 Add inputs for specifying owner and repo
2021-02-10 11:50:57 -05:00
Nick Cipollo
970fd8405b Bump jest 2020-12-22 13:30:22 -05:00
53 changed files with 17969 additions and 3129 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "monthly"

28
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: "PR Checks"
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
check_pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "yarn install"
run: yarn install
- name: "yarn build"
run: yarn build
- name: "check for uncommitted changes"
# Ensure no changes, but ignore node_modules dir since dev/fresh ci deps installed.
run: |
git diff --exit-code --stat -- . ':!node_modules' \
|| (echo "##[error] found changed files after build. please 'yarn build && npm run format'" \
"and check in all changes" \
&& exit 1)

View File

@@ -1,25 +0,0 @@
name: "PR Checks"
on: [pull_request, push]
jobs:
check_pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: "yarn install"
run: yarn install
- name: "yarn build"
run: yarn build
- name: "yarn test"
run: yarn test
- name: "check for uncommitted changes"
# Ensure no changes, but ignore node_modules dir since dev/fresh ci deps installed.
run: |
git diff --exit-code --stat -- . ':!node_modules' \
|| (echo "##[error] found changed files after build. please 'yarn build && npm run format'" \
"and check in all changes" \
&& exit 1)

14
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
name: "Test"
on: [push, pull_request]
jobs:
check_pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "yarn install"
run: yarn install
- name: "yarn test"
run: yarn test

3
.gitignore vendored
View File

@@ -93,3 +93,6 @@ fabric.properties
.idea/**/markdown-navigator/
# End of https://www.gitignore.io/api/webstorm
# Coverage
coverage

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@@ -1,28 +1,44 @@
# Release Action
This action will create a github release and optionally upload an artifact to it.
This action will create a GitHub release and optionally upload an artifact to it.
## Action Inputs
- **allowUpdates**: An optional flag which indicates if we should update a release if it already exists. Defaults to false.
- **artifact**: An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
- **artifacts**: An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
- **artifactContentType**: The content type of the artifact. Defaults to raw.
- **body**: An optional body for the release.
- **bodyFile**: An optional body file for the release. This should be the path to the file.
- **commit**: An optional commit reference. This will be used to create the tag if it does not exist.
- **draft**: Optionally marks this release as a draft release. Set to `true` to enable.
- **name**: An optional name for the release. If this is omitted the tag will be used.
- **omitBody**: Indicates if the release body should be omitted.
- **omitBodyDuringUpdate**: Indicates if the release body should be omitted during updates. The body will still be applied for newly created releases. This will preserve the existing body during updates.
- **omitName**: Indicates if the release name should be omitted.
- **omitNameDuringUpdate**: Indicates if the release name should be omitted during updates. The name will still be applied for newly created releases. This will preserve the existing name during updates.
- **prerelease**: Optionally marks this release as prerelease. Set to true to enable.
- **replacesArtifacts**: Indicates if existing release artifacts should be replaced. Defaults to true.
- **tag**: An optional tag for the release. If this is omitted the git ref will be used (if it is a tag).
- **token**: (**Required**) The Github token. Typically this will be `${{ secrets.GITHUB_TOKEN }}`.
| Input name | Description | Required | Default Value |
|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|----------------------|
| allowUpdates | An optional flag which indicates if we should update a release if it already exists. Defaults to false. | false | "" |
| artifactErrorsFailBuild | An optional flag which indicates if artifact read or upload errors should fail the build. | false | "" |
| artifacts | An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs) | false | "" |
| artifactContentType | The content type of the artifact. Defaults to raw | false | "" |
| body | An optional body for the release. | false | "" |
| bodyFile | An optional body file for the release. This should be the path to the file. | false | "" |
| commit | An optional commit reference. This will be used to create the tag if it does not exist. | false | "" |
| discussionCategory | When provided this will generate a discussion of the specified category. The category must exist otherwise this will cause the action to fail. This isn't used with draft releases | false | "" |
| draft | Optionally marks this release as a draft release. Set to true to enable. | false | "" |
| generateReleaseNotes | Indicates if release notes should be automatically generated. | false | false |
| name | An optional name for the release. If this is omitted the tag will be used. | false | "" |
| omitBody | Indicates if the release body should be omitted. | false | false |
| omitBodyDuringUpdate | Indicates if the release body should be omitted during updates. The body will still be applied for newly created releases. This will preserve the existing body during updates. | false | false |
| omitDraftDuringUpdate | Indicates if the draft flag should be omitted during updates. The draft flag will still be applied for newly created releases. This will preserve the existing draft state during updates. | false | false |
| omitName | Indicates if the release name should be omitted. | false | false |
| omitNameDuringUpdate | Indicates if the release name should be omitted during updates. The name will still be applied for newly created releases. This will preserve the existing name during updates. | false | false |
| omitPrereleaseDuringUpdate | Indicates if the prerelease flag should be omitted during updates. The prerelease flag will still be applied for newly created releases. This will preserve the existing prerelease state during updates. | false | false |
| owner | Optionally specify the owner of the repo where the release should be generated. Defaults to current repo'sowner. | false | "current repo owner" |
| prerelease | Optionally marks this release as prerelease. Set to true to enable. | false | "" |
| removeArtifacts | Indicates if existing release artifacts should be removed. | false | false |
| replacesArtifacts | Indicates if existing release artifacts should be replaced. | false | true |
| repo | Optionally specify the repo where the release should be generated. | false | current repo |
| tag | An optional tag for the release. If this is omitted the git ref will be used (if it is a tag). | false | "" |
| token | The GitHub token. This will default to the GitHub app token. This is primarily useful if you want to use your personal token (for targeting other repos, etc). If you are using a personal access token it should have access to the `repo` scope. | false | github.token |
## Action Outputs
| Output name | Description |
|-------------|-----------------------------------------------|
| id | The identifier of the created release. |
| html_url | The HTML URL of the release. |
| upload_url | The URL for uploading assets to the release. |
## Example
This example will create a release when tag is pushed:
This example will create a release when a tag is pushed:
```yml
name: Releases
@@ -36,8 +52,10 @@ jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: ncipollo/release-action@v1
with:
artifacts: "release.tar.gz,foo/*.txt"
@@ -47,5 +65,6 @@ jobs:
```
## Notes
- You must provide a tag either via the action input or the git ref (i.e push / create a tag). If you do not the action will fail.
- If the tag of the release you are creating does not exist yet, you should set both the `tag` and `commit` action inputs. `commit` can point to a commit hash or a branch name (ex - `main`).
- You must provide a tag either via the action input or the git ref (i.e push / create a tag). If you do not provide a tag the action will fail.
- If the tag of the release you are creating does not yet exist, you should set both the `tag` and `commit` action inputs. `commit` can point to a commit hash or a branch name (ex - `main`).
- In the example above only required permissions for the action specified (which is `contents: write`). If you add other actions to the same workflow you should expand `permissions` block accordingly.

View File

@@ -1,9 +1,12 @@
import { Action } from "../src/Action";
import { Artifact } from "../src/Artifact";
import { Inputs } from "../src/Inputs";
import { Releases } from "../src/Releases";
import { ArtifactUploader } from "../src/ArtifactUploader";
import {Action} from "../src/Action";
import {Artifact} from "../src/Artifact";
import {Inputs} from "../src/Inputs";
import {Releases} from "../src/Releases";
import {ArtifactUploader} from "../src/ArtifactUploader";
import {Outputs} from "../src/Outputs";
import {ArtifactDestroyer} from "../src/ArtifactDestroyer";
const applyReleaseDataMock = jest.fn()
const createMock = jest.fn()
const deleteMock = jest.fn()
const getMock = jest.fn()
@@ -11,6 +14,7 @@ const listArtifactsMock = jest.fn()
const listMock = jest.fn()
const updateMock = jest.fn()
const uploadMock = jest.fn()
const artifactDestroyMock = jest.fn()
const artifacts = [
new Artifact('a/art1'),
@@ -18,17 +22,21 @@ const artifacts = [
]
const createBody = 'createBody'
const createDraft = true
const createName = 'createName'
const commit = 'commit'
const draft = true
const discussionCategory = 'discussionCategory'
const generateReleaseNotes = true
const id = 100
const prerelease = true
const createPrerelease = true
const releaseId = 101
const replacesArtifacts = true
const tag = 'tag'
const token = 'token'
const updateBody = 'updateBody'
const updateDraft = false
const updateName = 'updateName'
const updatePrerelease = false
const url = 'http://api.example.com'
describe("Action", () => {
@@ -45,35 +53,62 @@ describe("Action", () => {
await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
expect(createMock).toBeCalledWith(tag,
createBody,
commit,
discussionCategory,
createDraft,
generateReleaseNotes,
createName,
createPrerelease)
expect(uploadMock).not.toBeCalled()
assertOutputApplied()
})
it('creates release if no release exists to update', async () => {
const action = createAction(true, true)
const error = { status: 404 }
const error = {status: 404}
getMock.mockRejectedValue(error)
await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
createDraft,
generateReleaseNotes,
createName,
createPrerelease)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied()
})
it('creates release if no draft releases', async () => {
const action = createAction(true, true)
const error = { status: 404 }
const error = {status: 404}
getMock.mockRejectedValue(error)
listMock.mockResolvedValue({
data: [
{ id: id, draft: false, tag_name: tag }
{id: id, draft: false, tag_name: tag}
]
})
await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
createDraft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied()
})
@@ -82,8 +117,36 @@ describe("Action", () => {
await action.perform()
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
createDraft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied()
})
it('removes all artifacts when artifact destroyer is enabled', async () => {
const action = createAction(false, true, true)
await action.perform()
expect(artifactDestroyMock).toBeCalledWith(releaseId)
assertOutputApplied()
})
it('removes no artifacts when artifact destroyer is disabled', async () => {
const action = createAction(false, true)
await action.perform()
expect(artifactDestroyMock).not.toBeCalled()
assertOutputApplied()
})
it('throws error when create fails', async () => {
@@ -97,7 +160,16 @@ describe("Action", () => {
expect(error).toEqual("error")
}
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
createDraft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).not.toBeCalled()
})
@@ -138,41 +210,69 @@ describe("Action", () => {
expect(error).toEqual("error")
}
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
expect(updateMock).toBeCalledWith(
id,
tag,
updateBody,
commit,
discussionCategory,
updateDraft,
updateName,
updatePrerelease
)
expect(uploadMock).not.toBeCalled()
})
it('throws error when upload fails', async () => {
const action = createAction(false, true)
uploadMock.mockRejectedValue("error")
const expectedError = {status: 404}
uploadMock.mockRejectedValue(expectedError)
expect.hasAssertions()
try {
await action.perform()
} catch (error) {
expect(error).toEqual("error")
expect(error).toEqual(expectedError)
}
expect(createMock).toBeCalledWith(tag, createBody, commit, draft, createName, prerelease)
expect(createMock).toBeCalledWith(
tag,
createBody,
commit,
discussionCategory,
createDraft,
generateReleaseNotes,
createName,
createPrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
})
it('updates draft release', async () => {
const action = createAction(true, true)
const error = { status: 404 }
const error = {status: 404}
getMock.mockRejectedValue(error)
listMock.mockResolvedValue({
data: [
{ id: 123, draft: false, tag_name: tag },
{ id: id, draft: true, tag_name: tag }
{id: 123, draft: false, tag_name: tag},
{id: id, draft: true, tag_name: tag}
]
})
await action.perform()
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
expect(updateMock).toBeCalledWith(
id,
tag,
updateBody,
commit,
discussionCategory,
updateDraft,
updateName,
updatePrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied()
})
it('updates release but does not upload if no artifact', async () => {
@@ -180,9 +280,18 @@ describe("Action", () => {
await action.perform()
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
expect(updateMock).toBeCalledWith(
id,
tag,
updateBody,
commit,
discussionCategory,
updateDraft,
updateName,
updatePrerelease
)
expect(uploadMock).not.toBeCalled()
assertOutputApplied()
})
it('updates release then uploads artifact', async () => {
@@ -190,12 +299,25 @@ describe("Action", () => {
await action.perform()
expect(updateMock).toBeCalledWith(id, tag, updateBody, commit, draft, updateName, prerelease)
expect(updateMock).toBeCalledWith(
id,
tag,
updateBody,
commit,
discussionCategory,
updateDraft,
updateName,
updatePrerelease
)
expect(uploadMock).toBeCalledWith(artifacts, releaseId, url)
assertOutputApplied()
})
function createAction(allowUpdates: boolean, hasArtifact: boolean): Action {
function assertOutputApplied() {
expect(applyReleaseDataMock).toBeCalledWith({id: releaseId, upload_url: url})
}
function createAction(allowUpdates: boolean, hasArtifact: boolean, removeArtifacts: boolean = false): Action {
let inputArtifact: Artifact[]
if (hasArtifact) {
inputArtifact = artifacts
@@ -239,17 +361,30 @@ describe("Action", () => {
const MockInputs = jest.fn<Inputs, any>(() => {
return {
allowUpdates: allowUpdates,
artifactErrorsFailBuild: true,
artifacts: inputArtifact,
createdDraft: createDraft,
createdReleaseBody: createBody,
createdReleaseName: createName,
commit: commit,
draft: draft,
prerelease: prerelease,
discussionCategory: discussionCategory,
generateReleaseNotes: true,
owner: "owner",
createdPrerelease: createPrerelease,
replacesArtifacts: replacesArtifacts,
removeArtifacts: removeArtifacts,
repo: "repo",
tag: tag,
token: token,
updatedDraft: updateDraft,
updatedReleaseBody: updateBody,
updatedReleaseName: updateName
updatedReleaseName: updateName,
updatedPrerelease: updatePrerelease
}
})
const MockOutputs = jest.fn<Outputs, any>(() => {
return {
applyReleaseData: applyReleaseDataMock
}
})
const MockUploader = jest.fn<ArtifactUploader, any>(() => {
@@ -257,11 +392,18 @@ describe("Action", () => {
uploadArtifacts: uploadMock
}
})
const MockArtifactDestroyer = jest.fn<ArtifactDestroyer, any>(() => {
return {
destroyArtifacts: artifactDestroyMock
}
})
const inputs = new MockInputs()
const outputs = new MockOutputs()
const releases = new MockReleases()
const uploader = new MockUploader()
const artifactDestroyer = new MockArtifactDestroyer()
return new Action(inputs, releases, uploader)
return new Action(inputs, outputs, releases, uploader, artifactDestroyer)
}
})

View File

@@ -0,0 +1,90 @@
import {Artifact} from "../src/Artifact"
import {GithubArtifactUploader} from "../src/ArtifactUploader"
import {Releases} from "../src/Releases";
import {RequestError} from '@octokit/request-error'
import {GithubArtifactDestroyer} from "../src/ArtifactDestroyer";
const releaseId = 100
const deleteMock = jest.fn()
const listArtifactsMock = jest.fn()
describe('ArtifactDestroyer', () => {
beforeEach(() => {
deleteMock.mockClear()
listArtifactsMock.mockClear()
})
it('destroys all artifacts', async () => {
mockListWithAssets()
mockDeleteSuccess()
const destroyer = createDestroyer()
await destroyer.destroyArtifacts(releaseId)
expect(deleteMock).toBeCalledTimes(2)
})
it('destroys nothing when no artifacts found', async () => {
mockListWithoutAssets()
const destroyer = createDestroyer()
await destroyer.destroyArtifacts(releaseId)
expect(deleteMock).toBeCalledTimes(0)
})
it('throws when delete call fails', async () => {
mockListWithAssets()
mockDeleteError()
const destroyer = createDestroyer()
expect.hasAssertions()
try {
await destroyer.destroyArtifacts(releaseId)
} catch (error) {
expect(error).toEqual("error")
}
})
function createDestroyer(): GithubArtifactDestroyer {
const MockReleases = jest.fn<Releases, any>(() => {
return {
create: jest.fn(),
deleteArtifact: deleteMock,
getByTag: jest.fn(),
listArtifactsForRelease: listArtifactsMock,
listReleases: jest.fn(),
update: jest.fn(),
uploadArtifact: jest.fn()
}
})
return new GithubArtifactDestroyer(new MockReleases())
}
function mockDeleteError(): any {
deleteMock.mockRejectedValue("error")
}
function mockDeleteSuccess(): any {
deleteMock.mockResolvedValue({})
}
function mockListWithAssets() {
listArtifactsMock.mockResolvedValue([
{
name: "art1",
id: 1
},
{
name: "art2",
id: 2
}
])
}
function mockListWithoutAssets() {
listArtifactsMock.mockResolvedValue([])
}
});

View File

@@ -1,22 +1,60 @@
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
import { Globber } from "../src/Globber";
import { Artifact } from "../src/Artifact";
const warnMock = jest.fn()
import {FileArtifactGlobber} from "../src/ArtifactGlobber"
import {Globber} from "../src/Globber";
import {Artifact} from "../src/Artifact";
import untildify = require("untildify");
const contentType = "raw"
const globMock = jest.fn()
const globResults = ["file1", "file2"]
jest.mock('@actions/core', () => {
return {warning: warnMock};
})
jest.mock('fs', () => {
return {
statSync: () => {
return {
isDirectory(): boolean {
return false
}
}
}
};
})
describe("ArtifactGlobber", () => {
beforeEach(() => {
globMock.mockClear()
})
it("expands paths in which start with a ~", () => {
const globber = createArtifactGlobber()
const expectedArtifacts =
globResults.map((path) => new Artifact(path, contentType))
expect(globber.globArtifactString('~/path', 'raw', false))
.toEqual(expectedArtifacts)
expect(globMock).toBeCalledWith(untildify('~/path'))
expect(warnMock).not.toBeCalled()
})
it("globs simple path", () => {
const globber = createArtifactGlobber()
const expectedArtifacts =
globResults.map((path) => new Artifact(path, contentType))
expect(globber.globArtifactString('path', 'raw'))
expect(globber.globArtifactString('path', 'raw', false))
.toEqual(expectedArtifacts)
expect(globMock).toBeCalledWith('path')
expect(warnMock).not.toBeCalled()
})
it("splits multiple paths", () => {
it("splits multiple paths with comma separator", () => {
const globber = createArtifactGlobber()
const expectedArtifacts =
@@ -24,16 +62,50 @@ describe("ArtifactGlobber", () => {
.concat(globResults)
.map((path) => new Artifact(path, contentType))
expect(globber.globArtifactString('path1,path2', 'raw'))
expect(globber.globArtifactString('path1,path2', 'raw', false))
.toEqual(expectedArtifacts)
expect(globMock).toBeCalledWith('path1')
expect(globMock).toBeCalledWith('path2')
expect(warnMock).not.toBeCalled()
})
function createArtifactGlobber(): FileArtifactGlobber {
it("splits multiple paths with new line separator and trims start", () => {
const globber = createArtifactGlobber()
const expectedArtifacts =
globResults
.concat(globResults)
.map((path) => new Artifact(path, contentType))
expect(globber.globArtifactString('path1\n path2', 'raw', false))
.toEqual(expectedArtifacts)
expect(globMock).toBeCalledWith('path1')
expect(globMock).toBeCalledWith('path2')
expect(warnMock).not.toBeCalled()
})
it("warns when no glob results are produced and empty results shouldn't throw", () => {
const globber = createArtifactGlobber([])
expect(globber.globArtifactString('path', 'raw', false))
.toEqual([])
expect(warnMock).toBeCalled()
})
it("throws when no glob results are produced and empty results shouild throw", () => {
const globber = createArtifactGlobber([])
expect(() => {
globber.globArtifactString('path', 'raw', true)
}).toThrow()
})
function createArtifactGlobber(results: string[] = globResults): FileArtifactGlobber {
const MockGlobber = jest.fn<Globber, any>(() => {
return {
glob: () => globResults
glob: globMock
}
})
globMock.mockReturnValue(results)
return new FileArtifactGlobber(new MockGlobber())
}
})

View File

@@ -0,0 +1,60 @@
const directoryMock = jest.fn()
const warnMock = jest.fn()
import {ArtifactPathValidator} from "../src/ArtifactPathValidator";
const pattern = 'pattern'
jest.mock('@actions/core', () => {
return {warning: warnMock};
})
jest.mock('fs', () => {
return {
statSync: () => {
return {isDirectory: directoryMock}
}
};
})
describe("ArtifactPathValidator", () => {
beforeEach(() => {
warnMock.mockClear()
directoryMock.mockClear()
})
it("warns and filters out path which points to a directory", () => {
const paths = ['path1', 'path2']
directoryMock.mockReturnValueOnce(true).mockReturnValueOnce(false)
const validator = new ArtifactPathValidator(false, paths, pattern)
const result = validator.validate()
expect(warnMock).toBeCalled()
expect(result).toEqual(['path2'])
})
it("warns when no glob results are produced and empty results shouldn't throw", () => {
const validator = new ArtifactPathValidator(false, [], pattern)
const result = validator.validate()
expect(warnMock).toBeCalled()
})
it("throws when no glob results are produced and empty results shouild throw", () => {
const validator = new ArtifactPathValidator(true, [], pattern)
expect(() => {
validator.validate()
}).toThrow()
})
it("throws when path points to directory", () => {
const paths = ['path1', 'path2']
directoryMock.mockReturnValueOnce(true).mockReturnValueOnce(false)
const validator = new ArtifactPathValidator(true, paths, pattern)
expect(() => {
validator.validate()
}).toThrow()
})
})

View File

@@ -1,7 +1,7 @@
import { Artifact } from "../src/Artifact"
import { GithubArtifactUploader } from "../src/ArtifactUploader"
import { Releases } from "../src/Releases";
import { RequestError } from '@octokit/request-error'
import {Artifact} from "../src/Artifact"
import {GithubArtifactUploader} from "../src/ArtifactUploader"
import {Releases} from "../src/Releases";
import {RequestError} from '@octokit/request-error'
const artifacts = [
new Artifact('a/art1'),
@@ -19,7 +19,9 @@ const uploadMock = jest.fn()
jest.mock('fs', () => {
return {
readFileSync: () => fileContents,
statSync: () => { return { size: contentLength } }
statSync: () => {
return {size: contentLength}
}
};
})
@@ -124,6 +126,19 @@ describe('ArtifactUploader', () => {
expect(deleteMock).toBeCalledTimes(0)
})
it('throws upload error when replacesExistingArtifacts is true', async () => {
mockListWithoutAssets()
mockUploadError()
const uploader = createUploader(true, true)
expect.hasAssertions()
try {
await uploader.uploadArtifacts(artifacts, releaseId, url)
} catch (error) {
expect(error).toEqual(Error("Failed to upload artifact art1. error."))
}
})
it('throws error from replace', async () => {
mockDeleteError()
mockListWithAssets()
@@ -155,7 +170,7 @@ describe('ArtifactUploader', () => {
expect(deleteMock).toBeCalledTimes(0)
})
function createUploader(replaces: boolean): GithubArtifactUploader {
function createUploader(replaces: boolean, throws: boolean = false): GithubArtifactUploader {
const MockReleases = jest.fn<Releases, any>(() => {
return {
create: jest.fn(),
@@ -167,7 +182,7 @@ describe('ArtifactUploader', () => {
uploadArtifact: uploadMock
}
})
return new GithubArtifactUploader(new MockReleases(), replaces)
return new GithubArtifactUploader(new MockReleases(), replaces, throws)
}
function mockDeleteError(): any {
@@ -179,29 +194,37 @@ describe('ArtifactUploader', () => {
}
function mockListWithAssets() {
listArtifactsMock.mockResolvedValue({
data: [
{
name: "art1",
id: 1
},
{
name: "art2",
id: 2
}
]
})
listArtifactsMock.mockResolvedValue([
{
name: "art1",
id: 1
},
{
name: "art2",
id: 2
}
])
}
function mockListWithoutAssets() {
listArtifactsMock.mockResolvedValue({ data: [] })
listArtifactsMock.mockResolvedValue([])
}
function mockUploadArtifact(status: number = 200, failures: number = 0) {
const error = new RequestError(`HTTP ${status}`, status, { headers: {}, request: { method: 'GET', url: '', headers: {} } })
const error = new RequestError(`HTTP ${status}`, status, {
headers: {},
request: {method: 'GET', url: '', headers: {}}
})
for (let index = 0; index < failures; index++) {
uploadMock.mockRejectedValueOnce(error)
}
uploadMock.mockResolvedValue({})
}
function mockUploadError() {
uploadMock.mockRejectedValue({
message: "error",
status: 502
})
}
});

View File

@@ -1,70 +0,0 @@
import { ErrorMessage } from "../src/ErrorMessage"
describe('ErrorMessage', () => {
describe('has error with code', () => {
const error = {
message: 'something bad happened',
errors: [
{
code: 'missing',
resource: 'release'
},
{
code: 'already_exists',
resource: 'release'
}
],
status: 422
}
it('does not have error', () => {
const errorMessage = new ErrorMessage(error)
expect(errorMessage.hasErrorWithCode('missing_field')).toBeFalsy()
})
it('has error', () => {
const errorMessage = new ErrorMessage(error)
expect(errorMessage.hasErrorWithCode('missing')).toBeTruthy()
})
})
it('generates message with errors', () => {
const error = {
message: 'something bad happened',
errors: [
{
code: 'missing',
resource: 'release'
},
{
code: 'already_exists',
resource: 'release'
}
],
status: 422
}
const errorMessage = new ErrorMessage(error)
const expectedString = "Error 422: something bad happened\nErrors:\n- release does not exist.\n- release already exists."
expect(errorMessage.toString()).toBe(expectedString)
})
it('generates message without errors', () => {
const error = {
message: 'something bad happened',
status: 422
}
const errorMessage = new ErrorMessage(error)
expect(errorMessage.toString()).toBe('Error 422: something bad happened')
})
it('provides error status', () => {
const error = { status: 404 }
const errorMessage = new ErrorMessage(error)
expect(errorMessage.status).toBe(404)
})
})

View File

@@ -1,99 +1,70 @@
import { GithubError } from "../src/GithubError"
describe('GithubError', () => {
describe('ErrorMessage', () => {
it('provides error code', () => {
describe('has error with code', () => {
const error = {
code: "missing"
message: 'something bad happened',
errors: [
{
code: 'missing',
resource: 'release'
},
{
code: 'already_exists',
resource: 'release'
}
],
status: 422
}
const githubError = new GithubError(error)
expect(githubError.code).toBe('missing')
})
it('generates missing resource error message', () => {
const resource = "release"
const error = {
code: "missing",
resource: resource
}
const githubError = new GithubError(error)
const message = githubError.toString()
expect(message).toBe(`${resource} does not exist.`)
})
it('generates missing field error message', () => {
const resource = "release"
const field = "body"
const error = {
code: "missing_field",
field: field,
resource: resource
}
const githubError = new GithubError(error)
const message = githubError.toString()
expect(message).toBe(`The ${field} field on ${resource} is missing.`)
})
it('generates invalid field error message', () => {
const resource = "release"
const field = "body"
const error = {
code: "invalid",
field: field,
resource: resource
}
const githubError = new GithubError(error)
const message = githubError.toString()
expect(message).toBe(`The ${field} field on ${resource} is an invalid format.`)
})
it('generates resource already exists error message', () => {
const resource = "release"
const field = "body"
const error = {
code: "already_exists",
resource: resource
}
const githubError = new GithubError(error)
const message = githubError.toString()
expect(message).toBe(`${resource} already exists.`)
})
describe('generates custom error message', () => {
it('with documentation url', () => {
const url = "https://api.example.com"
const error = {
code: "custom",
message: "foo",
documentation_url: url
}
it('does not have error', () => {
const githubError = new GithubError(error)
const message = githubError.toString()
expect(message).toBe(`foo\nPlease see ${url}.`)
expect(githubError.hasErrorWithCode('missing_field')).toBeFalsy()
})
it('without documentation url', () => {
const error = {
code: "custom",
message: "foo"
}
it('has error', () => {
const githubError = new GithubError(error)
const message = githubError.toString()
expect(message).toBe('foo')
expect(githubError.hasErrorWithCode('missing')).toBeTruthy()
})
})
})
it('generates message with errors', () => {
const error = {
message: 'something bad happened',
errors: [
{
code: 'missing',
resource: 'release'
},
{
code: 'already_exists',
resource: 'release'
}
],
status: 422
}
const githubError = new GithubError(error)
const expectedString = "Error 422: something bad happened\nErrors:\n- release does not exist.\n- release already exists."
expect(githubError.toString()).toBe(expectedString)
})
it('generates message without errors', () => {
const error = {
message: 'something bad happened',
status: 422
}
const githubError = new GithubError(error)
expect(githubError.toString()).toBe('Error 422: something bad happened')
})
it('provides error status', () => {
const error = { status: 404 }
const githubError = new GithubError(error)
expect(githubError.status).toBe(404)
})
})

View File

@@ -0,0 +1,98 @@
import { GithubErrorDetail } from "../src/GithubErrorDetail"
describe('GithubErrorDetail', () => {
it('provides error code', () => {
const error = {
code: "missing"
}
const detail = new GithubErrorDetail(error)
expect(detail.code).toBe('missing')
})
it('generates missing resource error message', () => {
const resource = "release"
const error = {
code: "missing",
resource: resource
}
const detail = new GithubErrorDetail(error)
const message = detail.toString()
expect(message).toBe(`${resource} does not exist.`)
})
it('generates missing field error message', () => {
const resource = "release"
const field = "body"
const error = {
code: "missing_field",
field: field,
resource: resource
}
const detail = new GithubErrorDetail(error)
const message = detail.toString()
expect(message).toBe(`The ${field} field on ${resource} is missing.`)
})
it('generates invalid field error message', () => {
const resource = "release"
const field = "body"
const error = {
code: "invalid",
field: field,
resource: resource
}
const detail = new GithubErrorDetail(error)
const message = detail.toString()
expect(message).toBe(`The ${field} field on ${resource} is an invalid format.`)
})
it('generates resource already exists error message', () => {
const resource = "release"
const error = {
code: "already_exists",
resource: resource
}
const detail = new GithubErrorDetail(error)
const message = detail.toString()
expect(message).toBe(`${resource} already exists.`)
})
describe('generates custom error message', () => {
it('with documentation url', () => {
const url = "https://api.example.com"
const error = {
code: "custom",
message: "foo",
documentation_url: url
}
const detail = new GithubErrorDetail(error)
const message = detail.toString()
expect(message).toBe(`foo\nPlease see ${url}.`)
})
it('without documentation url', () => {
const error = {
code: "custom",
message: "foo"
}
const detail = new GithubErrorDetail(error)
const message = detail.toString()
expect(message).toBe('foo')
})
})
})

View File

@@ -38,9 +38,16 @@ describe('Inputs', () => {
inputs = new CoreInputs(createGlobber(), context)
})
it('returns targetCommit', () => {
mockGetInput.mockReturnValue('42')
expect(inputs.commit).toBe('42')
describe('commit', () => {
it('returns commit', () => {
mockGetInput.mockReturnValueOnce('commit')
expect(inputs.commit).toBe('commit')
})
it('returns undefined when omitted', () => {
mockGetInput.mockReturnValueOnce('')
expect(inputs.commit).toBeUndefined()
})
})
it('returns token', () => {
@@ -59,7 +66,28 @@ describe('Inputs', () => {
})
})
describe('artifactErrorsFailBuild', () => {
it('returns false', () => {
expect(inputs.artifactErrorsFailBuild).toBe(false)
})
it('returns true', () => {
mockGetInput.mockReturnValue('true')
expect(inputs.artifactErrorsFailBuild).toBe(true)
})
})
describe('artifacts', () => {
it('globber told to throw errors', () => {
mockGetInput.mockReturnValueOnce('art1')
.mockReturnValueOnce('contentType')
.mockReturnValueOnce('true')
expect(inputs.artifacts).toEqual(artifacts)
expect(mockGlob).toBeCalledTimes(1)
expect(mockGlob).toBeCalledWith('art1', 'contentType', true)
})
it('returns empty artifacts', () => {
mockGetInput.mockReturnValueOnce('')
.mockReturnValueOnce('')
@@ -71,28 +99,43 @@ describe('Inputs', () => {
it('returns input.artifacts', () => {
mockGetInput.mockReturnValueOnce('art1')
.mockReturnValueOnce('contentType')
.mockReturnValueOnce('false')
expect(inputs.artifacts).toEqual(artifacts)
expect(mockGlob).toBeCalledTimes(1)
expect(mockGlob).toBeCalledWith('art1', 'contentType')
expect(mockGlob).toBeCalledWith('art1', 'contentType', false)
})
it('returns input.artifacts with default contentType', () => {
mockGetInput.mockReturnValueOnce('art1')
.mockReturnValueOnce('')
.mockReturnValueOnce('false')
expect(inputs.artifacts).toEqual(artifacts)
expect(mockGlob).toBeCalledTimes(1)
expect(mockGlob).toBeCalledWith('art1', 'raw')
expect(mockGlob).toBeCalledWith('art1', 'raw', false)
})
it('returns input.artifact', () => {
mockGetInput.mockReturnValueOnce('')
.mockReturnValueOnce('art2')
.mockReturnValueOnce('contentType')
.mockReturnValueOnce('false')
expect(inputs.artifacts).toEqual(artifacts)
expect(mockGlob).toBeCalledTimes(1)
expect(mockGlob).toBeCalledWith('art2', 'contentType')
expect(mockGlob).toBeCalledWith('art2', 'contentType', false)
})
})
describe('createdDraft', () => {
it('returns false', () => {
expect(inputs.createdDraft).toBe(false)
})
it('returns true', () => {
mockGetInput.mockReturnValue('true')
expect(inputs.createdDraft).toBe(true)
})
})
@@ -142,7 +185,7 @@ describe('Inputs', () => {
mockGetInput
.mockReturnValueOnce('true')
.mockReturnValueOnce('name')
expect(inputs.createdReleaseBody).toBeUndefined()
expect(inputs.createdReleaseName).toBeUndefined()
})
it('returns tag', () => {
@@ -154,25 +197,50 @@ describe('Inputs', () => {
})
})
describe('draft', () => {
it('returns false', () => {
expect(inputs.draft).toBe(false)
describe('discussionCategory', () => {
it('returns category', () => {
mockGetInput.mockReturnValue('Release')
expect(inputs.discussionCategory).toBe('Release')
})
it('returns true', () => {
mockGetInput.mockReturnValue('true')
expect(inputs.draft).toBe(true)
it('returns undefined', () => {
mockGetInput.mockReturnValue('')
expect(inputs.discussionCategory).toBe(undefined)
})
})
describe('prerelase', () => {
describe('generateReleaseNotes', () => {
it('returns returns true', function () {
mockGetInput.mockReturnValue("true")
expect(inputs.generateReleaseNotes).toBe(true)
});
it('returns false when omitted', function () {
mockGetInput.mockReturnValue("")
expect(inputs.generateReleaseNotes).toBe(false)
});
})
describe('owner', () => {
it('returns owner from context', function () {
process.env.GITHUB_REPOSITORY = "owner/repo"
mockGetInput.mockReturnValue("")
expect(inputs.owner).toBe("owner")
});
it('returns owner from inputs', function () {
mockGetInput.mockReturnValue("owner")
expect(inputs.owner).toBe("owner")
});
})
describe('createdPrerelase', () => {
it('returns false', () => {
expect(inputs.prerelease).toBe(false)
expect(inputs.createdPrerelease).toBe(false)
})
it('returns true', () => {
mockGetInput.mockReturnValue('true')
expect(inputs.prerelease).toBe(true)
expect(inputs.createdPrerelease).toBe(true)
})
})
@@ -187,6 +255,29 @@ describe('Inputs', () => {
})
})
describe('removeArtifacts', () => {
it('returns false', () => {
expect(inputs.removeArtifacts).toBe(false)
})
it('returns true', () => {
mockGetInput.mockReturnValue('true')
expect(inputs.removeArtifacts).toBe(true)
})
})
describe('repo', () => {
it('returns repo from context', function () {
process.env.GITHUB_REPOSITORY = "owner/repo"
mockGetInput.mockReturnValue("")
expect(inputs.repo).toBe("repo")
});
it('returns repo from inputs', function () {
mockGetInput.mockReturnValue("repo")
expect(inputs.repo).toBe("repo")
});
})
describe('tag', () => {
it('returns input tag', () => {
mockGetInput.mockReturnValue('tag')
@@ -203,10 +294,38 @@ describe('Inputs', () => {
expect(inputs.tag).toBe('sha-tag')
})
it('throws if no tag', () => {
context.ref = ""
expect(() => inputs.tag).toThrow()
})
})
describe('updatedDraft', () => {
it('returns false', () => {
expect(inputs.updatedDraft).toBe(false)
})
it('returns true', () => {
mockGetInput
.mockReturnValueOnce('false')
.mockReturnValue('true')
expect(inputs.updatedDraft).toBe(true)
})
it('returns true when omitted is blank', () => {
mockGetInput
.mockReturnValueOnce('')
.mockReturnValue('true')
expect(inputs.updatedDraft).toBe(true)
})
it('returns undefined when omitted for update', () => {
mockGetInput
.mockReturnValueOnce('true')
.mockReturnValueOnce('true')
expect(inputs.updatedDraft).toBeUndefined()
})
})
describe('updatedReleaseBody', () => {
it('returns input body', () => {
mockGetInput
@@ -288,6 +407,29 @@ describe('Inputs', () => {
})
})
describe('updatedPrerelease', () => {
it('returns false', () => {
mockGetInput
.mockReturnValueOnce('false')
.mockReturnValueOnce('false')
expect(inputs.updatedPrerelease).toBe(false)
})
it('returns true', () => {
mockGetInput
.mockReturnValueOnce('false')
.mockReturnValueOnce('true')
expect(inputs.updatedPrerelease).toBe(true)
})
it('returns undefined when omitted for update', () => {
mockGetInput
.mockReturnValueOnce('true')
.mockReturnValueOnce('false')
expect(inputs.updatedPrerelease).toBeUndefined()
})
})
function createGlobber(): ArtifactGlobber {
const MockGlobber = jest.fn<ArtifactGlobber, any>(() => {
return {

View File

@@ -0,0 +1,88 @@
import {Action} from "../src/Action";
import * as github from "@actions/github";
import {Inputs} from "../src/Inputs";
import {GithubReleases, ReleaseData} from "../src/Releases";
import {GithubArtifactUploader} from "../src/ArtifactUploader";
import * as path from "path";
import {FileArtifactGlobber} from "../src/ArtifactGlobber";
import {Outputs} from "../src/Outputs";
import {GithubArtifactDestroyer} from "../src/ArtifactDestroyer";
// This test is currently intended to be manually run during development. To run:
// - Make sure you have an environment variable named GITHUB_TOKEN assigned to your token
// - Remove skip from the test below
describe.skip('Integration Test', () => {
let action: Action
beforeEach(() => {
const token = getToken()
const git = github.getOctokit(token)
const inputs = getInputs()
const outputs = getOutputs()
const releases = new GithubReleases(inputs, git)
const uploader = new GithubArtifactUploader(
releases,
inputs.replacesArtifacts,
inputs.artifactErrorsFailBuild,
)
const artifactDestroyer = new GithubArtifactDestroyer(releases)
action = new Action(inputs, outputs, releases, uploader, artifactDestroyer)
})
it('Performs action', async () => {
await action.perform()
})
function getInputs(): Inputs {
const MockInputs = jest.fn<Inputs, any>(() => {
return {
allowUpdates: true,
artifactErrorsFailBuild: false,
artifacts: artifacts(),
createdDraft: false,
createdReleaseBody: "This release was generated by release-action's integration test",
createdReleaseName: "Releases Action Integration Test",
commit: undefined,
discussionCategory: 'Release',
generateReleaseNotes: true,
owner: "ncipollo",
createdPrerelease: false,
replacesArtifacts: true,
removeArtifacts: false,
repo: "actions-playground",
tag: "release-action-test",
token: getToken(),
updatedDraft: false,
updatedReleaseBody: "This release was generated by release-action's integration test",
updatedReleaseName: "Releases Action Integration Test",
updatedPrerelease: false
}
})
return new MockInputs();
}
function getOutputs(): Outputs {
const MockOutputs = jest.fn<Outputs, any>(() => {
return {
applyReleaseData(releaseData: ReleaseData) {
console.log(`Release Data: ${releaseData}`)
}
}
})
return new MockOutputs()
}
function artifacts() {
const globber = new FileArtifactGlobber()
const artifactPath = path.join(__dirname, 'Integration.test.ts')
const artifactString = `~/Desktop,~/Desktop/test.txt,blarg.tx, ${artifactPath}`
return globber.globArtifactString(artifactString, "raw", false)
}
function getToken(): string {
return process.env.GITHUB_TOKEN ?? ""
}
})

29
__tests__/Outputs.test.ts Normal file
View File

@@ -0,0 +1,29 @@
const mockSetOutput = jest.fn();
import {CoreOutputs, Outputs} from "../src/Outputs";
import {ReleaseData} from "../src/Releases";
jest.mock('@actions/core', () => {
return {setOutput: mockSetOutput};
})
describe('Outputs', () => {
let outputs: Outputs;
let releaseData: ReleaseData
beforeEach(() => {
outputs = new CoreOutputs()
releaseData = {
id: 1,
html_url: 'https://api.example.com/assets',
upload_url: 'https://api.example.com'
}
})
it('Applies the release data to the action output', () => {
outputs.applyReleaseData(releaseData)
expect(mockSetOutput).toBeCalledWith('id', releaseData.id)
expect(mockSetOutput).toBeCalledWith('html_url', releaseData.html_url)
expect(mockSetOutput).toBeCalledWith('upload_url', releaseData.upload_url)
})
})

View File

@@ -6,6 +6,10 @@ inputs:
description: 'An optional flag which indicates if we should update a release if it already exists. Defaults to false.'
required: false
default: ''
artifactErrorsFailBuild:
description: 'An optional flag which indicates if artifact read or upload errors should fail the build.'
required: false
default: ''
artifact:
deprecationMessage: Use 'artifacts' instead.
description: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs)'
@@ -30,11 +34,19 @@ inputs:
commit:
description: "An optional commit reference. This will be used to create the tag if it does not exist."
required: false
default: ''
discussionCategory:
description: "When provided this will generate a discussion of the specified category. The category must exist otherwise this will cause the action to fail. This isn't used with draft releases"
required: false
default: ''
draft:
description: "Optionally marks this release as a draft release. Set to true to enable."
required: false
default: ''
generateReleaseNotes:
description: 'Indicates if release notes should be automatically generated.'
required: false
default: 'false'
name:
description: 'An optional name for the release. If this is omitted the tag will be used.'
required: false
@@ -47,6 +59,10 @@ inputs:
description: 'Indicates if the release body should be omitted during updates. The body will still be applied for newly created releases. This will preserve the existing body during updates.'
required: false
default: 'false'
omitDraftDuringUpdate:
description: 'Indicates if the draft flag should be omitted during updates. The draft flag will still be applied for newly created releases. This will preserve the existing draft state during updates.'
required: false
default: 'false'
omitName:
description: 'Indicates if the release name should be omitted.'
required: false
@@ -55,25 +71,48 @@ inputs:
description: 'Indicates if the release name should be omitted during updates. The name will still be applied for newly created releases. This will preserve the existing name during updates.'
required: false
default: 'false'
omitPrereleaseDuringUpdate:
description: 'Indicates if the prerelease flag should be omitted during updates. The prerelease flag will still be applied for newly created releases. This will preserve the existing prerelease state during updates.'
required: false
default: 'false'
owner:
description: "Optionally specify the owner of the repo where the release should be generated. Defaults to current repo's owner."
required: false
default: ''
prerelease:
description: "Optionally marks this release as prerelease. Set to true to enable."
required: false
default: ''
removeArtifacts:
description: 'Indicates if existing release artifacts should be removed, Defaults to false.'
required: false
default: 'false'
replacesArtifacts:
description: "Indicates if existing release artifacts should be replaced. Defaults to true."
required: false
default: 'true'
repo:
description: "Optionally specify the repo where the release should be generated. Defaults to current repo"
required: false
default: ''
tag:
description: 'An optional tag for the release. If this is omitted the git ref will be used (if it is a tag).'
required: false
default: ''
token:
description: 'The Github token.'
required: true
default: ''
required: false
default: ${{ github.token }}
outputs:
id:
description: 'The identifier of the created release.'
html_url:
description: 'The HTML URL of the release.'
upload_url:
description: 'The URL for uploading assets to the release.'
runs:
using: 'node12'
main: 'lib/Main.js'
main: 'dist/index.js'
branding:
icon: 'tag'
color: 'gray-dark'

13215
dist/index.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/index.js.map vendored Normal file

File diff suppressed because one or more lines are too long

862
dist/licenses.txt vendored Normal file
View File

@@ -0,0 +1,862 @@
@actions/core
MIT
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
@actions/github
MIT
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
@actions/http-client
MIT
Actions Http Client for Node.js
Copyright (c) GitHub, Inc.
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
@octokit/auth-token
MIT
The MIT License
Copyright (c) 2019 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
@octokit/core
MIT
The MIT License
Copyright (c) 2019 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
@octokit/endpoint
MIT
The MIT License
Copyright (c) 2018 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
@octokit/graphql
MIT
The MIT License
Copyright (c) 2018 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
@octokit/plugin-paginate-rest
MIT
MIT License Copyright (c) 2019 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
@octokit/plugin-rest-endpoint-methods
MIT
MIT License Copyright (c) 2019 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
@octokit/request
MIT
The MIT License
Copyright (c) 2018 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
@octokit/request-error
MIT
The MIT License
Copyright (c) 2019 Octokit contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
@vercel/ncc
MIT
Copyright 2018 ZEIT, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
balanced-match
MIT
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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 THE
SOFTWARE.
before-after-hook
Apache-2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018 Gregor Martynus and other contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
brace-expansion
MIT
MIT License
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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 THE
SOFTWARE.
concat-map
MIT
This software is released under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
deprecation
ISC
The ISC License
Copyright (c) Gregor Martynus and contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
fs.realpath
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----
This library bundles a version of the `fs.realpath` and `fs.realpathSync`
methods from Node.js v0.10 under the terms of the Node.js MIT license.
Node's license follows, also included at the header of `old.js` which contains
the licensed code:
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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 THE SOFTWARE.
glob
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
## Glob Logo
Glob's logo created by Tanya Brassie <http://tanyabrassie.com/>, licensed
under a Creative Commons Attribution-ShareAlike 4.0 International License
https://creativecommons.org/licenses/by-sa/4.0/
inflight
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
inherits
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
is-plain-object
MIT
The MIT License (MIT)
Copyright (c) 2014-2017, Jon Schlinkert.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
minimatch
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
node-fetch
MIT
The MIT License (MIT)
Copyright (c) 2016 David Frank
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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 THE
SOFTWARE.
once
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
path-is-absolute
MIT
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
tr46
MIT
tunnel
MIT
The MIT License (MIT)
Copyright (c) 2012 Koichi Kobayashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
universal-user-agent
ISC
# [ISC License](https://spdx.org/licenses/ISC)
Copyright (c) 2018, Gregor Martynus (https://github.com/gr2m)
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
untildify
MIT
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 THE SOFTWARE.
webidl-conversions
BSD-2-Clause
# The BSD 2-Clause License
Copyright (c) 2014, Domenic Denicola
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
whatwg-url
MIT
The MIT License (MIT)
Copyright (c) 20152016 Sebastian Mayr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
wrappy
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

1
dist/sourcemap-register.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,68 +1,100 @@
"use strict";
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) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Action = void 0;
const ErrorMessage_1 = require("./ErrorMessage");
const GithubError_1 = require("./GithubError");
class Action {
constructor(inputs, releases, uploader) {
constructor(inputs, outputs, releases, uploader, artifactDestroyer) {
this.inputs = inputs;
this.outputs = outputs;
this.releases = releases;
this.uploader = uploader;
this.artifactDestroyer = artifactDestroyer;
}
async perform() {
const releaseResponse = await this.createOrUpdateRelease();
const releaseId = releaseResponse.id;
const uploadUrl = releaseResponse.upload_url;
const artifacts = this.inputs.artifacts;
if (artifacts.length > 0) {
await this.uploader.uploadArtifacts(artifacts, releaseId, uploadUrl);
}
}
async createOrUpdateRelease() {
if (this.inputs.allowUpdates) {
try {
const getResponse = await this.releases.getByTag(this.inputs.tag);
return await this.updateRelease(getResponse.data.id);
perform() {
return __awaiter(this, void 0, void 0, function* () {
const releaseResponse = yield this.createOrUpdateRelease();
const releaseData = releaseResponse.data;
const releaseId = releaseData.id;
const uploadUrl = releaseData.upload_url;
if (this.inputs.removeArtifacts) {
yield this.artifactDestroyer.destroyArtifacts(releaseId);
}
catch (error) {
if (Action.noPublishedRelease(error)) {
return await this.updateDraftOrCreateRelease();
}
else {
throw error;
}
const artifacts = this.inputs.artifacts;
if (artifacts.length > 0) {
yield this.uploader.uploadArtifacts(artifacts, releaseId, uploadUrl);
}
}
else {
return await this.createRelease();
}
this.outputs.applyReleaseData(releaseData);
});
}
async updateRelease(id) {
const response = await this.releases.update(id, this.inputs.tag, this.inputs.updatedReleaseBody, this.inputs.commit, this.inputs.draft, this.inputs.updatedReleaseName, this.inputs.prerelease);
return response.data;
createOrUpdateRelease() {
return __awaiter(this, void 0, void 0, function* () {
if (this.inputs.allowUpdates) {
let getResponse;
try {
getResponse = yield this.releases.getByTag(this.inputs.tag);
}
catch (error) {
return yield this.checkForMissingReleaseError(error);
}
return yield this.updateRelease(getResponse.data.id);
}
else {
return yield this.createRelease();
}
});
}
checkForMissingReleaseError(error) {
return __awaiter(this, void 0, void 0, function* () {
if (Action.noPublishedRelease(error)) {
return yield this.updateDraftOrCreateRelease();
}
else {
throw error;
}
});
}
updateRelease(id) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.releases.update(id, this.inputs.tag, this.inputs.updatedReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.updatedDraft, this.inputs.updatedReleaseName, this.inputs.updatedPrerelease);
});
}
static noPublishedRelease(error) {
const errorMessage = new ErrorMessage_1.ErrorMessage(error);
return errorMessage.status == 404;
const githubError = new GithubError_1.GithubError(error);
return githubError.status == 404;
}
async updateDraftOrCreateRelease() {
const draftReleaseId = await this.findMatchingDraftReleaseId();
if (draftReleaseId) {
return await this.updateRelease(draftReleaseId);
}
else {
return await this.createRelease();
}
updateDraftOrCreateRelease() {
return __awaiter(this, void 0, void 0, function* () {
const draftReleaseId = yield this.findMatchingDraftReleaseId();
if (draftReleaseId) {
return yield this.updateRelease(draftReleaseId);
}
else {
return yield this.createRelease();
}
});
}
async findMatchingDraftReleaseId() {
const tag = this.inputs.tag;
const response = await this.releases.listReleases();
const releases = response.data;
const draftRelease = releases.find(release => release.draft && release.tag_name == tag);
return draftRelease === null || draftRelease === void 0 ? void 0 : draftRelease.id;
findMatchingDraftReleaseId() {
return __awaiter(this, void 0, void 0, function* () {
const tag = this.inputs.tag;
const response = yield this.releases.listReleases();
const releases = response.data;
const draftRelease = releases.find(release => release.draft && release.tag_name == tag);
return draftRelease === null || draftRelease === void 0 ? void 0 : draftRelease.id;
});
}
async createRelease() {
const response = await this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.draft, this.inputs.createdReleaseName, this.inputs.prerelease);
return response.data;
createRelease() {
return __awaiter(this, void 0, void 0, function* () {
return yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.discussionCategory, this.inputs.createdDraft, this.inputs.generateReleaseNotes, this.inputs.createdReleaseName, this.inputs.createdPrerelease);
});
}
}
exports.Action = Action;

View File

@@ -6,14 +6,14 @@ const fs_1 = require("fs");
class Artifact {
constructor(path, contentType = "raw") {
this.path = path;
this.name = path_1.basename(path);
this.name = (0, path_1.basename)(path);
this.contentType = contentType;
}
get contentLength() {
return fs_1.statSync(this.path).size;
return (0, fs_1.statSync)(this.path).size;
}
readFile() {
return fs_1.readFileSync(this.path);
return (0, fs_1.readFileSync)(this.path);
}
}
exports.Artifact = Artifact;

52
lib/ArtifactDestroyer.js Normal file
View File

@@ -0,0 +1,52 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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.prototype.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) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubArtifactDestroyer = void 0;
const core = __importStar(require("@actions/core"));
class GithubArtifactDestroyer {
constructor(releases) {
this.releases = releases;
}
destroyArtifacts(releaseId) {
return __awaiter(this, void 0, void 0, function* () {
const releaseAssets = yield this.releases.listArtifactsForRelease(releaseId);
for (const artifact of releaseAssets) {
const asset = artifact;
core.debug(`Deleting existing artifact ${artifact.name}...`);
yield this.releases.deleteArtifact(asset.id);
}
});
}
}
exports.GithubArtifactDestroyer = GithubArtifactDestroyer;

View File

@@ -1,17 +1,75 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileArtifactGlobber = void 0;
const core = __importStar(require("@actions/core"));
const Globber_1 = require("./Globber");
const Artifact_1 = require("./Artifact");
const untildify_1 = __importDefault(require("untildify"));
const ArtifactPathValidator_1 = require("./ArtifactPathValidator");
class FileArtifactGlobber {
constructor(globber = new Globber_1.FileGlobber()) {
this.globber = globber;
}
globArtifactString(artifact, contentType) {
return artifact.split(',')
.map((path) => this.globber.glob(path))
globArtifactString(artifact, contentType, errorsFailBuild) {
const split = /[,\n]/;
return artifact.split(split)
.map(path => path.trimStart())
.map(path => FileArtifactGlobber.expandPath(path))
.map(pattern => this.globPattern(pattern, errorsFailBuild))
.map((globResult) => FileArtifactGlobber.validatePattern(errorsFailBuild, globResult[1], globResult[0]))
.reduce((accumulated, current) => accumulated.concat(current))
.map((path) => new Artifact_1.Artifact(path, contentType));
.map(path => new Artifact_1.Artifact(path, contentType));
}
globPattern(pattern, errorsFailBuild) {
const paths = this.globber.glob(pattern);
if (paths.length == 0) {
if (errorsFailBuild) {
FileArtifactGlobber.throwGlobError(pattern);
}
else {
FileArtifactGlobber.reportGlobWarning(pattern);
}
}
return [pattern, paths];
}
static validatePattern(errorsFailBuild, paths, pattern) {
const validator = new ArtifactPathValidator_1.ArtifactPathValidator(errorsFailBuild, paths, pattern);
return validator.validate();
}
static reportGlobWarning(pattern) {
core.warning(`Artifact pattern :${pattern} did not match any files`);
}
static throwGlobError(pattern) {
throw Error(`Artifact pattern :${pattern} did not match any files`);
}
static expandPath(path) {
return (0, untildify_1.default)(path);
}
}
exports.FileArtifactGlobber = FileArtifactGlobber;

View File

@@ -0,0 +1,62 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArtifactPathValidator = void 0;
const core = __importStar(require("@actions/core"));
const fs_1 = require("fs");
class ArtifactPathValidator {
constructor(errorsFailBuild, paths, pattern) {
this.paths = paths;
this.pattern = pattern;
this.errorsFailBuild = errorsFailBuild;
}
validate() {
this.verifyPathsNotEmpty();
return this.paths.filter((path) => this.verifyNotDirectory(path));
}
verifyPathsNotEmpty() {
if (this.paths.length == 0) {
const message = `Artifact pattern:${this.pattern} did not match any files`;
this.reportError(message);
}
}
verifyNotDirectory(path) {
const isDir = (0, fs_1.statSync)(path).isDirectory();
if (isDir) {
const message = `Artifact is a directory:${path}. Directories can not be uploaded to a release.`;
this.reportError(message);
}
return !isDir;
}
reportError(message) {
if (this.errorsFailBuild) {
throw Error(message);
}
else {
core.warning(message);
}
}
}
exports.ArtifactPathValidator = ArtifactPathValidator;

View File

@@ -1,7 +1,11 @@
"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]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
@@ -14,55 +18,75 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
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);
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.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) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubArtifactUploader = void 0;
const core = __importStar(require("@actions/core"));
class GithubArtifactUploader {
constructor(releases, replacesExistingArtifacts = true) {
constructor(releases, replacesExistingArtifacts = true, throwsUploadErrors = false) {
this.releases = releases;
this.replacesExistingArtifacts = replacesExistingArtifacts;
this.throwsUploadErrors = throwsUploadErrors;
}
async uploadArtifacts(artifacts, releaseId, uploadUrl) {
if (this.replacesExistingArtifacts) {
await this.deleteUpdatedArtifacts(artifacts, releaseId);
}
for (const artifact of artifacts) {
await this.uploadArtifact(artifact, releaseId, uploadUrl);
}
}
async uploadArtifact(artifact, releaseId, uploadUrl, retry = 3) {
try {
core.debug(`Uploading artifact ${artifact.name}...`);
await this.releases.uploadArtifact(uploadUrl, artifact.contentLength, artifact.contentType, artifact.readFile(), artifact.name, releaseId);
}
catch (error) {
if (error.status >= 500 && retry > 0) {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}. Retrying...`);
await this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1);
uploadArtifacts(artifacts, releaseId, uploadUrl) {
return __awaiter(this, void 0, void 0, function* () {
if (this.replacesExistingArtifacts) {
yield this.deleteUpdatedArtifacts(artifacts, releaseId);
}
else {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
for (const artifact of artifacts) {
yield this.uploadArtifact(artifact, releaseId, uploadUrl);
}
}
}
async deleteUpdatedArtifacts(artifacts, releaseId) {
const response = await this.releases.listArtifactsForRelease(releaseId);
const releaseAssets = response.data;
const assetByName = {};
releaseAssets.forEach(asset => {
assetByName[asset.name] = asset;
});
for (const artifact of artifacts) {
const asset = assetByName[artifact.name];
if (asset) {
core.debug(`Deleting existing artifact ${artifact.name}...`);
await this.releases.deleteArtifact(asset.id);
}
uploadArtifact(artifact, releaseId, uploadUrl, retry = 3) {
return __awaiter(this, void 0, void 0, function* () {
try {
core.debug(`Uploading artifact ${artifact.name}...`);
yield this.releases.uploadArtifact(uploadUrl, artifact.contentLength, artifact.contentType, artifact.readFile(), artifact.name, releaseId);
}
}
catch (error) {
if (error.status >= 500 && retry > 0) {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}. Retrying...`);
yield this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1);
}
else {
if (this.throwsUploadErrors) {
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
}
else {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
}
}
}
});
}
deleteUpdatedArtifacts(artifacts, releaseId) {
return __awaiter(this, void 0, void 0, function* () {
const releaseAssets = yield this.releases.listArtifactsForRelease(releaseId);
const assetByName = {};
releaseAssets.forEach(asset => {
assetByName[asset.name] = asset;
});
for (const artifact of artifacts) {
const asset = assetByName[artifact.name];
if (asset) {
core.debug(`Deleting existing artifact ${artifact.name}...`);
yield this.releases.deleteArtifact(asset.id);
}
}
});
}
}
exports.GithubArtifactUploader = GithubArtifactUploader;

View File

@@ -1,40 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorMessage = void 0;
const GithubError_1 = require("./GithubError");
class ErrorMessage {
constructor(error) {
this.error = error;
this.githubErrors = this.generateGithubErrors();
}
generateGithubErrors() {
const errors = this.error.errors;
if (errors instanceof Array) {
return errors.map((err) => new GithubError_1.GithubError(err));
}
else {
return [];
}
}
get status() {
return this.error.status;
}
hasErrorWithCode(code) {
return this.githubErrors.some((err) => err.code == code);
}
toString() {
const message = this.error.message;
const errors = this.githubErrors;
const status = this.status;
if (errors.length > 0) {
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`;
}
else {
return `Error ${status}: ${message}`;
}
}
errorBulletedList(errors) {
return errors.map((err) => `- ${err}`).join("\n");
}
}
exports.ErrorMessage = ErrorMessage;

View File

@@ -1,57 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubError = void 0;
const GithubErrorDetail_1 = require("./GithubErrorDetail");
class GithubError {
constructor(error) {
this.error = error;
this.githubErrors = this.generateGithubErrors();
}
get code() {
return this.error.code;
}
toString() {
const code = this.error.code;
switch (code) {
case 'missing':
return this.missingResourceMessage();
case 'missing_field':
return this.missingFieldMessage();
case 'invalid':
return this.invalidFieldMessage();
case 'already_exists':
return this.resourceAlreadyExists();
default:
return this.customErrorMessage();
}
}
customErrorMessage() {
const message = this.error.message;
const documentation = this.error.documentation_url;
let documentationMessage;
if (documentation) {
documentationMessage = `\nPlease see ${documentation}.`;
generateGithubErrors() {
const errors = this.error.errors;
if (errors instanceof Array) {
return errors.map((err) => new GithubErrorDetail_1.GithubErrorDetail(err));
}
else {
documentationMessage = "";
return [];
}
return `${message}${documentationMessage}`;
}
invalidFieldMessage() {
const resource = this.error.resource;
const field = this.error.field;
return `The ${field} field on ${resource} is an invalid format.`;
get status() {
return this.error.status;
}
missingResourceMessage() {
const resource = this.error.resource;
return `${resource} does not exist.`;
hasErrorWithCode(code) {
return this.githubErrors.some((err) => err.code == code);
}
missingFieldMessage() {
const resource = this.error.resource;
const field = this.error.field;
return `The ${field} field on ${resource} is missing.`;
toString() {
const message = this.error.message;
const errors = this.githubErrors;
const status = this.status;
if (errors.length > 0) {
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`;
}
else {
return `Error ${status}: ${message}`;
}
}
resourceAlreadyExists() {
const resource = this.error.resource;
return `${resource} already exists.`;
errorBulletedList(errors) {
return errors.map((err) => `- ${err}`).join("\n");
}
}
exports.GithubError = GithubError;

57
lib/GithubErrorDetail.js Normal file
View File

@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubErrorDetail = void 0;
class GithubErrorDetail {
constructor(error) {
this.error = error;
}
get code() {
return this.error.code;
}
toString() {
const code = this.error.code;
switch (code) {
case 'missing':
return this.missingResourceMessage();
case 'missing_field':
return this.missingFieldMessage();
case 'invalid':
return this.invalidFieldMessage();
case 'already_exists':
return this.resourceAlreadyExists();
default:
return this.customErrorMessage();
}
}
customErrorMessage() {
const message = this.error.message;
const documentation = this.error.documentation_url;
let documentationMessage;
if (documentation) {
documentationMessage = `\nPlease see ${documentation}.`;
}
else {
documentationMessage = "";
}
return `${message}${documentationMessage}`;
}
invalidFieldMessage() {
const resource = this.error.resource;
const field = this.error.field;
return `The ${field} field on ${resource} is an invalid format.`;
}
missingResourceMessage() {
const resource = this.error.resource;
return `${resource} does not exist.`;
}
missingFieldMessage() {
const resource = this.error.resource;
const field = this.error.field;
return `The ${field} field on ${resource} is missing.`;
}
resourceAlreadyExists() {
const resource = this.error.resource;
return `${resource} already exists.`;
}
}
exports.GithubErrorDetail = GithubErrorDetail;

View File

@@ -1,7 +1,11 @@
"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]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
@@ -14,7 +18,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
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);
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
@@ -42,17 +46,13 @@ class CoreInputs {
contentType = 'raw';
}
return this.artifactGlobber
.globArtifactString(artifacts, contentType);
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild);
}
return [];
}
get createdReleaseBody() {
if (CoreInputs.omitBody)
return undefined;
return this.body;
}
static get omitBody() {
return core.getInput('omitBody') == 'true';
get artifactErrorsFailBuild() {
const allow = core.getInput('artifactErrorsFailBuild');
return allow == 'true';
}
get body() {
const body = core.getInput('body');
@@ -65,8 +65,21 @@ class CoreInputs {
}
return '';
}
get commit() {
return core.getInput('commit');
get createdDraft() {
const draft = core.getInput('draft');
return draft == 'true';
}
get createdPrerelease() {
const preRelease = core.getInput('prerelease');
return preRelease == 'true';
}
get createdReleaseBody() {
if (CoreInputs.omitBody)
return undefined;
return this.body;
}
static get omitBody() {
return core.getInput('omitBody') == 'true';
}
get createdReleaseName() {
if (CoreInputs.omitName)
@@ -76,6 +89,20 @@ class CoreInputs {
static get omitName() {
return core.getInput('omitName') == 'true';
}
get commit() {
const commit = core.getInput('commit');
if (commit) {
return commit;
}
return undefined;
}
get discussionCategory() {
const category = core.getInput('discussionCategory');
if (category) {
return category;
}
return undefined;
}
get name() {
const name = core.getInput('name');
if (name) {
@@ -83,18 +110,32 @@ class CoreInputs {
}
return this.tag;
}
get draft() {
const draft = core.getInput('draft');
return draft == 'true';
get generateReleaseNotes() {
const generate = core.getInput('generateReleaseNotes');
return generate == 'true';
}
get prerelease() {
const preRelease = core.getInput('prerelease');
return preRelease == 'true';
get owner() {
let owner = core.getInput('owner');
if (owner) {
return owner;
}
return this.context.repo.owner;
}
get removeArtifacts() {
const removes = core.getInput('removeArtifacts');
return removes == 'true';
}
get replacesArtifacts() {
const replaces = core.getInput('replacesArtifacts');
return replaces == 'true';
}
get repo() {
let repo = core.getInput('repo');
if (repo) {
return repo;
}
return this.context.repo.repo;
}
get tag() {
const tag = core.getInput('tag');
if (tag) {
@@ -110,6 +151,22 @@ class CoreInputs {
get token() {
return core.getInput('token', { required: true });
}
get updatedDraft() {
if (CoreInputs.omitDraftDuringUpdate)
return undefined;
return this.createdDraft;
}
static get omitDraftDuringUpdate() {
return core.getInput('omitDraftDuringUpdate') == 'true';
}
get updatedPrerelease() {
if (CoreInputs.omitPrereleaseDuringUpdate)
return undefined;
return this.createdPrerelease;
}
static get omitPrereleaseDuringUpdate() {
return core.getInput('omitPrereleaseDuringUpdate') == 'true';
}
get updatedReleaseBody() {
if (CoreInputs.omitBody || CoreInputs.omitBodyDuringUpdate)
return undefined;
@@ -127,7 +184,7 @@ class CoreInputs {
return core.getInput('omitNameDuringUpdate') == 'true';
}
stringFromFile(path) {
return fs_1.readFileSync(path, 'utf-8');
return (0, fs_1.readFileSync)(path, 'utf-8');
}
}
exports.CoreInputs = CoreInputs;

View File

@@ -1,7 +1,11 @@
"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]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
@@ -14,10 +18,19 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
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);
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.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) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const github = __importStar(require("@actions/github"));
const core = __importStar(require("@actions/core"));
@@ -26,16 +39,20 @@ const Releases_1 = require("./Releases");
const Action_1 = require("./Action");
const ArtifactUploader_1 = require("./ArtifactUploader");
const ArtifactGlobber_1 = require("./ArtifactGlobber");
const ErrorMessage_1 = require("./ErrorMessage");
async function run() {
try {
const action = createAction();
await action.perform();
}
catch (error) {
const errorMessage = new ErrorMessage_1.ErrorMessage(error);
core.setFailed(errorMessage.toString());
}
const GithubError_1 = require("./GithubError");
const Outputs_1 = require("./Outputs");
const ArtifactDestroyer_1 = require("./ArtifactDestroyer");
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const action = createAction();
yield action.perform();
}
catch (error) {
const githubError = new GithubError_1.GithubError(error);
core.setFailed(githubError.toString());
}
});
}
function createAction() {
const token = core.getInput('token');
@@ -43,8 +60,10 @@ function createAction() {
const git = github.getOctokit(token);
const globber = new ArtifactGlobber_1.FileArtifactGlobber();
const inputs = new Inputs_1.CoreInputs(globber, context);
const releases = new Releases_1.GithubReleases(context, git);
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts);
return new Action_1.Action(inputs, releases, uploader);
const outputs = new Outputs_1.CoreOutputs();
const releases = new Releases_1.GithubReleases(inputs, git);
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild);
const artifactDestroyer = new ArtifactDestroyer_1.GithubArtifactDestroyer(releases);
return new Action_1.Action(inputs, outputs, releases, uploader, artifactDestroyer);
}
run();

35
lib/Outputs.js Normal file
View File

@@ -0,0 +1,35 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CoreOutputs = void 0;
const core = __importStar(require("@actions/core"));
class CoreOutputs {
applyReleaseData(releaseData) {
core.setOutput('id', releaseData.id);
core.setOutput('html_url', releaseData.html_url);
core.setOutput('upload_url', releaseData.upload_url);
}
}
exports.CoreOutputs = CoreOutputs;

View File

@@ -1,77 +1,103 @@
"use strict";
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) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubReleases = void 0;
class GithubReleases {
constructor(context, git) {
this.context = context;
constructor(inputs, git) {
this.inputs = inputs;
this.git = git;
}
async create(tag, body, commitHash, draft, name, prerelease) {
// noinspection TypeScriptValidateJSTypes
return this.git.repos.createRelease({
body: body,
name: name,
draft: draft,
owner: this.context.repo.owner,
prerelease: prerelease,
repo: this.context.repo.repo,
target_commitish: commitHash,
tag_name: tag
create(tag, body, commitHash, discussionCategory, draft, generateReleaseNotes, name, prerelease) {
return __awaiter(this, void 0, void 0, function* () {
// noinspection TypeScriptValidateJSTypes
return this.git.rest.repos.createRelease({
body: body,
name: name,
discussion_category_name: discussionCategory,
draft: draft,
generate_release_notes: generateReleaseNotes,
owner: this.inputs.owner,
prerelease: prerelease,
repo: this.inputs.repo,
target_commitish: commitHash,
tag_name: tag
});
});
}
async deleteArtifact(assetId) {
return this.git.repos.deleteReleaseAsset({
asset_id: assetId,
owner: this.context.repo.owner,
repo: this.context.repo.repo
deleteArtifact(assetId) {
return __awaiter(this, void 0, void 0, function* () {
return this.git.rest.repos.deleteReleaseAsset({
asset_id: assetId,
owner: this.inputs.owner,
repo: this.inputs.repo
});
});
}
async listArtifactsForRelease(releaseId) {
return this.git.repos.listReleaseAssets({
owner: this.context.repo.owner,
release_id: releaseId,
repo: this.context.repo.repo
getByTag(tag) {
return __awaiter(this, void 0, void 0, function* () {
return this.git.rest.repos.getReleaseByTag({
owner: this.inputs.owner,
repo: this.inputs.repo,
tag: tag
});
});
}
async listReleases() {
return this.git.repos.listReleases({
owner: this.context.repo.owner,
repo: this.context.repo.repo
listArtifactsForRelease(releaseId) {
return __awaiter(this, void 0, void 0, function* () {
return this.git.paginate(this.git.rest.repos.listReleaseAssets, {
owner: this.inputs.owner,
release_id: releaseId,
repo: this.inputs.repo
});
});
}
async getByTag(tag) {
return this.git.repos.getReleaseByTag({
owner: this.context.repo.owner,
repo: this.context.repo.repo,
tag: tag
listReleases() {
return __awaiter(this, void 0, void 0, function* () {
return this.git.rest.repos.listReleases({
owner: this.inputs.owner,
repo: this.inputs.repo
});
});
}
async update(id, tag, body, commitHash, draft, name, prerelease) {
// noinspection TypeScriptValidateJSTypes
return this.git.repos.updateRelease({
release_id: id,
body: body,
name: name,
draft: draft,
owner: this.context.repo.owner,
prerelease: prerelease,
repo: this.context.repo.repo,
target_commitish: commitHash,
tag_name: tag
update(id, tag, body, commitHash, discussionCategory, draft, name, prerelease) {
return __awaiter(this, void 0, void 0, function* () {
// noinspection TypeScriptValidateJSTypes
return this.git.rest.repos.updateRelease({
release_id: id,
body: body,
name: name,
discussion_category_name: discussionCategory,
draft: draft,
owner: this.inputs.owner,
prerelease: prerelease,
repo: this.inputs.repo,
target_commitish: commitHash,
tag_name: tag
});
});
}
async uploadArtifact(assetUrl, contentLength, contentType, file, name, releaseId) {
return this.git.repos.uploadReleaseAsset({
url: assetUrl,
headers: {
"content-length": contentLength,
"content-type": contentType
},
data: file,
name: name,
owner: this.context.repo.owner,
release_id: releaseId,
repo: this.context.repo.repo
uploadArtifact(assetUrl, contentLength, contentType, file, name, releaseId) {
return __awaiter(this, void 0, void 0, function* () {
return this.git.rest.repos.uploadReleaseAsset({
url: assetUrl,
headers: {
"content-length": contentLength,
"content-type": contentType
},
data: file,
name: name,
owner: this.inputs.owner,
release_id: releaseId,
repo: this.inputs.repo
});
});
}
}

View File

@@ -7,8 +7,10 @@
"scripts": {
"build": "tsc",
"clean": "rm -rf lib/*",
"debug": "yarn clean && yarn install && yarn build",
"release": "yarn clean && yarn install --production && yarn build",
"coverage": "jest --coverage",
"debug": "yarn clean && yarn install && yarn build && yarn package",
"package": "ncc build --source-map --license licenses.txt",
"release": "yarn clean && yarn install --production && yarn build && yarn package",
"test": "jest"
},
"repository": {
@@ -23,19 +25,18 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/github": "^4.0.0",
"add": "^2.0.6",
"glob": "^7.1.4",
"global": "^4.4.0"
"@actions/core": "^1.6.0",
"@actions/github": "^5.0.0",
"@types/glob": "^7.2.0",
"glob": "^7.2.0",
"untildify": "^4.0.0"
},
"devDependencies": {
"@types/glob": "^7.1.1",
"@types/node": "^12.0.4",
"@types/jest": "^26.0.5",
"jest": "^26.1.0",
"jest-circus": "^26.1.0",
"ts-jest": "^26.1.3",
"typescript": "^3.9.7"
"@types/jest": "^27.4.0",
"@types/node": "^17.0.21",
"jest": "^27.5.1",
"jest-circus": "^27.5.1",
"ts-jest": "^27.1.3",
"typescript": "^4.6.3"
}
}

View File

@@ -1,68 +1,95 @@
import { Inputs } from "./Inputs";
import { Releases } from "./Releases";
import { ReposCreateReleaseResponseData } from "@octokit/types";
import { ArtifactUploader } from "./ArtifactUploader";
import { ErrorMessage } from "./ErrorMessage";
import {Inputs} from "./Inputs";
import {
CreateOrUpdateReleaseResponse,
CreateReleaseResponse,
ReleaseByTagResponse,
Releases,
UpdateReleaseResponse
} from "./Releases";
import {ArtifactUploader} from "./ArtifactUploader";
import {GithubError} from "./GithubError";
import {Outputs} from "./Outputs";
import {ArtifactDestroyer} from "./ArtifactDestroyer";
export class Action {
private inputs: Inputs
private outputs: Outputs
private releases: Releases
private artifactDestroyer: ArtifactDestroyer
private uploader: ArtifactUploader
constructor(inputs: Inputs, releases: Releases, uploader: ArtifactUploader) {
constructor(inputs: Inputs,
outputs: Outputs,
releases: Releases,
uploader: ArtifactUploader,
artifactDestroyer: ArtifactDestroyer) {
this.inputs = inputs
this.outputs = outputs
this.releases = releases
this.uploader = uploader
this.artifactDestroyer = artifactDestroyer
}
async perform() {
const releaseResponse = await this.createOrUpdateRelease();
const releaseId = releaseResponse.id
const uploadUrl = releaseResponse.upload_url
const releaseData = releaseResponse.data
const releaseId = releaseData.id
const uploadUrl = releaseData.upload_url
if (this.inputs.removeArtifacts) {
await this.artifactDestroyer.destroyArtifacts(releaseId)
}
const artifacts = this.inputs.artifacts
if (artifacts.length > 0) {
await this.uploader.uploadArtifacts(artifacts, releaseId, uploadUrl)
}
this.outputs.applyReleaseData(releaseData)
}
private async createOrUpdateRelease(): Promise<ReposCreateReleaseResponseData> {
private async createOrUpdateRelease(): Promise<CreateOrUpdateReleaseResponse> {
if (this.inputs.allowUpdates) {
let getResponse: ReleaseByTagResponse
try {
const getResponse = await this.releases.getByTag(this.inputs.tag)
return await this.updateRelease(getResponse.data.id)
} catch (error) {
if (Action.noPublishedRelease(error)) {
return await this.updateDraftOrCreateRelease()
} else {
throw error
}
getResponse = await this.releases.getByTag(this.inputs.tag)
} catch (error: any) {
return await this.checkForMissingReleaseError(error)
}
return await this.updateRelease(getResponse.data.id)
} else {
return await this.createRelease()
}
}
private async updateRelease(id: number): Promise<ReposCreateReleaseResponseData> {
const response = await this.releases.update(
private async checkForMissingReleaseError(error: Error): Promise<CreateOrUpdateReleaseResponse> {
if (Action.noPublishedRelease(error)) {
return await this.updateDraftOrCreateRelease()
} else {
throw error
}
}
private async updateRelease(id: number): Promise<UpdateReleaseResponse> {
return await this.releases.update(
id,
this.inputs.tag,
this.inputs.updatedReleaseBody,
this.inputs.commit,
this.inputs.draft,
this.inputs.discussionCategory,
this.inputs.updatedDraft,
this.inputs.updatedReleaseName,
this.inputs.prerelease
this.inputs.updatedPrerelease
)
return response.data
}
private static noPublishedRelease(error: any): boolean {
const errorMessage = new ErrorMessage(error)
return errorMessage.status == 404
const githubError = new GithubError(error)
return githubError.status == 404
}
private async updateDraftOrCreateRelease(): Promise<ReposCreateReleaseResponseData> {
private async updateDraftOrCreateRelease(): Promise<CreateReleaseResponse | UpdateReleaseResponse> {
const draftReleaseId = await this.findMatchingDraftReleaseId()
if (draftReleaseId) {
return await this.updateRelease(draftReleaseId)
@@ -80,16 +107,16 @@ export class Action {
return draftRelease?.id
}
private async createRelease(): Promise<ReposCreateReleaseResponseData> {
const response = await this.releases.create(
private async createRelease(): Promise<CreateReleaseResponse> {
return await this.releases.create(
this.inputs.tag,
this.inputs.createdReleaseBody,
this.inputs.commit,
this.inputs.draft,
this.inputs.discussionCategory,
this.inputs.createdDraft,
this.inputs.generateReleaseNotes,
this.inputs.createdReleaseName,
this.inputs.prerelease
this.inputs.createdPrerelease
)
return response.data
}
}

20
src/ArtifactDestroyer.ts Normal file
View File

@@ -0,0 +1,20 @@
import {Releases} from "./Releases";
import * as core from "@actions/core";
export interface ArtifactDestroyer {
destroyArtifacts(releaseId: number): Promise<void>
}
export class GithubArtifactDestroyer implements ArtifactDestroyer {
constructor(private releases: Releases) {
}
async destroyArtifacts(releaseId: number): Promise<void> {
const releaseAssets = await this.releases.listArtifactsForRelease(releaseId)
for (const artifact of releaseAssets) {
const asset = artifact
core.debug(`Deleting existing artifact ${artifact.name}...`)
await this.releases.deleteArtifact(asset.id)
}
}
}

View File

@@ -1,8 +1,11 @@
import { Globber, FileGlobber } from "./Globber";
import { Artifact } from "./Artifact";
import * as core from '@actions/core';
import {Globber, FileGlobber} from "./Globber";
import {Artifact} from "./Artifact";
import untildify from "untildify";
import {ArtifactPathValidator} from "./ArtifactPathValidator";
export interface ArtifactGlobber {
globArtifactString(artifact: string, contentType: string): Artifact[]
globArtifactString(artifact: string, contentType: string, errorsFailBuild: boolean): Artifact[]
}
export class FileArtifactGlobber implements ArtifactGlobber {
@@ -12,11 +15,43 @@ export class FileArtifactGlobber implements ArtifactGlobber {
this.globber = globber
}
globArtifactString(artifact: string, contentType: string): Artifact[] {
return artifact.split(',')
.map((path) => this.globber.glob(path))
globArtifactString(artifact: string, contentType: string, errorsFailBuild: boolean): Artifact[] {
const split = /[,\n]/
return artifact.split(split)
.map(path => path.trimStart())
.map(path => FileArtifactGlobber.expandPath(path))
.map(pattern => this.globPattern(pattern, errorsFailBuild))
.map((globResult) => FileArtifactGlobber.validatePattern(errorsFailBuild, globResult[1], globResult[0]))
.reduce((accumulated, current) => accumulated.concat(current))
.map((path) => new Artifact(path, contentType))
.map(path => new Artifact(path, contentType))
}
}
private globPattern(pattern: string, errorsFailBuild: boolean): [string, string[]] {
const paths = this.globber.glob(pattern)
if (paths.length == 0) {
if (errorsFailBuild) {
FileArtifactGlobber.throwGlobError(pattern)
} else {
FileArtifactGlobber.reportGlobWarning(pattern)
}
}
return [pattern, paths]
}
private static validatePattern(errorsFailBuild: boolean, paths: string[], pattern: string): string[] {
const validator = new ArtifactPathValidator(errorsFailBuild, paths, pattern)
return validator.validate()
}
private static reportGlobWarning(pattern: string) {
core.warning(`Artifact pattern :${pattern} did not match any files`)
}
private static throwGlobError(pattern: string) {
throw Error(`Artifact pattern :${pattern} did not match any files`)
}
private static expandPath(path: string): string {
return untildify(path)
}
}

View File

@@ -0,0 +1,43 @@
import * as core from "@actions/core";
import {statSync} from "fs";
export class ArtifactPathValidator {
private readonly errorsFailBuild: boolean;
private paths: string[];
private readonly pattern: string
constructor(errorsFailBuild: boolean, paths: string[], pattern: string) {
this.paths = paths;
this.pattern = pattern
this.errorsFailBuild = errorsFailBuild;
}
validate(): string[] {
this.verifyPathsNotEmpty()
return this.paths.filter((path) => this.verifyNotDirectory(path))
}
private verifyPathsNotEmpty() {
if (this.paths.length == 0) {
const message = `Artifact pattern:${this.pattern} did not match any files`
this.reportError(message)
}
}
private verifyNotDirectory(path: string): boolean {
const isDir = statSync(path).isDirectory()
if (isDir) {
const message = `Artifact is a directory:${path}. Directories can not be uploaded to a release.`
this.reportError(message)
}
return !isDir
}
private reportError(message: string) {
if (this.errorsFailBuild) {
throw Error(message)
} else {
core.warning(message)
}
}
}

View File

@@ -10,6 +10,7 @@ export class GithubArtifactUploader implements ArtifactUploader {
constructor(
private releases: Releases,
private replacesExistingArtifacts: boolean = true,
private throwsUploadErrors: boolean = false,
) {
}
@@ -36,19 +37,22 @@ export class GithubArtifactUploader implements ArtifactUploader {
artifact.readFile(),
artifact.name,
releaseId)
} catch (error) {
} catch (error: any) {
if (error.status >= 500 && retry > 0) {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}. Retrying...`)
await this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1)
} else {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
if (this.throwsUploadErrors) {
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
} else {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
}
}
}
}
private async deleteUpdatedArtifacts(artifacts: Artifact[], releaseId: number): Promise<void> {
const response = await this.releases.listArtifactsForRelease(releaseId)
const releaseAssets = response.data
const releaseAssets = await this.releases.listArtifactsForRelease(releaseId)
const assetByName: Record<string, { id: number; name: string }> = {}
releaseAssets.forEach(asset => {
assetByName[asset.name] = asset

View File

@@ -1,44 +0,0 @@
import {GithubError} from "./GithubError"
export class ErrorMessage {
private error: any
private githubErrors: GithubError[]
constructor(error: any) {
this.error = error
this.githubErrors = this.generateGithubErrors()
}
private generateGithubErrors(): GithubError[] {
const errors = this.error.errors
if (errors instanceof Array) {
return errors.map((err) => new GithubError(err))
} else {
return []
}
}
get status(): number {
return this.error.status
}
hasErrorWithCode(code: String): boolean {
return this.githubErrors.some((err) => err.code == code)
}
toString(): string {
const message = this.error.message
const errors = this.githubErrors
const status = this.status
if (errors.length > 0) {
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`
} else {
return `Error ${status}: ${message}`
}
}
private errorBulletedList(errors: GithubError[]): string {
return errors.map((err) => `- ${err}`).join("\n")
}
}

View File

@@ -1,65 +1,44 @@
import {GithubErrorDetail} from "./GithubErrorDetail"
export class GithubError {
private error: any;
private error: any
private readonly githubErrors: GithubErrorDetail[]
constructor(error: any) {
this.error = error
this.githubErrors = this.generateGithubErrors()
}
get code(): string {
return this.error.code
private generateGithubErrors(): GithubErrorDetail[] {
const errors = this.error.errors
if (errors instanceof Array) {
return errors.map((err) => new GithubErrorDetail(err))
} else {
return []
}
}
get status(): number {
return this.error.status
}
hasErrorWithCode(code: String): boolean {
return this.githubErrors.some((err) => err.code == code)
}
toString(): string {
const code = this.error.code
switch (code) {
case 'missing':
return this.missingResourceMessage()
case 'missing_field':
return this.missingFieldMessage()
case 'invalid':
return this.invalidFieldMessage()
case 'already_exists':
return this.resourceAlreadyExists()
default:
return this.customErrorMessage()
}
}
private customErrorMessage(): string {
const message = this.error.message;
const documentation = this.error.documentation_url
let documentationMessage: string
if (documentation) {
documentationMessage = `\nPlease see ${documentation}.`
const message = this.error.message
const errors = this.githubErrors
const status = this.status
if (errors.length > 0) {
return `Error ${status}: ${message}\nErrors:\n${this.errorBulletedList(errors)}`
} else {
documentationMessage = ""
return `Error ${status}: ${message}`
}
return `${message}${documentationMessage}`
}
private invalidFieldMessage(): string {
const resource = this.error.resource
const field = this.error.field
return `The ${field} field on ${resource} is an invalid format.`
}
private missingResourceMessage(): string {
const resource = this.error.resource
return `${resource} does not exist.`
}
private missingFieldMessage(): string {
const resource = this.error.resource
const field = this.error.field
return `The ${field} field on ${resource} is missing.`
}
private resourceAlreadyExists(): string {
const resource = this.error.resource
return `${resource} already exists.`
private errorBulletedList(errors: GithubErrorDetail[]): string {
return errors.map((err) => `- ${err}`).join("\n")
}
}

65
src/GithubErrorDetail.ts Normal file
View File

@@ -0,0 +1,65 @@
export class GithubErrorDetail {
private error: any;
constructor(error: any) {
this.error = error
}
get code(): string {
return this.error.code
}
toString(): string {
const code = this.error.code
switch (code) {
case 'missing':
return this.missingResourceMessage()
case 'missing_field':
return this.missingFieldMessage()
case 'invalid':
return this.invalidFieldMessage()
case 'already_exists':
return this.resourceAlreadyExists()
default:
return this.customErrorMessage()
}
}
private customErrorMessage(): string {
const message = this.error.message;
const documentation = this.error.documentation_url
let documentationMessage: string
if (documentation) {
documentationMessage = `\nPlease see ${documentation}.`
} else {
documentationMessage = ""
}
return `${message}${documentationMessage}`
}
private invalidFieldMessage(): string {
const resource = this.error.resource
const field = this.error.field
return `The ${field} field on ${resource} is an invalid format.`
}
private missingResourceMessage(): string {
const resource = this.error.resource
return `${resource} does not exist.`
}
private missingFieldMessage(): string {
const resource = this.error.resource
const field = this.error.field
return `The ${field} field on ${resource} is missing.`
}
private resourceAlreadyExists(): string {
const resource = this.error.resource
return `${resource} already exists.`
}
}

View File

@@ -6,17 +6,25 @@ import {Artifact} from './Artifact';
export interface Inputs {
readonly allowUpdates: boolean
readonly artifactErrorsFailBuild: boolean
readonly artifacts: Artifact[]
readonly commit: string
readonly commit?: string
readonly createdDraft: boolean
readonly createdPrerelease: boolean
readonly createdReleaseBody?: string
readonly createdReleaseName?: string
readonly draft: boolean
readonly prerelease: boolean
readonly discussionCategory?: string
readonly generateReleaseNotes: boolean
readonly owner: string
readonly removeArtifacts: boolean
readonly replacesArtifacts: boolean
readonly repo: string
readonly tag: string
readonly token: string
readonly updatedDraft?: boolean
readonly updatedReleaseBody?: string
readonly updatedReleaseName?: string
readonly updatedPrerelease?: boolean
}
export class CoreInputs implements Inputs {
@@ -44,21 +52,17 @@ export class CoreInputs implements Inputs {
contentType = 'raw'
}
return this.artifactGlobber
.globArtifactString(artifacts, contentType)
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild)
}
return []
}
get createdReleaseBody(): string | undefined {
if (CoreInputs.omitBody) return undefined
return this.body
get artifactErrorsFailBuild(): boolean {
const allow = core.getInput('artifactErrorsFailBuild')
return allow == 'true'
}
private static get omitBody(): boolean {
return core.getInput('omitBody') == 'true'
}
private get body() : string | undefined {
private get body(): string | undefined {
const body = core.getInput('body')
if (body) {
return body
@@ -72,8 +76,23 @@ export class CoreInputs implements Inputs {
return ''
}
get commit(): string {
return core.getInput('commit')
get createdDraft(): boolean {
const draft = core.getInput('draft')
return draft == 'true'
}
get createdPrerelease(): boolean {
const preRelease = core.getInput('prerelease')
return preRelease == 'true'
}
get createdReleaseBody(): string | undefined {
if (CoreInputs.omitBody) return undefined
return this.body
}
private static get omitBody(): boolean {
return core.getInput('omitBody') == 'true'
}
get createdReleaseName(): string | undefined {
@@ -85,6 +104,22 @@ export class CoreInputs implements Inputs {
return core.getInput('omitName') == 'true'
}
get commit(): string | undefined {
const commit = core.getInput('commit')
if (commit) {
return commit
}
return undefined
}
get discussionCategory(): string | undefined {
const category = core.getInput('discussionCategory')
if (category) {
return category
}
return undefined
}
private get name(): string | undefined {
const name = core.getInput('name')
if (name) {
@@ -93,22 +128,37 @@ export class CoreInputs implements Inputs {
return this.tag
}
get draft(): boolean {
const draft = core.getInput('draft')
return draft == 'true'
get generateReleaseNotes(): boolean {
const generate = core.getInput('generateReleaseNotes')
return generate == 'true'
}
get prerelease(): boolean {
const preRelease = core.getInput('prerelease')
return preRelease == 'true'
get owner(): string {
let owner = core.getInput('owner')
if (owner) {
return owner
}
return this.context.repo.owner
}
get removeArtifacts(): boolean {
const removes = core.getInput('removeArtifacts')
return removes == 'true'
}
get replacesArtifacts(): boolean {
const replaces = core.getInput('replacesArtifacts')
return replaces == 'true'
}
get repo(): string {
let repo = core.getInput('repo')
if (repo) {
return repo
}
return this.context.repo.repo
}
get tag(): string {
const tag = core.getInput('tag')
if (tag) {
@@ -128,6 +178,24 @@ export class CoreInputs implements Inputs {
return core.getInput('token', {required: true})
}
get updatedDraft(): boolean | undefined {
if (CoreInputs.omitDraftDuringUpdate) return undefined
return this.createdDraft
}
private static get omitDraftDuringUpdate(): boolean {
return core.getInput('omitDraftDuringUpdate') == 'true'
}
get updatedPrerelease(): boolean | undefined {
if (CoreInputs.omitPrereleaseDuringUpdate) return undefined
return this.createdPrerelease
}
private static get omitPrereleaseDuringUpdate(): boolean {
return core.getInput('omitPrereleaseDuringUpdate') == 'true'
}
get updatedReleaseBody(): string | undefined {
if (CoreInputs.omitBody || CoreInputs.omitBodyDuringUpdate) return undefined
return this.body
@@ -138,7 +206,7 @@ export class CoreInputs implements Inputs {
}
get updatedReleaseName(): string | undefined {
if (CoreInputs.omitName || CoreInputs.omitNameDuringUpdate) return undefined
if (CoreInputs.omitName || CoreInputs.omitNameDuringUpdate) return undefined
return this.name
}

View File

@@ -1,32 +1,37 @@
import * as github from '@actions/github';
import * as core from '@actions/core';
import { CoreInputs } from './Inputs';
import { GithubReleases } from './Releases';
import { Action } from './Action';
import { GithubArtifactUploader } from './ArtifactUploader';
import { FileArtifactGlobber } from './ArtifactGlobber';
import { ErrorMessage } from './ErrorMessage';
import {CoreInputs} from './Inputs';
import {GithubReleases} from './Releases';
import {Action} from './Action';
import {GithubArtifactUploader} from './ArtifactUploader';
import {FileArtifactGlobber} from './ArtifactGlobber';
import {GithubError} from './GithubError';
import {CoreOutputs} from "./Outputs";
import {GithubArtifactDestroyer} from "./ArtifactDestroyer";
async function run() {
try {
const action = createAction()
await action.perform()
} catch (error) {
const errorMessage = new ErrorMessage(error)
core.setFailed(errorMessage.toString());
}
try {
const action = createAction()
await action.perform()
} catch (error) {
const githubError = new GithubError(error)
core.setFailed(githubError.toString());
}
}
function createAction(): Action {
const token = core.getInput('token')
const context = github.context
const git = github.getOctokit(token)
const globber = new FileArtifactGlobber()
const token = core.getInput('token')
const context = github.context
const git = github.getOctokit(token)
const globber = new FileArtifactGlobber()
const inputs = new CoreInputs(globber, context)
const releases = new GithubReleases(context, git)
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts)
return new Action(inputs, releases, uploader)
const inputs = new CoreInputs(globber, context)
const outputs = new CoreOutputs()
const releases = new GithubReleases(inputs, git)
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild)
const artifactDestroyer = new GithubArtifactDestroyer(releases)
return new Action(inputs, outputs, releases, uploader, artifactDestroyer)
}
run();

14
src/Outputs.ts Normal file
View File

@@ -0,0 +1,14 @@
import * as core from '@actions/core';
import {ReleaseData} from "./Releases";
export interface Outputs {
applyReleaseData(releaseData: ReleaseData): void
}
export class CoreOutputs implements Outputs {
applyReleaseData(releaseData: ReleaseData) {
core.setOutput('id', releaseData.id)
core.setOutput('html_url', releaseData.html_url)
core.setOutput('upload_url', releaseData.upload_url)
}
}

View File

@@ -1,41 +1,52 @@
import {Context} from "@actions/github/lib/context";
import { GitHub } from '@actions/github/lib/utils'
import {
OctokitResponse,
ReposListReleaseAssetsResponseData,
ReposCreateReleaseResponseData,
ReposGetReleaseByTagResponseData,
ReposListReleasesResponseData,
ReposUploadReleaseAssetResponseData
} from "@octokit/types";
import {GitHub} from '@actions/github/lib/utils'
import {OctokitResponse} from "@octokit/types";
import {RestEndpointMethodTypes} from "@octokit/plugin-rest-endpoint-methods";
import {Inputs} from "./Inputs";
export type CreateReleaseResponse = RestEndpointMethodTypes["repos"]["createRelease"]["response"]
export type ReleaseByTagResponse = RestEndpointMethodTypes["repos"]["getReleaseByTag"]["response"]
export type ListReleasesResponse = RestEndpointMethodTypes["repos"]["listReleases"]["response"]
export type ListReleaseAssetsResponseData = RestEndpointMethodTypes["repos"]["listReleaseAssets"]["response"]["data"]
export type UpdateReleaseResponse = RestEndpointMethodTypes["repos"]["updateRelease"]["response"]
export type UploadArtifactResponse = RestEndpointMethodTypes["repos"]["uploadReleaseAsset"]["response"]
export type CreateOrUpdateReleaseResponse = CreateReleaseResponse | UpdateReleaseResponse
export type ReleaseData = {
id: number
html_url: string
upload_url: string
}
export interface Releases {
create(
tag: string,
body?: string,
commitHash?: string,
discussionCategory?: string,
draft?: boolean,
generateReleaseNotes?: boolean,
name?: string,
prerelease?: boolean
): Promise<OctokitResponse<ReposCreateReleaseResponseData>>
): Promise<CreateReleaseResponse>
deleteArtifact(assetId: number): Promise<OctokitResponse<any>>
getByTag(tag: string): Promise<OctokitResponse<ReposGetReleaseByTagResponseData>>
getByTag(tag: string): Promise<ReleaseByTagResponse>
listArtifactsForRelease(releaseId: number): Promise<OctokitResponse<ReposListReleaseAssetsResponseData>>
listArtifactsForRelease(releaseId: number): Promise<ListReleaseAssetsResponseData>
listReleases(): Promise<OctokitResponse<ReposListReleasesResponseData>>
listReleases(): Promise<ListReleasesResponse>
update(
id: number,
tag: string,
body?: string,
commitHash?: string,
discussionCategory?: string,
draft?: boolean,
name?: string,
prerelease?: boolean
): Promise<OctokitResponse<ReposCreateReleaseResponseData>>
): Promise<UpdateReleaseResponse>
uploadArtifact(
assetUrl: string,
@@ -44,15 +55,15 @@ export interface Releases {
file: string | object,
name: string,
releaseId: number,
): Promise<OctokitResponse<ReposUploadReleaseAssetResponseData>>
): Promise<UploadArtifactResponse>
}
export class GithubReleases implements Releases {
context: Context
git: InstanceType<typeof GitHub>
inputs: Inputs
constructor(context: Context, git: InstanceType<typeof GitHub>) {
this.context = context
constructor(inputs: Inputs, git: InstanceType<typeof GitHub>) {
this.inputs = inputs
this.git = git
}
@@ -60,18 +71,22 @@ export class GithubReleases implements Releases {
tag: string,
body?: string,
commitHash?: string,
discussionCategory?: string,
draft?: boolean,
generateReleaseNotes?: boolean,
name?: string,
prerelease?: boolean
): Promise<OctokitResponse<ReposCreateReleaseResponseData>> {
): Promise<CreateReleaseResponse> {
// noinspection TypeScriptValidateJSTypes
return this.git.repos.createRelease({
return this.git.rest.repos.createRelease({
body: body,
name: name,
discussion_category_name: discussionCategory,
draft: draft,
owner: this.context.repo.owner,
generate_release_notes: generateReleaseNotes,
owner: this.inputs.owner,
prerelease: prerelease,
repo: this.context.repo.repo,
repo: this.inputs.repo,
target_commitish: commitHash,
tag_name: tag
})
@@ -80,35 +95,35 @@ export class GithubReleases implements Releases {
async deleteArtifact(
assetId: number
): Promise<OctokitResponse<any>> {
return this.git.repos.deleteReleaseAsset({
return this.git.rest.repos.deleteReleaseAsset({
asset_id: assetId,
owner: this.context.repo.owner,
repo: this.context.repo.repo
owner: this.inputs.owner,
repo: this.inputs.repo
})
}
async getByTag(tag: string): Promise<ReleaseByTagResponse> {
return this.git.rest.repos.getReleaseByTag({
owner: this.inputs.owner,
repo: this.inputs.repo,
tag: tag
})
}
async listArtifactsForRelease(
releaseId: number
): Promise<OctokitResponse<ReposListReleaseAssetsResponseData>> {
return this.git.repos.listReleaseAssets({
owner: this.context.repo.owner,
): Promise<ListReleaseAssetsResponseData> {
return this.git.paginate(this.git.rest.repos.listReleaseAssets, {
owner: this.inputs.owner,
release_id: releaseId,
repo: this.context.repo.repo
repo: this.inputs.repo
})
}
async listReleases(): Promise<OctokitResponse<ReposListReleasesResponseData>> {
return this.git.repos.listReleases({
owner: this.context.repo.owner,
repo: this.context.repo.repo
})
}
async getByTag(tag: string): Promise<OctokitResponse<ReposGetReleaseByTagResponseData>> {
return this.git.repos.getReleaseByTag({
owner: this.context.repo.owner,
repo: this.context.repo.repo,
tag: tag
async listReleases(): Promise<ListReleasesResponse> {
return this.git.rest.repos.listReleases({
owner: this.inputs.owner,
repo: this.inputs.repo
})
}
@@ -117,19 +132,21 @@ export class GithubReleases implements Releases {
tag: string,
body?: string,
commitHash?: string,
discussionCategory?: string,
draft?: boolean,
name?: string,
prerelease?: boolean
): Promise<OctokitResponse<ReposCreateReleaseResponseData>> {
): Promise<UpdateReleaseResponse> {
// noinspection TypeScriptValidateJSTypes
return this.git.repos.updateRelease({
return this.git.rest.repos.updateRelease({
release_id: id,
body: body,
name: name,
discussion_category_name: discussionCategory,
draft: draft,
owner: this.context.repo.owner,
owner: this.inputs.owner,
prerelease: prerelease,
repo: this.context.repo.repo,
repo: this.inputs.repo,
target_commitish: commitHash,
tag_name: tag
})
@@ -142,8 +159,8 @@ export class GithubReleases implements Releases {
file: string | object,
name: string,
releaseId: number,
): Promise<OctokitResponse<ReposUploadReleaseAssetResponseData>> {
return this.git.repos.uploadReleaseAsset({
): Promise<UploadArtifactResponse> {
return this.git.rest.repos.uploadReleaseAsset({
url: assetUrl,
headers: {
"content-length": contentLength,
@@ -151,9 +168,9 @@ export class GithubReleases implements Releases {
},
data: file as any,
name: name,
owner: this.context.repo.owner,
owner: this.inputs.owner,
release_id: releaseId,
repo: this.context.repo.repo
repo: this.inputs.repo
})
}
}

View File

@@ -1,63 +1,13 @@
{
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"moduleResolution": "node",
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
},
"exclude": ["node_modules", "**/*.test.ts"]
}
}

3975
yarn.lock

File diff suppressed because it is too large Load Diff