22 Commits

Author SHA1 Message Date
Brian DeHamer
a63cfcc7d1 bump @actions/attest from 1.5.0 to 1.6.0 (#217)
* bump @actions/attest from 1.5.0 to 1.6.0

Signed-off-by: Brian DeHamer <bdehamer@github.com>

* pin superlinter to v7.2.1

Signed-off-by: Brian DeHamer <bdehamer@github.com>

---------

Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-02-26 10:41:20 -08:00
dependabot[bot]
516fe2247f Bump @octokit/plugin-paginate-rest from 9.1.5 to 9.2.2 (#215)
* Bump @octokit/plugin-paginate-rest from 9.1.5 to 9.2.2

Bumps [@octokit/plugin-paginate-rest](https://github.com/octokit/plugin-paginate-rest.js) from 9.1.5 to 9.2.2.
- [Release notes](https://github.com/octokit/plugin-paginate-rest.js/releases)
- [Commits](https://github.com/octokit/plugin-paginate-rest.js/compare/v9.1.5...v9.2.2)

---
updated-dependencies:
- dependency-name: "@octokit/plugin-paginate-rest"
  dependency-type: indirect
...

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

* rebuild dist

Signed-off-by: Brian DeHamer <bdehamer@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Brian DeHamer <bdehamer@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Brian DeHamer <bdehamer@github.com>
Co-authored-by: Eugene <108841108+ejahnGithub@users.noreply.github.com>
2025-02-26 10:14:40 -05:00
dependabot[bot]
90924a287f Bump the npm-development group with 6 updates (#216)
* Bump the npm-development group with 6 updates

Bumps the npm-development group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.20.0` | `9.21.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.13.4` | `22.13.5` |
| [eslint](https://github.com/eslint/eslint) | `9.20.1` | `9.21.0` |
| [prettier](https://github.com/prettier/prettier) | `3.5.1` | `3.5.2` |
| [ts-jest](https://github.com/kulshekhar/ts-jest) | `29.2.5` | `29.2.6` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.24.1` | `8.25.0` |


Updates `@eslint/js` from 9.20.0 to 9.21.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v9.21.0/packages/js)

Updates `@types/node` from 22.13.4 to 22.13.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint` from 9.20.1 to 9.21.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.20.1...v9.21.0)

Updates `prettier` from 3.5.1 to 3.5.2
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.5.1...3.5.2)

Updates `ts-jest` from 29.2.5 to 29.2.6
- [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/v29.2.5...v29.2.6)

Updates `typescript-eslint` from 8.24.1 to 8.25.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.25.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
...

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

* rebuild dist

Signed-off-by: Brian DeHamer <bdehamer@github.com>

* fix typos

Signed-off-by: Brian DeHamer <bdehamer@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Brian DeHamer <bdehamer@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Brian DeHamer <bdehamer@github.com>
2025-02-25 11:49:37 -08:00
dependabot[bot]
ec6754115e Bump @octokit/request-error from 5.0.1 to 5.1.1 (#212)
* Bump @octokit/request-error from 5.0.1 to 5.1.1

Bumps [@octokit/request-error](https://github.com/octokit/request-error.js) from 5.0.1 to 5.1.1.
- [Release notes](https://github.com/octokit/request-error.js/releases)
- [Commits](https://github.com/octokit/request-error.js/compare/v5.0.1...v5.1.1)

---
updated-dependencies:
- dependency-name: "@octokit/request-error"
  dependency-type: indirect
...

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

* update dist

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Eugene <108841108+ejahnGithub@users.noreply.github.com>
Co-authored-by: ejahnGithub <ejahngithub@github.com>
2025-02-24 16:52:09 -05:00
dependabot[bot]
921d2f1bf7 Bump the npm-development group across 1 directory with 6 updates (#214)
Bumps the npm-development group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.19.0` | `9.20.0` |
| [@sigstore/mock](https://github.com/sigstore/sigstore-js) | `0.9.0` | `0.10.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.13.0` | `22.13.4` |
| [eslint](https://github.com/eslint/eslint) | `9.19.0` | `9.20.1` |
| [prettier](https://github.com/prettier/prettier) | `3.4.2` | `3.5.1` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.23.0` | `8.24.1` |



Updates `@eslint/js` from 9.19.0 to 9.20.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v9.20.0/packages/js)

Updates `@sigstore/mock` from 0.9.0 to 0.10.0
- [Release notes](https://github.com/sigstore/sigstore-js/releases)
- [Commits](https://github.com/sigstore/sigstore-js/compare/@sigstore/mock@0.9.0...@sigstore/mock@0.10.0)

Updates `@types/node` from 22.13.0 to 22.13.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint` from 9.19.0 to 9.20.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.19.0...v9.20.1)

Updates `prettier` from 3.4.2 to 3.5.1
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.4.2...3.5.1)

Updates `typescript-eslint` from 8.23.0 to 8.24.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.24.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@sigstore/mock"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-18 10:46:43 -05:00
dependabot[bot]
3f97edb763 Bump the npm-development group with 2 updates (#209)
Bumps the npm-development group with 2 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@types/node` from 22.10.10 to 22.13.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `typescript-eslint` from 8.22.0 to 8.23.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.23.0/packages/typescript-eslint)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 15:25:03 -08:00
Brian DeHamer
3ccffae6dc bump undici from 5.28.4 to 5.28.5 (#208)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-01-28 08:16:51 -08:00
dependabot[bot]
d0c17db4ba Bump the npm-development group with 5 updates (#205)
Bumps the npm-development group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.18.0` | `9.19.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.10.7` | `22.10.10` |
| [eslint](https://github.com/eslint/eslint) | `9.18.0` | `9.19.0` |
| [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli) | `0.43.0` | `0.44.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.21.0` | `8.22.0` |


Updates `@eslint/js` from 9.18.0 to 9.19.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v9.19.0/packages/js)

Updates `@types/node` from 22.10.7 to 22.10.10
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint` from 9.18.0 to 9.19.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.18.0...v9.19.0)

Updates `markdownlint-cli` from 0.43.0 to 0.44.0
- [Release notes](https://github.com/igorshubovych/markdownlint-cli/releases)
- [Commits](https://github.com/igorshubovych/markdownlint-cli/compare/v0.43.0...v0.44.0)

Updates `typescript-eslint` from 8.21.0 to 8.22.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.22.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: markdownlint-cli
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-27 14:41:13 -08:00
Brian DeHamer
caa5c7e0da clarify plans supporting artifact attestations (#202)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-01-22 06:13:06 -08:00
Brian DeHamer
0fae568887 bump version from 2.1.0 to 2.2.0 (#201)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-01-21 10:39:42 -08:00
Brian DeHamer
38bcf9b1c5 New subject-checksums input param (#198)
* new subject-checksums input param

Signed-off-by: Brian DeHamer <bdehamer@github.com>

* check for valid hex string for digest

Signed-off-by: Brian DeHamer <bdehamer@github.com>

---------

Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-01-21 10:32:02 -08:00
dependabot[bot]
f03e04cc3f Bump the npm-development group with 3 updates (#199)
Bumps the npm-development group with 3 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@types/node` from 22.10.6 to 22.10.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint-plugin-jest` from 28.10.0 to 28.11.0
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.10.0...v28.11.0)

Updates `typescript-eslint` from 8.20.0 to 8.21.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.21.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 10:07:37 -08:00
dependabot[bot]
3fd15bdad4 Bump the npm-development group with 5 updates (#196)
Bumps the npm-development group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.17.0` | `9.18.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.10.5` | `22.10.6` |
| [eslint](https://github.com/eslint/eslint) | `9.17.0` | `9.18.0` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.7.2` | `5.7.3` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.19.1` | `8.20.0` |


Updates `@eslint/js` from 9.17.0 to 9.18.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v9.18.0/packages/js)

Updates `@types/node` from 22.10.5 to 22.10.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint` from 9.17.0 to 9.18.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.17.0...v9.18.0)

Updates `typescript` from 5.7.2 to 5.7.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.7.2...v5.7.3)

Updates `typescript-eslint` from 8.19.1 to 8.20.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.20.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 08:32:15 -08:00
dependabot[bot]
f642f6cafe Bump the npm-development group with 2 updates (#194)
Bumps the npm-development group with 2 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@types/node` from 22.10.2 to 22.10.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `typescript-eslint` from 8.19.0 to 8.19.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.19.1/packages/typescript-eslint)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-06 16:05:02 -08:00
dependabot[bot]
67164a6c7a Bump typescript-eslint in the npm-development group (#191)
Bumps the npm-development group with 1 update: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `typescript-eslint` from 8.18.2 to 8.19.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.19.0/packages/typescript-eslint)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-31 08:56:55 -08:00
dependabot[bot]
e6c7a2a1f2 Bump the npm-development group with 2 updates (#189)
Bumps the npm-development group with 2 updates: [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `eslint-plugin-jest` from 28.9.0 to 28.10.0
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.9.0...v28.10.0)

Updates `typescript-eslint` from 8.18.1 to 8.18.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.18.2/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-24 08:35:11 -08:00
dependabot[bot]
d8029d4690 Bump the npm-development group with 6 updates (#186)
* Bump the npm-development group with 6 updates

Bumps the npm-development group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.16.0` | `9.17.0` |
| [@sigstore/mock](https://github.com/sigstore/sigstore-js) | `0.8.0` | `0.9.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.9.4` | `22.10.2` |
| [eslint](https://github.com/eslint/eslint) | `9.16.0` | `9.17.0` |
| [prettier](https://github.com/prettier/prettier) | `3.3.3` | `3.4.2` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.18.0` | `8.18.1` |


Updates `@eslint/js` from 9.16.0 to 9.17.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v9.17.0/packages/js)

Updates `@sigstore/mock` from 0.8.0 to 0.9.0
- [Release notes](https://github.com/sigstore/sigstore-js/releases)
- [Commits](https://github.com/sigstore/sigstore-js/compare/@sigstore/mock@0.8.0...@sigstore/mock@0.9.0)

Updates `@types/node` from 22.9.4 to 22.10.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint` from 9.16.0 to 9.17.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.16.0...v9.17.0)

Updates `prettier` from 3.3.3 to 3.4.2
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.3...3.4.2)

Updates `typescript-eslint` from 8.18.0 to 8.18.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.18.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@sigstore/mock"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
...

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

* rebuild dist

Signed-off-by: Brian DeHamer <bdehamer@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Brian DeHamer <bdehamer@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Brian DeHamer <bdehamer@github.com>
2024-12-23 12:10:15 -08:00
Brian DeHamer
bfa7e6911b Update eslint from 8.x to 9.x (#185)
* remove eslint prettier plugins

Signed-off-by: Brian DeHamer <bdehamer@github.com>

* eslint upgrade

Signed-off-by: Brian DeHamer <bdehamer@github.com>

* source fixup

Signed-off-by: Brian DeHamer <bdehamer@github.com>

---------

Signed-off-by: Brian DeHamer <bdehamer@github.com>
2024-12-13 15:25:52 -08:00
Brian DeHamer
d94b522220 Fix docs for attestation-url output (#183)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2024-12-09 13:42:58 -08:00
Brian DeHamer
63d2e98e26 add note about gh plans supporting attestations (#182)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2024-12-09 10:46:52 -08:00
Brian DeHamer
94d0d43131 add attestation-id and attestation-url outputs (#181)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2024-12-09 09:56:33 -08:00
Brian DeHamer
65e34a8aa7 deduplicate subjects before adding to statement (#180)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2024-12-06 07:14:14 -08:00
15 changed files with 3306 additions and 3147 deletions

View File

@@ -1,4 +0,0 @@
lib/
dist/
node_modules/
coverage/

View File

@@ -1,84 +0,0 @@
env:
node: true
es6: true
jest: true
globals:
Atomics: readonly
SharedArrayBuffer: readonly
ignorePatterns:
- '!.*'
- '**/node_modules/.*'
- '**/dist/.*'
- '**/coverage/.*'
- '*.json'
parser: '@typescript-eslint/parser'
parserOptions:
ecmaVersion: 2023
sourceType: module
project:
- './.github/linters/tsconfig.json'
- './tsconfig.json'
plugins:
- jest
- '@typescript-eslint'
extends:
- eslint:recommended
- plugin:@typescript-eslint/eslint-recommended
- plugin:@typescript-eslint/recommended
- plugin:github/recommended
- plugin:jest/recommended
rules:
{
'camelcase': 'off',
'eslint-comments/no-use': 'off',
'eslint-comments/no-unused-disable': 'off',
'i18n-text/no-en': 'off',
'import/no-namespace': 'off',
'import/no-unresolved': ['error', { 'ignore': ['csv-parse/sync'] }],
'no-console': 'off',
'no-unused-vars': 'off',
'prettier/prettier': 'error',
'semi': 'off',
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-assertions': 'error',
'@typescript-eslint/explicit-member-accessibility':
['error', { 'accessibility': 'no-public' }],
'@typescript-eslint/explicit-function-return-type':
['error', { 'allowExpressions': true }],
'@typescript-eslint/func-call-spacing': ['error', 'never'],
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-empty-interface': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-for-in-array': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-unnecessary-qualifier': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-var-requires': 'error',
'@typescript-eslint/prefer-for-of': 'warn',
'@typescript-eslint/prefer-function-type': 'warn',
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
'@typescript-eslint/promise-function-async': 'error',
'@typescript-eslint/require-array-sort-compare': 'error',
'@typescript-eslint/restrict-plus-operands': 'error',
'@typescript-eslint/semi': ['error', 'never'],
'@typescript-eslint/space-before-function-paren': 'off',
'@typescript-eslint/type-annotation-spacing': 'error',
'@typescript-eslint/unbound-method': 'error'
}

93
.github/linters/eslint.config.mjs vendored Normal file
View File

@@ -0,0 +1,93 @@
import eslint from '@eslint/js'
import importplugin from 'eslint-plugin-import'
import jestplugin from 'eslint-plugin-jest'
import tseslint from 'typescript-eslint'
export default tseslint.config(
// Ignore non-project files
{
name: 'ignore',
ignores: ['.github', 'dist', 'coverage', '**/*.json', 'jest.setup.js']
},
// Use recommended rules from ESLint, TypeScript, and other plugins
eslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
jestplugin.configs['flat/recommended'],
importplugin.flatConfigs.recommended,
importplugin.flatConfigs.typescript,
// Override some rules
{
name: 'project-settings',
languageOptions: {
ecmaVersion: 2023,
parserOptions: {
project: ['./.github/linters/tsconfig.json', './tsconfig.json']
}
},
rules: {
// eslint rules
eqeqeq: ['error', 'smart'],
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': 'off',
'no-implicit-globals': 'error',
'no-inner-declarations': 'error',
'no-invalid-this': 'error',
'no-return-assign': 'error',
'no-sequences': 'error',
'no-shadow': 'error',
'no-useless-concat': 'error',
'object-shorthand': ['error', 'always', { avoidQuotes: true }],
'one-var': ['error', 'never'],
'prefer-template': 'error',
// typescript-eslint rules
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/consistent-type-assertions': 'error',
'@typescript-eslint/explicit-function-return-type': [
'error',
{ allowExpressions: true }
],
'@typescript-eslint/explicit-member-accessibility': [
'error',
{ accessibility: 'no-public' }
],
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/no-unnecessary-qualifier': 'error',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/prefer-for-of': 'warn',
'@typescript-eslint/prefer-function-type': 'warn',
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
'@typescript-eslint/promise-function-async': 'error',
'@typescript-eslint/require-array-sort-compare': 'error',
'@typescript-eslint/restrict-template-expressions': 'off',
// eslint-plugin-import rules
'import/extensions': 'error',
'import/first': 'error',
'import/no-absolute-path': 'error',
'import/no-commonjs': 'error',
'import/no-deprecated': 'warn',
'import/no-dynamic-require': 'error',
'import/no-extraneous-dependencies': 'error',
'import/no-mutable-exports': 'error',
'import/no-namespace': 'off',
'import/no-unresolved': ['error', { ignore: ['csv-parse/sync'] }],
'import/no-anonymous-default-export': [
'error',
{
allowAnonymousClass: false,
allowAnonymousFunction: false,
allowArray: true,
allowArrowFunction: false,
allowLiteral: true,
allowObject: true
}
]
}
}
)

View File

@@ -38,7 +38,7 @@ jobs:
- name: Lint Codebase
id: super-linter
uses: super-linter/super-linter/slim@v7
uses: super-linter/super-linter/slim@v7.2.1
env:
DEFAULT_BRANCH: main
FILTER_REGEX_EXCLUDE: dist/**/*

View File

@@ -24,6 +24,17 @@ CLI][5].
See [Using artifact attestations to establish provenance for builds][9] for more
information on artifact attestations.
<!-- prettier-ignore-start -->
> [!NOTE]
> Artifact attestations are available in public repositories for all
> current GitHub plans.
>
> To use artifact attestations in private or internal repositories, you must
> be on a GitHub Enterprise Cloud plan.
>
> Artifact attestations are NOT supported on GitHub Enterprise Server.
<!-- prettier-ignore-end -->
## Usage
Within the GitHub Actions workflow which builds some artifact you would like to
@@ -44,7 +55,7 @@ attest:
1. Add the following to your workflow after your artifact has been built:
```yaml
- uses: actions/attest@v1
- uses: actions/attest@v2
with:
subject-path: '<PATH TO ARTIFACT>'
predicate-type: '<PREDICATE URI>'
@@ -54,30 +65,35 @@ attest:
The `subject-path` parameter should identify the artifact for which you want
to generate an attestation. The `predicate-type` can be any of the the
[vetted predicate types][3] or a custom value. The `predicate-path`
identifies a file containg the JSON-encoded predicate parameters.
identifies a file containing the JSON-encoded predicate parameters.
### Inputs
See [action.yml](action.yml)
```yaml
- uses: actions/attest@v1
- uses: actions/attest@v2
with:
# Path to the artifact serving as the subject of the attestation. Must
# specify exactly one of "subject-path" or "subject-digest". May contain
# a glob pattern or list of paths (total subject count cannot exceed 1024).
# specify exactly one of "subject-path", "subject-digest", or
# "subject-checksums". May contain a glob pattern or list of paths
# (total subject count cannot exceed 1024).
subject-path:
# SHA256 digest of the subject for the attestation. Must be in the form
# "sha256:hex_digest" (e.g. "sha256:abc123..."). Must specify exactly one
# of "subject-path" or "subject-digest".
# of "subject-path", "subject-digest", or "subject-checksums".
subject-digest:
# Subject name as it should appear in the attestation. Required unless
# "subject-path" is specified, in which case it will be inferred from the
# path.
# Subject name as it should appear in the attestation. Required when
# identifying the subject with the "subject-digest" input.
subject-name:
# Path to checksums file containing digest and name of subjects for
# attestation. Must specify exactly one of "subject-path", "subject-digest",
# or "subject-checksums".
subject-checksums:
# URI identifying the type of the predicate.
predicate-type:
@@ -109,9 +125,11 @@ See [action.yml](action.yml)
<!-- markdownlint-disable MD013 -->
| Name | Description | Example |
| ------------- | -------------------------------------------------------------- | ----------------------- |
| `bundle-path` | Absolute path to the file containing the generated attestation | `/tmp/attestation.json` |
| Name | Description | Example |
| ----------------- | -------------------------------------------------------------- | ------------------------------------------------ |
| `attestation-id` | GitHub ID for the attestation | `123456` |
| `attestation-url` | URL for the attestation summary | `https://github.com/foo/bar/attestations/123456` |
| `bundle-path` | Absolute path to the file containing the generated attestation | `/tmp/attestation.json` |
<!-- markdownlint-enable MD013 -->
@@ -157,7 +175,7 @@ jobs:
- name: Build artifact
run: make my-app
- name: Attest
uses: actions/attest@v1
uses: actions/attest@v2
with:
subject-path: '${{ github.workspace }}/my-app'
predicate-type: 'https://example.com/predicate/v1'
@@ -170,7 +188,7 @@ If you are generating multiple artifacts, you can attest all of them at the same
time by using a wildcard in the `subject-path` input.
```yaml
- uses: actions/attest@v1
- uses: actions/attest@v2
with:
subject-path: 'dist/**/my-bin-*'
predicate-type: 'https://example.com/predicate/v1'
@@ -184,19 +202,56 @@ Alternatively, you can explicitly list multiple subjects with either a comma or
newline delimited list:
```yaml
- uses: actions/attest@v1
- uses: actions/attest@v2
with:
subject-path: 'dist/foo, dist/bar'
```
```yaml
- uses: actions/attest@v1
- uses: actions/attest@v2
with:
subject-path: |
dist/foo
dist/bar
```
### Identify Subjects with Checksums File
If you are using tools like
[goreleaser](https://goreleaser.com/customization/checksum/) or
[jreleaser](https://jreleaser.org/guide/latest/reference/checksum.html) which
generate a checksums file you can identify the attestation subjects by passing
the path of the checksums file to the `subject-checksums` input. Each of the
artifacts identified in the checksums file will be listed as a subject for the
attestation.
```yaml
- name: Calculate artifact digests
run: |
shasum -a 256 foo_0.0.1_* > subject.checksums.txt
- uses: actions/attest@v2
with:
subject-checksums: subject.checksums.txt
predicate-type: 'https://example.com/predicate/v1'
predicate: '{}'
```
<!-- markdownlint-disable MD038 -->
The file referenced by the `subject-checksums` input must conform to the same
format used by the shasum tools. Each subject should be listed on a separate
line including the hex-encoded digest (either SHA256 or SHA512), a space, a
single character flag indicating either binary (`*`) or text (` `) input mode,
and the filename.
<!-- markdownlint-enable MD038 -->
```text
b569bf992b287f55d78bf8ee476497e9b7e9d2bf1c338860bfb905016218c740 foo_0.0.1_darwin_amd64
a54fc515e616cac7fcf11a49d5c5ec9ec315948a5935c1e11dd610b834b14dde foo_0.0.1_darwin_arm64
```
### Container Image
When working with container images you can invoke the action with the
@@ -247,7 +302,7 @@ jobs:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Attest
uses: actions/attest@v1
uses: actions/attest@v2
id: attest
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

View File

@@ -13,7 +13,7 @@ describe('index', () => {
beforeEach(() => {
getBooleanInputMock.mockImplementation(() => false)
})
it('calls run when imported', async () => {
it('calls run when imported', () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('../src/index')

View File

@@ -43,6 +43,7 @@ const defaultInputs: main.RunInputs = {
subjectName: '',
subjectDigest: '',
subjectPath: '',
subjectChecksums: '',
pushToRegistry: false,
showSummary: true,
githubToken: '',
@@ -138,7 +139,9 @@ describe('action', () => {
expect(runMock).toHaveReturned()
expect(setFailedMock).toHaveBeenCalledWith(
new Error('One of subject-path or subject-digest must be provided')
new Error(
'One of subject-path, subject-digest, or subject-checksums must be provided'
)
)
})
})
@@ -199,6 +202,16 @@ describe('action', () => {
'bundle-path',
expect.stringMatching('attestation.json')
)
expect(setOutputMock).toHaveBeenNthCalledWith(
2,
'attestation-id',
expect.stringMatching(attestationID)
)
expect(setOutputMock).toHaveBeenNthCalledWith(
3,
'attestation-url',
expect.stringContaining(`foo/bar/attestations/${attestationID}`)
)
expect(setFailedMock).not.toHaveBeenCalled()
})
})
@@ -285,6 +298,16 @@ describe('action', () => {
'bundle-path',
expect.stringMatching('attestation.json')
)
expect(setOutputMock).toHaveBeenNthCalledWith(
2,
'attestation-id',
expect.stringMatching(attestationID)
)
expect(setOutputMock).toHaveBeenNthCalledWith(
3,
'attestation-url',
expect.stringContaining(`foo/bar/attestations/${attestationID}`)
)
expect(setFailedMock).not.toHaveBeenCalled()
})
})

View File

@@ -12,13 +12,14 @@ describe('subjectFromInputs', () => {
const blankInputs: SubjectInputs = {
subjectPath: '',
subjectName: '',
subjectDigest: ''
subjectDigest: '',
subjectChecksums: ''
}
describe('when no inputs are provided', () => {
it('throws an error', async () => {
await expect(subjectFromInputs(blankInputs)).rejects.toThrow(
/one of subject-path or subject-digest must be provided/i
/one of subject-path, subject-digest, or subject-checksums must be provided/i
)
})
})
@@ -28,11 +29,42 @@ describe('subjectFromInputs', () => {
const inputs: SubjectInputs = {
subjectName: 'foo',
subjectPath: 'path/to/subject',
subjectDigest: 'digest'
subjectDigest: 'digest',
subjectChecksums: ''
}
await expect(subjectFromInputs(inputs)).rejects.toThrow(
/only one of subject-path or subject-digest may be provided/i
/only one of subject-path, subject-digest, or subject-checksums may be provided/i
)
})
})
describe('when both subject path and subject checksums are provided', () => {
it('throws an error', async () => {
const inputs: SubjectInputs = {
subjectName: '',
subjectPath: 'path/to/subject',
subjectDigest: '',
subjectChecksums: 'path/to/checksums'
}
await expect(subjectFromInputs(inputs)).rejects.toThrow(
/only one of subject-path, subject-digest, or subject-checksums may be provided/i
)
})
})
describe('when both subject digest and subject checksums are provided', () => {
it('throws an error', async () => {
const inputs: SubjectInputs = {
subjectName: 'foo',
subjectPath: '',
subjectDigest: 'digest',
subjectChecksums: 'path/to/checksums'
}
await expect(subjectFromInputs(inputs)).rejects.toThrow(
/only one of subject-path, subject-digest, or subject-checksums may be provided/i
)
})
})
@@ -67,7 +99,7 @@ describe('subjectFromInputs', () => {
})
})
describe('when the alogrithm is not supported', () => {
describe('when the algorithm is not supported', () => {
it('throws an error', async () => {
const inputs: SubjectInputs = {
...blankInputs,
@@ -232,7 +264,6 @@ describe('subjectFromInputs', () => {
expect(subjects).toBeDefined()
expect(subjects).toHaveLength(3)
/* eslint-disable-next-line github/array-foreach */
subjects.forEach((subject, i) => {
expect(subject.name).toEqual(`${filename}-${i}`)
expect(subject.digest).toEqual({ sha256: expectedDigest })
@@ -362,6 +393,143 @@ describe('subjectFromInputs', () => {
})
})
})
describe('when duplicate subjects are supplied', () => {
let otherDir = ''
// Add duplicate subject in alternate directory
beforeEach(async () => {
// Set-up temp directory
const tmpDir = await fs.realpath(os.tmpdir())
otherDir = await fs.mkdtemp(tmpDir + path.sep)
// Write file to temp directory
await fs.writeFile(path.join(otherDir, filename), content)
})
it('returns de-duplicated subjects', async () => {
const inputs: SubjectInputs = {
...blankInputs,
subjectPath: `${path.join(dir, 'subject')}, ${path.join(otherDir, 'subject')} `
}
const subjects = await subjectFromInputs(inputs)
expect(subjects).toBeDefined()
expect(subjects).toHaveLength(1)
})
})
})
describe('when specifying a subject checksums file', () => {
const checksums = `
187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d demo_0.0.1_linux_amd64
badline
5d8b4751ef31f9440d843fcfa4e53ca2e25b1cb1f13fd355fdc7c24b41fe645293291ea9297ba3989078abb77ebbaac66be073618a9e4974dbd0361881d4c718 demo_0.0.1_darwin_arm64`
let dir = ''
const filename = 'checksums'
beforeEach(async () => {
// Set-up temp directory
const tmpDir = await fs.realpath(os.tmpdir())
dir = await fs.mkdtemp(tmpDir + path.sep)
// Write file to temp directory
await fs.writeFile(path.join(dir, filename), checksums)
})
afterEach(async () => {
// Clean-up temp directory
await fs.rm(dir, { recursive: true })
})
describe('when the specified path is NOT a file', () => {
it('throws an error', async () => {
const inputs: SubjectInputs = {
...blankInputs,
subjectChecksums: dir
}
await expect(subjectFromInputs(inputs)).rejects.toThrow(
/subject checksums file not found/i
)
})
})
describe('when the specific path is a file', () => {
it('returns the multiple subjects', async () => {
const inputs: SubjectInputs = {
...blankInputs,
subjectChecksums: path.join(dir, filename)
}
const subjects = await subjectFromInputs(inputs)
expect(subjects).toBeDefined()
expect(subjects).toHaveLength(2)
expect(subjects).toContainEqual({
name: 'demo_0.0.1_linux_amd64',
digest: {
sha256:
'187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d'
}
})
})
})
})
describe('when specifying a subject checksums string', () => {
const checksums = `
f861e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e demo_0.0.1_linux_386
187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d demo_0.0.1_linux_amd64
9ecbf449e286a8a8748c161c52aa28b6b2fc64ab86f94161c5d1b3abc18156c5 demo_0.0.1_linux_arm64`
it('returns the multiple subjects', async () => {
const inputs: SubjectInputs = {
...blankInputs,
subjectChecksums: checksums
}
const subjects = await subjectFromInputs(inputs)
expect(subjects).toBeDefined()
expect(subjects).toHaveLength(3)
expect(subjects).toContainEqual({
name: 'demo_0.0.1_linux_386',
digest: {
sha256:
'f861e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e'
}
})
})
})
describe('when specifying a subject checksums string with an unrecognized digest', () => {
const checksums = `f861e demo_0.0.1_linux_386`
it('throws an error', async () => {
const inputs: SubjectInputs = {
...blankInputs,
subjectChecksums: checksums
}
await expect(subjectFromInputs(inputs)).rejects.toThrow(
/unknown digest algorithm/i
)
})
})
describe('when specifying a subject checksums string with an invalid digest', () => {
const checksums =
'!!!!e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e demo_0.0.1_linux_386'
it('throws an error', async () => {
const inputs: SubjectInputs = {
...blankInputs,
subjectChecksums: checksums
}
await expect(subjectFromInputs(inputs)).rejects.toThrow(/invalid digest/i)
})
})
})

View File

@@ -9,20 +9,26 @@ inputs:
subject-path:
description: >
Path to the artifact serving as the subject of the attestation. Must
specify exactly one of "subject-path" or "subject-digest". May contain a
glob pattern or list of paths (total subject count cannot exceed 1024).
specify exactly one of "subject-path", "subject-digest", or
"subject-checksums". May contain a glob pattern or list of paths (total
subject count cannot exceed 1024).
required: false
subject-digest:
description: >
Digest of the subject for the attestation. Must be in the form
"algorithm:hex_digest" (e.g. "sha256:abc123..."). Must specify exactly one
of "subject-path" or "subject-digest".
of "subject-path", "subject-digest", or "subject-checksums".
required: false
subject-name:
description: >
Subject name as it should appear in the attestation. Required unless
"subject-path" is specified, in which case it will be inferred from the
path.
Subject name as it should appear in the attestation. Required when
identifying the subject with the "subject-digest" input.
required: false
subject-checksums:
description: >
Path to checksums file containing digest and name of subjects for
attestation. Must specify exactly one of "subject-path", "subject-digest",
or "subject-checksums".
required: false
predicate-type:
description: >
@@ -61,6 +67,10 @@ inputs:
outputs:
bundle-path:
description: 'The path to the file containing the attestation bundle.'
attestation-id:
description: 'The ID of the attestation.'
attestation-url:
description: 'The URL for the attestation summary.'
runs:
using: node20

314
dist/index.js generated vendored
View File

@@ -377,11 +377,9 @@ const buildSLSAProvenancePredicate = (issuer) => __awaiter(void 0, void 0, void
// Split just the path and ref from the workflow string.
// owner/repo/.github/workflows/main.yml@main =>
// .github/workflows/main.yml, main
const [workflowPath, ...workflowRefChunks] = claims.workflow_ref
const [workflowPath] = claims.workflow_ref
.replace(`${claims.repository}/`, '')
.split('@');
// Handle case where tag contains `@` (e.g: when using changesets in a monorepo context),
const workflowRef = workflowRefChunks.join('@');
return {
type: SLSA_PREDICATE_V1_TYPE,
params: {
@@ -389,7 +387,7 @@ const buildSLSAProvenancePredicate = (issuer) => __awaiter(void 0, void 0, void
buildType: GITHUB_BUILD_TYPE,
externalParameters: {
workflow: {
ref: workflowRef,
ref: claims.ref,
repository: `${serverURL}/${claims.repository}`,
path: workflowPath
}
@@ -7521,7 +7519,7 @@ __export(dist_src_exports, {
module.exports = __toCommonJS(dist_src_exports);
// pkg/dist-src/version.js
var VERSION = "9.1.5";
var VERSION = "9.2.2";
// pkg/dist-src/normalize-paginated-list-response.js
function normalizePaginatedListResponse(response) {
@@ -7569,7 +7567,7 @@ function iterator(octokit, route, parameters) {
const response = await requestMethod({ method, url, headers });
const normalizedResponse = normalizePaginatedListResponse(response);
url = ((normalizedResponse.headers.link || "").match(
/<([^>]+)>;\s*rel="next"/
/<([^<>]+)>;\s*rel="next"/
) || [])[1];
return { value: normalizedResponse };
} catch (error) {
@@ -7682,6 +7680,8 @@ var paginatingEndpoints = [
"GET /orgs/{org}/members/{username}/codespaces",
"GET /orgs/{org}/migrations",
"GET /orgs/{org}/migrations/{migration_id}/repositories",
"GET /orgs/{org}/organization-roles/{role_id}/teams",
"GET /orgs/{org}/organization-roles/{role_id}/users",
"GET /orgs/{org}/outside_collaborators",
"GET /orgs/{org}/packages",
"GET /orgs/{org}/packages/{package_type}/{package_name}/versions",
@@ -10196,7 +10196,7 @@ var RequestError = class extends Error {
if (options.request.headers.authorization) {
requestCopy.headers = Object.assign({}, options.request.headers, {
authorization: options.request.headers.authorization.replace(
/ .*$/,
/(?<! ) .*$/,
" [REDACTED]"
)
});
@@ -28485,7 +28485,7 @@ Object.defineProperty(exports, "cryptoRuntime", ({ enumerable: true, get: functi
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.compactDecrypt = void 0;
exports.compactDecrypt = compactDecrypt;
const decrypt_js_1 = __nccwpck_require__(59344);
const errors_js_1 = __nccwpck_require__(15974);
const buffer_utils_js_1 = __nccwpck_require__(45734);
@@ -28513,7 +28513,6 @@ async function compactDecrypt(jwe, key, options) {
}
return result;
}
exports.compactDecrypt = compactDecrypt;
/***/ }),
@@ -28563,7 +28562,7 @@ exports.CompactEncrypt = CompactEncrypt;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.flattenedDecrypt = void 0;
exports.flattenedDecrypt = flattenedDecrypt;
const base64url_js_1 = __nccwpck_require__(12635);
const decrypt_js_1 = __nccwpck_require__(52806);
const errors_js_1 = __nccwpck_require__(15974);
@@ -28725,7 +28724,6 @@ async function flattenedDecrypt(jwe, key, options) {
}
return result;
}
exports.flattenedDecrypt = flattenedDecrypt;
/***/ }),
@@ -28909,7 +28907,7 @@ exports.FlattenedEncrypt = FlattenedEncrypt;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.generalDecrypt = void 0;
exports.generalDecrypt = generalDecrypt;
const decrypt_js_1 = __nccwpck_require__(59344);
const errors_js_1 = __nccwpck_require__(15974);
const is_object_js_1 = __nccwpck_require__(92242);
@@ -28941,7 +28939,6 @@ async function generalDecrypt(jwe, key, options) {
}
throw new errors_js_1.JWEDecryptionFailed();
}
exports.generalDecrypt = generalDecrypt;
/***/ }),
@@ -29146,7 +29143,7 @@ exports.GeneralEncrypt = GeneralEncrypt;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmbeddedJWK = void 0;
exports.EmbeddedJWK = EmbeddedJWK;
const import_js_1 = __nccwpck_require__(45647);
const is_object_js_1 = __nccwpck_require__(92242);
const errors_js_1 = __nccwpck_require__(15974);
@@ -29164,7 +29161,6 @@ async function EmbeddedJWK(protectedHeader, token) {
}
return key;
}
exports.EmbeddedJWK = EmbeddedJWK;
/***/ }),
@@ -29175,7 +29171,8 @@ exports.EmbeddedJWK = EmbeddedJWK;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.calculateJwkThumbprintUri = exports.calculateJwkThumbprint = void 0;
exports.calculateJwkThumbprint = calculateJwkThumbprint;
exports.calculateJwkThumbprintUri = calculateJwkThumbprintUri;
const digest_js_1 = __nccwpck_require__(12931);
const base64url_js_1 = __nccwpck_require__(12635);
const errors_js_1 = __nccwpck_require__(15974);
@@ -29224,13 +29221,11 @@ async function calculateJwkThumbprint(jwk, digestAlgorithm) {
const data = buffer_utils_js_1.encoder.encode(JSON.stringify(components));
return (0, base64url_js_1.encode)(await (0, digest_js_1.default)(digestAlgorithm, data));
}
exports.calculateJwkThumbprint = calculateJwkThumbprint;
async function calculateJwkThumbprintUri(jwk, digestAlgorithm) {
digestAlgorithm ??= 'sha256';
const thumbprint = await calculateJwkThumbprint(jwk, digestAlgorithm);
return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;
}
exports.calculateJwkThumbprintUri = calculateJwkThumbprintUri;
/***/ }),
@@ -29241,7 +29236,7 @@ exports.calculateJwkThumbprintUri = calculateJwkThumbprintUri;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createLocalJWKSet = void 0;
exports.createLocalJWKSet = createLocalJWKSet;
const import_js_1 = __nccwpck_require__(45647);
const errors_js_1 = __nccwpck_require__(15974);
const is_object_js_1 = __nccwpck_require__(92242);
@@ -29364,7 +29359,6 @@ function createLocalJWKSet(jwks) {
});
return localJWKSet;
}
exports.createLocalJWKSet = createLocalJWKSet;
/***/ }),
@@ -29375,7 +29369,8 @@ exports.createLocalJWKSet = createLocalJWKSet;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.experimental_jwksCache = exports.createRemoteJWKSet = exports.jwksCache = void 0;
exports.experimental_jwksCache = exports.jwksCache = void 0;
exports.createRemoteJWKSet = createRemoteJWKSet;
const fetch_jwks_js_1 = __nccwpck_require__(20311);
const errors_js_1 = __nccwpck_require__(15974);
const local_js_1 = __nccwpck_require__(25275);
@@ -29388,7 +29383,7 @@ function isCloudflareWorkers() {
let USER_AGENT;
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
const NAME = 'jose';
const VERSION = 'v5.9.4';
const VERSION = 'v5.9.6';
USER_AGENT = `${NAME}/${VERSION}`;
}
exports.jwksCache = Symbol();
@@ -29523,7 +29518,6 @@ function createRemoteJWKSet(url, options) {
});
return remoteJWKSet;
}
exports.createRemoteJWKSet = createRemoteJWKSet;
exports.experimental_jwksCache = exports.jwksCache;
@@ -29565,7 +29559,7 @@ exports.CompactSign = CompactSign;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.compactVerify = void 0;
exports.compactVerify = compactVerify;
const verify_js_1 = __nccwpck_require__(56358);
const errors_js_1 = __nccwpck_require__(15974);
const buffer_utils_js_1 = __nccwpck_require__(45734);
@@ -29587,7 +29581,6 @@ async function compactVerify(jws, key, options) {
}
return result;
}
exports.compactVerify = compactVerify;
/***/ }),
@@ -29694,7 +29687,7 @@ exports.FlattenedSign = FlattenedSign;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.flattenedVerify = void 0;
exports.flattenedVerify = flattenedVerify;
const base64url_js_1 = __nccwpck_require__(12635);
const verify_js_1 = __nccwpck_require__(11242);
const errors_js_1 = __nccwpck_require__(15974);
@@ -29817,7 +29810,6 @@ async function flattenedVerify(jws, key, options) {
}
return result;
}
exports.flattenedVerify = flattenedVerify;
/***/ }),
@@ -29913,7 +29905,7 @@ exports.GeneralSign = GeneralSign;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.generalVerify = void 0;
exports.generalVerify = generalVerify;
const verify_js_1 = __nccwpck_require__(56358);
const errors_js_1 = __nccwpck_require__(15974);
const is_object_js_1 = __nccwpck_require__(92242);
@@ -29938,7 +29930,6 @@ async function generalVerify(jws, key, options) {
}
throw new errors_js_1.JWSSignatureVerificationFailed();
}
exports.generalVerify = generalVerify;
/***/ }),
@@ -29949,7 +29940,7 @@ exports.generalVerify = generalVerify;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.jwtDecrypt = void 0;
exports.jwtDecrypt = jwtDecrypt;
const decrypt_js_1 = __nccwpck_require__(14298);
const jwt_claims_set_js_1 = __nccwpck_require__(13354);
const errors_js_1 = __nccwpck_require__(15974);
@@ -29973,7 +29964,6 @@ async function jwtDecrypt(jwt, key, options) {
}
return result;
}
exports.jwtDecrypt = jwtDecrypt;
/***/ }),
@@ -30236,7 +30226,7 @@ exports.UnsecuredJWT = UnsecuredJWT;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.jwtVerify = void 0;
exports.jwtVerify = jwtVerify;
const verify_js_1 = __nccwpck_require__(94212);
const jwt_claims_set_js_1 = __nccwpck_require__(13354);
const errors_js_1 = __nccwpck_require__(15974);
@@ -30252,7 +30242,6 @@ async function jwtVerify(jwt, key, options) {
}
return result;
}
exports.jwtVerify = jwtVerify;
/***/ }),
@@ -30263,22 +30252,21 @@ exports.jwtVerify = jwtVerify;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.exportJWK = exports.exportPKCS8 = exports.exportSPKI = void 0;
exports.exportSPKI = exportSPKI;
exports.exportPKCS8 = exportPKCS8;
exports.exportJWK = exportJWK;
const asn1_js_1 = __nccwpck_require__(12774);
const asn1_js_2 = __nccwpck_require__(12774);
const key_to_jwk_js_1 = __nccwpck_require__(9041);
async function exportSPKI(key) {
return (0, asn1_js_1.toSPKI)(key);
}
exports.exportSPKI = exportSPKI;
async function exportPKCS8(key) {
return (0, asn1_js_2.toPKCS8)(key);
}
exports.exportPKCS8 = exportPKCS8;
async function exportJWK(key) {
return (0, key_to_jwk_js_1.default)(key);
}
exports.exportJWK = exportJWK;
/***/ }),
@@ -30289,12 +30277,11 @@ exports.exportJWK = exportJWK;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.generateKeyPair = void 0;
exports.generateKeyPair = generateKeyPair;
const generate_js_1 = __nccwpck_require__(10088);
async function generateKeyPair(alg, options) {
return (0, generate_js_1.generateKeyPair)(alg, options);
}
exports.generateKeyPair = generateKeyPair;
/***/ }),
@@ -30305,12 +30292,11 @@ exports.generateKeyPair = generateKeyPair;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.generateSecret = void 0;
exports.generateSecret = generateSecret;
const generate_js_1 = __nccwpck_require__(10088);
async function generateSecret(alg, options) {
return (0, generate_js_1.generateSecret)(alg, options);
}
exports.generateSecret = generateSecret;
/***/ }),
@@ -30321,7 +30307,10 @@ exports.generateSecret = generateSecret;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.importJWK = exports.importPKCS8 = exports.importX509 = exports.importSPKI = void 0;
exports.importSPKI = importSPKI;
exports.importX509 = importX509;
exports.importPKCS8 = importPKCS8;
exports.importJWK = importJWK;
const base64url_js_1 = __nccwpck_require__(12635);
const asn1_js_1 = __nccwpck_require__(12774);
const jwk_to_key_js_1 = __nccwpck_require__(80939);
@@ -30333,21 +30322,18 @@ async function importSPKI(spki, alg, options) {
}
return (0, asn1_js_1.fromSPKI)(spki, alg, options);
}
exports.importSPKI = importSPKI;
async function importX509(x509, alg, options) {
if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) {
throw new TypeError('"x509" must be X.509 formatted string');
}
return (0, asn1_js_1.fromX509)(x509, alg, options);
}
exports.importX509 = importX509;
async function importPKCS8(pkcs8, alg, options) {
if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) {
throw new TypeError('"pkcs8" must be PKCS#8 formatted string');
}
return (0, asn1_js_1.fromPKCS8)(pkcs8, alg, options);
}
exports.importPKCS8 = importPKCS8;
async function importJWK(jwk, alg) {
if (!(0, is_object_js_1.default)(jwk)) {
throw new TypeError('JWK must be an object');
@@ -30370,7 +30356,6 @@ async function importJWK(jwk, alg) {
throw new errors_js_1.JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
}
}
exports.importJWK = importJWK;
/***/ }),
@@ -30381,7 +30366,8 @@ exports.importJWK = importJWK;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.unwrap = exports.wrap = void 0;
exports.wrap = wrap;
exports.unwrap = unwrap;
const encrypt_js_1 = __nccwpck_require__(36286);
const decrypt_js_1 = __nccwpck_require__(52806);
const base64url_js_1 = __nccwpck_require__(12635);
@@ -30394,12 +30380,10 @@ async function wrap(alg, key, cek, iv) {
tag: (0, base64url_js_1.encode)(wrapped.tag),
};
}
exports.wrap = wrap;
async function unwrap(alg, key, encryptedKey, iv, tag) {
const jweAlgorithm = alg.slice(0, 7);
return (0, decrypt_js_1.default)(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0));
}
exports.unwrap = unwrap;
/***/ }),
@@ -30410,7 +30394,13 @@ exports.unwrap = unwrap;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.concatKdf = exports.lengthAndInput = exports.uint32be = exports.uint64be = exports.p2s = exports.concat = exports.decoder = exports.encoder = void 0;
exports.decoder = exports.encoder = void 0;
exports.concat = concat;
exports.p2s = p2s;
exports.uint64be = uint64be;
exports.uint32be = uint32be;
exports.lengthAndInput = lengthAndInput;
exports.concatKdf = concatKdf;
const digest_js_1 = __nccwpck_require__(12931);
exports.encoder = new TextEncoder();
exports.decoder = new TextDecoder();
@@ -30425,11 +30415,9 @@ function concat(...buffers) {
}
return buf;
}
exports.concat = concat;
function p2s(alg, p2sInput) {
return concat(exports.encoder.encode(alg), new Uint8Array([0]), p2sInput);
}
exports.p2s = p2s;
function writeUInt32BE(buf, value, offset) {
if (value < 0 || value >= MAX_INT32) {
throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`);
@@ -30444,17 +30432,14 @@ function uint64be(value) {
writeUInt32BE(buf, low, 4);
return buf;
}
exports.uint64be = uint64be;
function uint32be(value) {
const buf = new Uint8Array(4);
writeUInt32BE(buf, value);
return buf;
}
exports.uint32be = uint32be;
function lengthAndInput(input) {
return concat(uint32be(input.length), input);
}
exports.lengthAndInput = lengthAndInput;
async function concatKdf(secret, bits, value) {
const iterations = Math.ceil((bits >> 3) / 32);
const res = new Uint8Array(iterations * 32);
@@ -30467,7 +30452,6 @@ async function concatKdf(secret, bits, value) {
}
return res.slice(0, bits >> 3);
}
exports.concatKdf = concatKdf;
/***/ }),
@@ -30478,7 +30462,7 @@ exports.concatKdf = concatKdf;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.bitLength = void 0;
exports.bitLength = bitLength;
const errors_js_1 = __nccwpck_require__(15974);
const random_js_1 = __nccwpck_require__(23376);
function bitLength(alg) {
@@ -30498,7 +30482,6 @@ function bitLength(alg) {
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
}
}
exports.bitLength = bitLength;
exports["default"] = (alg) => (0, random_js_1.default)(new Uint8Array(bitLength(alg) >> 3));
@@ -30616,13 +30599,13 @@ exports.checkKeyTypeWithJwk = checkKeyType.bind(undefined, true);
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = checkP2s;
const errors_js_1 = __nccwpck_require__(15974);
function checkP2s(p2s) {
if (!(p2s instanceof Uint8Array) || p2s.length < 8) {
throw new errors_js_1.JWEInvalid('PBES2 Salt Input must be 8 or more octets');
}
}
exports["default"] = checkP2s;
/***/ }),
@@ -30633,7 +30616,8 @@ exports["default"] = checkP2s;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.checkEncCryptoKey = exports.checkSigCryptoKey = void 0;
exports.checkSigCryptoKey = checkSigCryptoKey;
exports.checkEncCryptoKey = checkEncCryptoKey;
function unusable(name, prop = 'algorithm.name') {
return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
}
@@ -30728,7 +30712,6 @@ function checkSigCryptoKey(key, alg, ...usages) {
}
checkUsage(key, usages);
}
exports.checkSigCryptoKey = checkSigCryptoKey;
function checkEncCryptoKey(key, alg, ...usages) {
switch (alg) {
case 'A128GCM':
@@ -30787,7 +30770,6 @@ function checkEncCryptoKey(key, alg, ...usages) {
}
checkUsage(key, usages);
}
exports.checkEncCryptoKey = checkEncCryptoKey;
/***/ }),
@@ -31047,7 +31029,7 @@ exports["default"] = (date) => Math.floor(date.getTime() / 1000);
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.withAlg = void 0;
exports.withAlg = withAlg;
function message(msg, actual, ...types) {
types = types.filter(Boolean);
if (types.length > 2) {
@@ -31079,7 +31061,6 @@ exports["default"] = (actual, ...types) => {
function withAlg(alg, actual, ...types) {
return message(`Key for the ${alg} algorithm must be `, actual, ...types);
}
exports.withAlg = withAlg;
/***/ }),
@@ -31122,24 +31103,23 @@ exports["default"] = isDisjoint;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.isSecretJWK = exports.isPublicJWK = exports.isPrivateJWK = exports.isJWK = void 0;
exports.isJWK = isJWK;
exports.isPrivateJWK = isPrivateJWK;
exports.isPublicJWK = isPublicJWK;
exports.isSecretJWK = isSecretJWK;
const is_object_js_1 = __nccwpck_require__(92242);
function isJWK(key) {
return (0, is_object_js_1.default)(key) && typeof key.kty === 'string';
}
exports.isJWK = isJWK;
function isPrivateJWK(key) {
return key.kty !== 'oct' && typeof key.d === 'string';
}
exports.isPrivateJWK = isPrivateJWK;
function isPublicJWK(key) {
return key.kty !== 'oct' && typeof key.d === 'undefined';
}
exports.isPublicJWK = isPublicJWK;
function isSecretJWK(key) {
return isJWK(key) && key.kty === 'oct' && typeof key.k === 'string';
}
exports.isSecretJWK = isSecretJWK;
/***/ }),
@@ -31150,6 +31130,7 @@ exports.isSecretJWK = isSecretJWK;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = isObject;
function isObjectLike(value) {
return typeof value === 'object' && value !== null;
}
@@ -31166,7 +31147,6 @@ function isObject(input) {
}
return Object.getPrototypeOf(input) === proto;
}
exports["default"] = isObject;
/***/ }),
@@ -31177,7 +31157,7 @@ exports["default"] = isObject;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.bitLength = void 0;
exports.bitLength = bitLength;
const errors_js_1 = __nccwpck_require__(15974);
const random_js_1 = __nccwpck_require__(23376);
function bitLength(alg) {
@@ -31197,7 +31177,6 @@ function bitLength(alg) {
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
}
}
exports.bitLength = bitLength;
exports["default"] = (alg) => (0, random_js_1.default)(new Uint8Array(bitLength(alg) >> 3));
@@ -31618,6 +31597,7 @@ exports.decode = decode;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = cbcTag;
const node_crypto_1 = __nccwpck_require__(77598);
const buffer_utils_js_1 = __nccwpck_require__(45734);
function cbcTag(aad, iv, ciphertext, macSize, macKey, keySize) {
@@ -31626,7 +31606,6 @@ function cbcTag(aad, iv, ciphertext, macSize, macKey, keySize) {
hmac.update(macData);
return hmac.digest().slice(0, keySize >> 3);
}
exports["default"] = cbcTag;
/***/ }),
@@ -31848,6 +31827,7 @@ exports["default"] = digest;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = dsaDigest;
const errors_js_1 = __nccwpck_require__(15974);
function dsaDigest(alg) {
switch (alg) {
@@ -31870,7 +31850,6 @@ function dsaDigest(alg) {
throw new errors_js_1.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
}
}
exports["default"] = dsaDigest;
/***/ }),
@@ -31881,7 +31860,9 @@ exports["default"] = dsaDigest;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ecdhAllowed = exports.generateEpk = exports.deriveKey = void 0;
exports.ecdhAllowed = void 0;
exports.deriveKey = deriveKey;
exports.generateEpk = generateEpk;
const node_crypto_1 = __nccwpck_require__(77598);
const node_util_1 = __nccwpck_require__(57975);
const get_named_curve_js_1 = __nccwpck_require__(65661);
@@ -31920,7 +31901,6 @@ async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu = new
const sharedSecret = (0, node_crypto_1.diffieHellman)({ privateKey, publicKey });
return (0, buffer_utils_js_1.concatKdf)(sharedSecret, keyLength, value);
}
exports.deriveKey = deriveKey;
async function generateEpk(kee) {
let key;
if ((0, webcrypto_js_1.isCryptoKey)(kee)) {
@@ -31946,7 +31926,6 @@ async function generateEpk(kee) {
throw new errors_js_1.JOSENotSupported('Invalid or unsupported EPK');
}
}
exports.generateEpk = generateEpk;
const ecdhAllowed = (key) => ['P-256', 'P-384', 'P-521', 'X25519', 'X448'].includes((0, get_named_curve_js_1.default)(key));
exports.ecdhAllowed = ecdhAllowed;
@@ -32100,7 +32079,8 @@ exports["default"] = fetchJwks;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.generateKeyPair = exports.generateSecret = void 0;
exports.generateSecret = generateSecret;
exports.generateKeyPair = generateKeyPair;
const node_crypto_1 = __nccwpck_require__(77598);
const node_util_1 = __nccwpck_require__(57975);
const random_js_1 = __nccwpck_require__(23376);
@@ -32133,7 +32113,6 @@ async function generateSecret(alg, options) {
}
return (0, node_crypto_1.createSecretKey)((0, random_js_1.default)(new Uint8Array(length >> 3)));
}
exports.generateSecret = generateSecret;
async function generateKeyPair(alg, options) {
switch (alg) {
case 'RS256':
@@ -32199,7 +32178,6 @@ async function generateKeyPair(alg, options) {
throw new errors_js_1.JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
}
}
exports.generateKeyPair = generateKeyPair;
/***/ }),
@@ -32279,6 +32257,7 @@ exports["default"] = getNamedCurve;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = getSignVerifyKey;
const node_crypto_1 = __nccwpck_require__(77598);
const webcrypto_js_1 = __nccwpck_require__(59044);
const crypto_key_js_1 = __nccwpck_require__(26319);
@@ -32307,7 +32286,6 @@ function getSignVerifyKey(alg, key, usage) {
}
throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types, 'Uint8Array', 'JSON Web Key'));
}
exports["default"] = getSignVerifyKey;
/***/ }),
@@ -32318,6 +32296,7 @@ exports["default"] = getSignVerifyKey;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = hmacDigest;
const errors_js_1 = __nccwpck_require__(15974);
function hmacDigest(alg) {
switch (alg) {
@@ -32331,7 +32310,6 @@ function hmacDigest(alg) {
throw new errors_js_1.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
}
}
exports["default"] = hmacDigest;
/***/ }),
@@ -32435,6 +32413,7 @@ exports["default"] = keyToJWK;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = keyForCrypto;
const node_crypto_1 = __nccwpck_require__(77598);
const get_named_curve_js_1 = __nccwpck_require__(65661);
const errors_js_1 = __nccwpck_require__(15974);
@@ -32538,7 +32517,6 @@ function keyForCrypto(alg, key) {
}
return options ? { ...options, key } : key;
}
exports["default"] = keyForCrypto;
/***/ }),
@@ -32829,7 +32807,7 @@ exports.decode = base64url.decode;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.decodeJwt = void 0;
exports.decodeJwt = decodeJwt;
const base64url_js_1 = __nccwpck_require__(78305);
const buffer_utils_js_1 = __nccwpck_require__(45734);
const is_object_js_1 = __nccwpck_require__(92242);
@@ -32862,7 +32840,6 @@ function decodeJwt(jwt) {
throw new errors_js_1.JWTInvalid('Invalid JWT Claims Set');
return result;
}
exports.decodeJwt = decodeJwt;
/***/ }),
@@ -32873,7 +32850,7 @@ exports.decodeJwt = decodeJwt;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.decodeProtectedHeader = void 0;
exports.decodeProtectedHeader = decodeProtectedHeader;
const base64url_js_1 = __nccwpck_require__(78305);
const buffer_utils_js_1 = __nccwpck_require__(45734);
const is_object_js_1 = __nccwpck_require__(92242);
@@ -32908,7 +32885,6 @@ function decodeProtectedHeader(token) {
throw new TypeError('Invalid Token or Protected Header formatting');
}
}
exports.decodeProtectedHeader = decodeProtectedHeader;
/***/ }),
@@ -42905,7 +42881,7 @@ const testSet = (set, version, options) => {
const debug = __nccwpck_require__(1159)
const { MAX_LENGTH, MAX_SAFE_INTEGER } = __nccwpck_require__(45101)
const { safeRe: re, t } = __nccwpck_require__(95471)
const { safeRe: re, safeSrc: src, t } = __nccwpck_require__(95471)
const parseOptions = __nccwpck_require__(70356)
const { compareIdentifiers } = __nccwpck_require__(73348)
@@ -42915,7 +42891,7 @@ class SemVer {
if (version instanceof SemVer) {
if (version.loose === !!options.loose &&
version.includePrerelease === !!options.includePrerelease) {
version.includePrerelease === !!options.includePrerelease) {
return version
} else {
version = version.version
@@ -43081,6 +43057,20 @@ class SemVer {
// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc (release, identifier, identifierBase) {
if (release.startsWith('pre')) {
if (!identifier && identifierBase === false) {
throw new Error('invalid increment argument: identifier is empty')
}
// Avoid an invalid semver results
if (identifier) {
const r = new RegExp(`^${this.options.loose ? src[t.PRERELEASELOOSE] : src[t.PRERELEASE]}$`)
const match = `-${identifier}`.match(r)
if (!match || match[1] !== identifier) {
throw new Error(`invalid identifier: ${identifier}`)
}
}
}
switch (release) {
case 'premajor':
this.prerelease.length = 0
@@ -43111,6 +43101,12 @@ class SemVer {
}
this.inc('pre', identifier, identifierBase)
break
case 'release':
if (this.prerelease.length === 0) {
throw new Error(`version ${this.raw} is not a prerelease`)
}
this.prerelease.length = 0
break
case 'major':
// If this is a pre-major version, bump up to the same major version.
@@ -43154,10 +43150,6 @@ class SemVer {
case 'pre': {
const base = Number(identifierBase) ? 1 : 0
if (!identifier && identifierBase === false) {
throw new Error('invalid increment argument: identifier is empty')
}
if (this.prerelease.length === 0) {
this.prerelease = [base]
} else {
@@ -43416,20 +43408,13 @@ const diff = (version1, version2) => {
return 'major'
}
// Otherwise it can be determined by checking the high version
if (highVersion.patch) {
// anything higher than a patch bump would result in the wrong version
// If the main part has no difference
if (lowVersion.compareMain(highVersion) === 0) {
if (lowVersion.minor && !lowVersion.patch) {
return 'minor'
}
return 'patch'
}
if (highVersion.minor) {
// anything higher than a minor bump would result in the wrong version
return 'minor'
}
// bumping major/minor/patch all have same result
return 'major'
}
// add the `pre` prefix if we are going to a prerelease version
@@ -43936,6 +43921,7 @@ exports = module.exports = {}
const re = exports.re = []
const safeRe = exports.safeRe = []
const src = exports.src = []
const safeSrc = exports.safeSrc = []
const t = exports.t = {}
let R = 0
@@ -43968,6 +43954,7 @@ const createToken = (name, value, isGlobal) => {
debug(name, index, value)
t[name] = index
src[index] = value
safeSrc[index] = safe
re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined)
}
@@ -56553,6 +56540,14 @@ const { isUint8Array, isArrayBuffer } = __nccwpck_require__(98253)
const { File: UndiciFile } = __nccwpck_require__(63041)
const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(94322)
let random
try {
const crypto = __nccwpck_require__(77598)
random = (max) => crypto.randomInt(0, max)
} catch {
random = (max) => Math.floor(Math.random(max))
}
let ReadableStream = globalThis.ReadableStream
/** @type {globalThis['File']} */
@@ -56638,7 +56633,7 @@ function extractBody (object, keepalive = false) {
// Set source to a copy of the bytes held by object.
source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength))
} else if (util.isFormDataLike(object)) {
const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}`
const boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, '0')}`
const prefix = `--${boundary}\r\nContent-Disposition: form-data`
/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
@@ -70859,6 +70854,7 @@ const inputs = {
subjectPath: core.getInput('subject-path'),
subjectName: core.getInput('subject-name'),
subjectDigest: core.getInput('subject-digest'),
subjectChecksums: core.getInput('subject-checksums'),
predicateType: core.getInput('predicate-type'),
predicate: core.getInput('predicate'),
predicatePath: core.getInput('predicate-path'),
@@ -70868,7 +70864,7 @@ const inputs = {
// undocumented -- not part of public interface
privateSigning: ['true', 'True', 'TRUE', '1'].includes(core.getInput('private-signing'))
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
(0, main_1.run)(inputs);
@@ -70970,8 +70966,12 @@ async function run(inputs) {
encoding: 'utf-8',
flag: 'a'
});
if (att.attestationID) {
core.setOutput('attestation-id', att.attestationID);
core.setOutput('attestation-url', attestationURL(att.attestationID));
}
if (inputs.showSummary) {
logSummary(att);
await logSummary(att);
}
}
catch (err) {
@@ -71014,13 +71014,13 @@ const logAttestation = (subjects, attestation, sigstoreInstance) => {
}
};
// Attach summary information to the GitHub Actions run
const logSummary = (attestation) => {
const logSummary = async (attestation) => {
const { attestationID } = attestation;
if (attestationID) {
const url = attestationURL(attestationID);
core.summary.addHeading('Attestation Created', 3);
core.summary.addList([`<a href="${url}">${url}</a>`]);
core.summary.write();
await core.summary.write();
}
};
const tempDir = () => {
@@ -71149,23 +71149,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.formatSubjectDigest = exports.subjectFromInputs = void 0;
const glob = __importStar(__nccwpck_require__(47206));
const assert_1 = __importDefault(__nccwpck_require__(42613));
const crypto_1 = __importDefault(__nccwpck_require__(76982));
const sync_1 = __nccwpck_require__(61110);
const fs_1 = __importDefault(__nccwpck_require__(79896));
const os_1 = __importDefault(__nccwpck_require__(70857));
const path_1 = __importDefault(__nccwpck_require__(16928));
const MAX_SUBJECT_COUNT = 1024;
const MAX_SUBJECT_CHECKSUM_SIZE_BYTES = 512 * MAX_SUBJECT_COUNT;
const DIGEST_ALGORITHM = 'sha256';
const HEX_STRING_RE = /^[0-9a-fA-F]+$/;
// Returns the subject specified by the action's inputs. The subject may be
// specified as a path to a file or as a digest. If a path is provided, the
// file's digest is calculated and returned along with the subject's name. If a
// digest is provided, the name must also be provided.
const subjectFromInputs = async (inputs) => {
const { subjectPath, subjectDigest, subjectName, downcaseName } = inputs;
if (!subjectPath && !subjectDigest) {
throw new Error('One of subject-path or subject-digest must be provided');
const { subjectPath, subjectDigest, subjectName, subjectChecksums, downcaseName } = inputs;
const enabledInputs = [subjectPath, subjectDigest, subjectChecksums].filter(Boolean);
if (enabledInputs.length === 0) {
throw new Error('One of subject-path, subject-digest, or subject-checksums must be provided');
}
if (subjectPath && subjectDigest) {
throw new Error('Only one of subject-path or subject-digest may be provided');
if (enabledInputs.length > 1) {
throw new Error('Only one of subject-path, subject-digest, or subject-checksums may be provided');
}
if (subjectDigest && !subjectName) {
throw new Error('subject-name must be provided when using subject-digest');
@@ -71173,11 +71178,17 @@ const subjectFromInputs = async (inputs) => {
// If push-to-registry is enabled, ensure the subject name is lowercase
// to conform to OCI image naming conventions
const name = downcaseName ? subjectName.toLowerCase() : subjectName;
if (subjectPath) {
return await getSubjectFromPath(subjectPath, name);
}
else {
return [getSubjectFromDigest(subjectDigest, name)];
switch (true) {
case !!subjectPath:
return getSubjectFromPath(subjectPath, name);
case !!subjectDigest:
return [getSubjectFromDigest(subjectDigest, name)];
case !!subjectChecksums:
return getSubjectFromChecksums(subjectChecksums);
/* istanbul ignore next */
default:
// This should be unreachable, but TS requires a default case
assert_1.default.fail('unreachable');
}
};
exports.subjectFromInputs = subjectFromInputs;
@@ -71193,9 +71204,8 @@ exports.formatSubjectDigest = formatSubjectDigest;
const getSubjectFromPath = async (subjectPath, subjectName) => {
const digestedSubjects = [];
// Parse the list of subject paths
const subjectPaths = parseList(subjectPath).join('\n');
const subjectPaths = parseSubjectPathList(subjectPath).join('\n');
// Expand the globbed paths to a list of actual paths
/* eslint-disable-next-line github/no-then */
const paths = await glob.create(subjectPaths).then(async (g) => g.glob());
// Filter path list to just the files (not directories)
const files = paths.filter(p => fs_1.default.statSync(p).isFile());
@@ -71205,7 +71215,10 @@ const getSubjectFromPath = async (subjectPath, subjectName) => {
for (const file of files) {
const name = subjectName || path_1.default.parse(file).base;
const digest = await digestFile(DIGEST_ALGORITHM, file);
digestedSubjects.push({ name, digest: { [DIGEST_ALGORITHM]: digest } });
// Only add the subject if it is not already in the list
if (!digestedSubjects.some(s => s.name === name && s.digest[DIGEST_ALGORITHM] === digest)) {
digestedSubjects.push({ name, digest: { [DIGEST_ALGORITHM]: digest } });
}
}
if (digestedSubjects.length === 0) {
throw new Error(`Could not find subject at path ${subjectPath}`);
@@ -71224,6 +71237,49 @@ const getSubjectFromDigest = (subjectDigest, subjectName) => {
digest: { [alg]: digest }
};
};
const getSubjectFromChecksums = (subjectChecksums) => {
if (fs_1.default.existsSync(subjectChecksums)) {
return getSubjectFromChecksumsFile(subjectChecksums);
}
else {
return getSubjectFromChecksumsString(subjectChecksums);
}
};
const getSubjectFromChecksumsFile = (checksumsPath) => {
const stats = fs_1.default.statSync(checksumsPath);
if (!stats.isFile()) {
throw new Error(`subject checksums file not found: ${checksumsPath}`);
}
/* istanbul ignore next */
if (stats.size > MAX_SUBJECT_CHECKSUM_SIZE_BYTES) {
throw new Error(`subject checksums file exceeds maximum allowed size: ${MAX_SUBJECT_CHECKSUM_SIZE_BYTES} bytes`);
}
const checksums = fs_1.default.readFileSync(checksumsPath, 'utf-8');
return getSubjectFromChecksumsString(checksums);
};
const getSubjectFromChecksumsString = (checksums) => {
const subjects = [];
const records = checksums.split(os_1.default.EOL).filter(Boolean);
for (const record of records) {
// Find the space delimiter following the digest
const delimIndex = record.indexOf(' ');
// Skip any line that doesn't have a delimiter
if (delimIndex === -1) {
continue;
}
// Swallow the type identifier character at the beginning of the name
const name = record.slice(delimIndex + 2);
const digest = record.slice(0, delimIndex);
if (!HEX_STRING_RE.test(digest)) {
throw new Error(`Invalid digest: ${digest}`);
}
subjects.push({
name,
digest: { [digestAlgorithm(digest)]: digest }
});
}
return subjects;
};
// Calculates the digest of a file using the specified algorithm. The file is
// streamed into the digest function to avoid loading the entire file into
// memory. The returned digest is a hex string.
@@ -71236,7 +71292,7 @@ const digestFile = async (algorithm, filePath) => {
.once('finish', () => resolve(hash.read()));
});
};
const parseList = (input) => {
const parseSubjectPathList = (input) => {
const res = [];
const records = (0, sync_1.parse)(input, {
columns: false,
@@ -71249,6 +71305,16 @@ const parseList = (input) => {
}
return res.filter(item => item).map(pat => pat.trim());
};
const digestAlgorithm = (digest) => {
switch (digest.length) {
case 64:
return 'sha256';
case 128:
return 'sha512';
default:
throw new Error(`Unknown digest algorithm: ${digest}`);
}
};
/***/ }),

5468
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "actions/attest",
"description": "Generate signed attestations for workflow artifacts",
"version": "2.0.0",
"version": "2.2.1",
"author": "",
"private": true,
"homepage": "https://github.com/actions/attest",
@@ -27,7 +27,7 @@
"ci-test": "jest",
"format:write": "prettier --write **/*.ts",
"format:check": "prettier --check **/*.ts",
"lint:eslint": "npx eslint . -c ./.github/linters/.eslintrc.yml",
"lint:eslint": "npx eslint . -c ./.github/linters/eslint.config.mjs",
"lint:markdown": "npx markdownlint --config .github/linters/.markdown-lint.yml \"*.md\"",
"lint": "npm run lint:eslint && npm run lint:markdown",
"package": "ncc build src/index.ts --license licenses.txt",
@@ -69,33 +69,31 @@
]
},
"dependencies": {
"@actions/attest": "^1.5.0",
"@actions/attest": "^1.6.0",
"@actions/core": "^1.11.1",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.5.0",
"@sigstore/oci": "^0.4.0",
"csv-parse": "^5.6.0"
},
"devDependencies": {
"@sigstore/mock": "^0.8.0",
"@eslint/js": "^9.21.0",
"@sigstore/mock": "^0.10.0",
"@types/jest": "^29.5.14",
"@types/make-fetch-happen": "^10.0.4",
"@types/node": "^22.9.4",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@types/node": "^22.13.5",
"@vercel/ncc": "^0.38.3",
"eslint": "^8.57.1",
"eslint-plugin-github": "^5.1.2",
"eslint-plugin-jest": "^28.9.0",
"eslint-plugin-jsonc": "^2.18.2",
"eslint-plugin-prettier": "^5.2.1",
"eslint": "^9.21.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^28.11.0",
"jest": "^29.7.0",
"js-yaml": "^4.1.0",
"markdownlint-cli": "^0.43.0",
"markdownlint-cli": "^0.44.0",
"nock": "^13.5.6",
"prettier": "^3.3.3",
"prettier-eslint": "^16.3.0",
"ts-jest": "^29.2.5",
"typescript": "^5.7.2",
"undici": "^5.28.4"
"prettier": "^3.5.2",
"ts-jest": "^29.2.6",
"typescript": "^5.7.3",
"typescript-eslint": "^8.25.0",
"undici": "^5.28.5"
}
}

View File

@@ -8,6 +8,7 @@ const inputs: RunInputs = {
subjectPath: core.getInput('subject-path'),
subjectName: core.getInput('subject-name'),
subjectDigest: core.getInput('subject-digest'),
subjectChecksums: core.getInput('subject-checksums'),
predicateType: core.getInput('predicate-type'),
predicate: core.getInput('predicate'),
predicatePath: core.getInput('predicate-path'),
@@ -20,5 +21,5 @@ const inputs: RunInputs = {
)
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
run(inputs)

View File

@@ -79,8 +79,13 @@ export async function run(inputs: RunInputs): Promise<void> {
flag: 'a'
})
if (att.attestationID) {
core.setOutput('attestation-id', att.attestationID)
core.setOutput('attestation-url', attestationURL(att.attestationID))
}
if (inputs.showSummary) {
logSummary(att)
await logSummary(att)
}
} catch (err) {
// Fail the workflow run if an error occurs
@@ -148,14 +153,14 @@ const logAttestation = (
}
// Attach summary information to the GitHub Actions run
const logSummary = (attestation: AttestResult): void => {
const logSummary = async (attestation: AttestResult): Promise<void> => {
const { attestationID } = attestation
if (attestationID) {
const url = attestationURL(attestationID)
core.summary.addHeading('Attestation Created', 3)
core.summary.addList([`<a href="${url}">${url}</a>`])
core.summary.write()
await core.summary.write()
}
}

View File

@@ -1,18 +1,23 @@
import * as glob from '@actions/glob'
import assert from 'assert'
import crypto from 'crypto'
import { parse } from 'csv-parse/sync'
import fs from 'fs'
import os from 'os'
import path from 'path'
import type { Subject } from '@actions/attest'
const MAX_SUBJECT_COUNT = 1024
const MAX_SUBJECT_CHECKSUM_SIZE_BYTES = 512 * MAX_SUBJECT_COUNT
const DIGEST_ALGORITHM = 'sha256'
const HEX_STRING_RE = /^[0-9a-fA-F]+$/
export type SubjectInputs = {
subjectPath: string
subjectName: string
subjectDigest: string
subjectChecksums: string
downcaseName?: boolean
}
// Returns the subject specified by the action's inputs. The subject may be
@@ -22,15 +27,26 @@ export type SubjectInputs = {
export const subjectFromInputs = async (
inputs: SubjectInputs
): Promise<Subject[]> => {
const { subjectPath, subjectDigest, subjectName, downcaseName } = inputs
const {
subjectPath,
subjectDigest,
subjectName,
subjectChecksums,
downcaseName
} = inputs
if (!subjectPath && !subjectDigest) {
throw new Error('One of subject-path or subject-digest must be provided')
const enabledInputs = [subjectPath, subjectDigest, subjectChecksums].filter(
Boolean
)
if (enabledInputs.length === 0) {
throw new Error(
'One of subject-path, subject-digest, or subject-checksums must be provided'
)
}
if (subjectPath && subjectDigest) {
if (enabledInputs.length > 1) {
throw new Error(
'Only one of subject-path or subject-digest may be provided'
'Only one of subject-path, subject-digest, or subject-checksums may be provided'
)
}
@@ -42,10 +58,17 @@ export const subjectFromInputs = async (
// to conform to OCI image naming conventions
const name = downcaseName ? subjectName.toLowerCase() : subjectName
if (subjectPath) {
return await getSubjectFromPath(subjectPath, name)
} else {
return [getSubjectFromDigest(subjectDigest, name)]
switch (true) {
case !!subjectPath:
return getSubjectFromPath(subjectPath, name)
case !!subjectDigest:
return [getSubjectFromDigest(subjectDigest, name)]
case !!subjectChecksums:
return getSubjectFromChecksums(subjectChecksums)
/* istanbul ignore next */
default:
// This should be unreachable, but TS requires a default case
assert.fail('unreachable')
}
}
@@ -65,10 +88,9 @@ const getSubjectFromPath = async (
const digestedSubjects: Subject[] = []
// Parse the list of subject paths
const subjectPaths = parseList(subjectPath).join('\n')
const subjectPaths = parseSubjectPathList(subjectPath).join('\n')
// Expand the globbed paths to a list of actual paths
/* eslint-disable-next-line github/no-then */
const paths = await glob.create(subjectPaths).then(async g => g.glob())
// Filter path list to just the files (not directories)
@@ -84,7 +106,14 @@ const getSubjectFromPath = async (
const name = subjectName || path.parse(file).base
const digest = await digestFile(DIGEST_ALGORITHM, file)
digestedSubjects.push({ name, digest: { [DIGEST_ALGORITHM]: digest } })
// Only add the subject if it is not already in the list
if (
!digestedSubjects.some(
s => s.name === name && s.digest[DIGEST_ALGORITHM] === digest
)
) {
digestedSubjects.push({ name, digest: { [DIGEST_ALGORITHM]: digest } })
}
}
if (digestedSubjects.length === 0) {
@@ -113,6 +142,62 @@ const getSubjectFromDigest = (
}
}
const getSubjectFromChecksums = (subjectChecksums: string): Subject[] => {
if (fs.existsSync(subjectChecksums)) {
return getSubjectFromChecksumsFile(subjectChecksums)
} else {
return getSubjectFromChecksumsString(subjectChecksums)
}
}
const getSubjectFromChecksumsFile = (checksumsPath: string): Subject[] => {
const stats = fs.statSync(checksumsPath)
if (!stats.isFile()) {
throw new Error(`subject checksums file not found: ${checksumsPath}`)
}
/* istanbul ignore next */
if (stats.size > MAX_SUBJECT_CHECKSUM_SIZE_BYTES) {
throw new Error(
`subject checksums file exceeds maximum allowed size: ${MAX_SUBJECT_CHECKSUM_SIZE_BYTES} bytes`
)
}
const checksums = fs.readFileSync(checksumsPath, 'utf-8')
return getSubjectFromChecksumsString(checksums)
}
const getSubjectFromChecksumsString = (checksums: string): Subject[] => {
const subjects: Subject[] = []
const records: string[] = checksums.split(os.EOL).filter(Boolean)
for (const record of records) {
// Find the space delimiter following the digest
const delimIndex = record.indexOf(' ')
// Skip any line that doesn't have a delimiter
if (delimIndex === -1) {
continue
}
// Swallow the type identifier character at the beginning of the name
const name = record.slice(delimIndex + 2)
const digest = record.slice(0, delimIndex)
if (!HEX_STRING_RE.test(digest)) {
throw new Error(`Invalid digest: ${digest}`)
}
subjects.push({
name,
digest: { [digestAlgorithm(digest)]: digest }
})
}
return subjects
}
// Calculates the digest of a file using the specified algorithm. The file is
// streamed into the digest function to avoid loading the entire file into
// memory. The returned digest is a hex string.
@@ -129,7 +214,7 @@ const digestFile = async (
})
}
const parseList = (input: string): string[] => {
const parseSubjectPathList = (input: string): string[] => {
const res: string[] = []
const records: string[][] = parse(input, {
@@ -145,3 +230,14 @@ const parseList = (input: string): string[] => {
return res.filter(item => item).map(pat => pat.trim())
}
const digestAlgorithm = (digest: string): string => {
switch (digest.length) {
case 64:
return 'sha256'
case 128:
return 'sha512'
default:
throw new Error(`Unknown digest algorithm: ${digest}`)
}
}