Compare commits

...

299 Commits

Author SHA1 Message Date
Daniel Kennedy 3a0ba4ba74 fix(tests): close sockets to remove a Jest warning about resources outliving their tests 2026-01-30 08:44:11 -05:00
Daniel Kennedy ae29a2751b @actions/cache: convert to an ESM module (#2275)
* `@actions/cache`: convert to an ESM module

* Update the fixture to ESM syntax

* Update the cache workflows

* Bump `@actions/glob` to `0.6.1`

* Fix awaiting in the cache unit tests

* Fix a type issues in contracts

* Export the `DownloadOptions`/`UploadOptions` like before

* More cache test fixes

* Make the cache units tests better

* Add some more logging

* Add retries to restore-cache.mjs
2026-01-29 14:23:32 -05:00
Daniel Kennedy b48854e1ac @actions/glob: fix minimatch imports (#2276) 2026-01-29 13:30:54 -05:00
Daniel Kennedy 9d912b1840 @actions/tool-cache: convert to an ESM module (#2274)
* `@actions/tool-cache`: convert to an ESM module

* Fix jest config

* Downgrade `nock` since it's conflicting with `@actions/attest`'s version
2026-01-29 11:26:14 -05:00
Daniel Kennedy 7a0147b5c6 @actions/glob: convert to an ESM module (#2273)
* `@actions/glob`: convert to an ESM module

* Update packages/glob/RELEASES.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-29 10:41:33 -05:00
Daniel Kennedy 5793b08cd9 @actions/artifact: convert to an ESM module (#2266)
* `@actions/artifact`: convert to an ESM module

* Update the package-lock.json

* Undo the GHES ignores

* Fix the reference to `@actions/http-client` in the lock file

* Bump `@actions/core` to `3.0.0`

* Remove `jest.config.cjs`

* Import `OctoKitOptions` from `@octokit/core/types`

* Pull the package version from `package.json`

* Workaround getting the package version for the user-agent

* Fix the `archiver` import

* Fix linting
2026-01-29 09:52:09 -05:00
Daniel Kennedy ed3ea3b5ba @actions/core: convert to ESM module 2026-01-28 20:50:58 -05:00
Daniel Kennedy c9c663babe Bump @actions/io to 3.0.2 2026-01-28 15:59:40 -05:00
Daniel Kennedy 0fc1805b46 @actions/exec: convert to ESM module 2026-01-28 15:59:40 -05:00
Daniel Kennedy a6e9f4bab2 @actions/io: update lock file version 2026-01-28 14:36:03 -05:00
Daniel Kennedy 758b556388 @actions/io: export lib/io-util 2026-01-28 14:08:19 -05:00
Daniel Kennedy 9e060cb3e1 Add release notes 2026-01-28 13:33:17 -05:00
Daniel Kennedy 5501ba08b7 @actions/io: convert to ESM module 2026-01-28 13:33:17 -05:00
Daniel Kennedy 4446f00fc7 Add a release entry for 4.0.0 2026-01-28 10:27:09 -05:00
Daniel Kennedy 965dcc7493 Fix a JSON lint issue 2026-01-28 10:27:09 -05:00
Daniel Kennedy d464f9dd60 Add proxy/interfaces exports 2026-01-28 10:27:09 -05:00
Daniel Kennedy c9ab4f9548 http-client: convert to ESM 2026-01-28 10:27:09 -05:00
Lokesh Gopu a2986ee511 Merge pull request #2260 from actions/lokesh755-actions-github-v9-esm
ESM-only with updated @octokit dependencies
2026-01-27 15:58:18 -05:00
Daniel Kennedy e827417593 Bump @actions/glob to 0.5.1 in @actions/cache 2026-01-27 15:43:44 -05:00
Lokesh Gopu b05d26b3fa ESM-only with updated @octokit dependencies 2026-01-27 15:35:32 -05:00
Daniel Kennedy ecdfc18bf2 Bump @actions/glob version to 0.5.1 2026-01-27 14:55:56 -05:00
Daniel Kennedy e8e0ce7ad8 Bump @actions/core to 2.0.3 on @actions/glob 2026-01-27 14:55:56 -05:00
Daniel Kennedy dc6427f3c3 Attest: undo the @actions/github/@octokit bumps 2026-01-27 13:31:31 -05:00
Daniel Kennedy 76339b5f68 Bump @actions/http-client and @actions/github on all packages 2026-01-27 13:31:31 -05:00
Daniel Kennedy c0ef67ec49 Release @actions/github v8.0.1 2026-01-27 10:29:06 -05:00
Daniel Kennedy 968fd7f8d3 Bump undici to v6.23.0 and @actions/http-client to v3.0.2 in @actions/github 2026-01-27 10:29:06 -05:00
Daniel Kennedy 9b27fa97f9 Release @actions/http-client version 3.0.2 2026-01-27 09:53:50 -05:00
Daniel Kennedy 065cf9f0b1 Bump undici to v6.23.0 in @actions/http-client 2026-01-27 09:38:40 -05:00
Lokesh Gopu b77f226465 Merge pull request #2249 from actions/fix/upgrade-octokit-dependencies
upgrade octokit dependencies
2026-01-22 14:46:12 -05:00
Lokesh Gopu f61ae48376 upgrade octokit dependencies 2026-01-22 11:59:59 -05:00
Salman Chishti 4236fc3e78 Merge pull request #2246 from actions/dependabot/npm_and_yarn/packages/attest/tar-7.5.6
chore(deps): bump tar from 7.5.2 to 7.5.6 in /packages/attest
2026-01-22 15:53:06 +00:00
Salman Chishti f366966232 Merge pull request #2248 from actions/dependabot/npm_and_yarn/lodash-4.17.23
chore(deps): bump lodash from 4.17.21 to 4.17.23
2026-01-22 14:48:46 +00:00
dependabot[bot] bd561a6765 chore(deps): bump lodash from 4.17.21 to 4.17.23
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-22 00:03:54 +00:00
dependabot[bot] 26490f0d3b chore(deps): bump tar from 7.5.2 to 7.5.6 in /packages/attest
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.2 to 7.5.6.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.2...v7.5.6)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-21 21:04:00 +00:00
Ryan Ghadimi ee91adfbc4 Merge pull request #2243 from GhadimiR/main
Don't retry 429s returned from the cache service
2026-01-16 10:43:35 +00:00
Ryan Ghadimi a039cff4a1 Add comment for rate limiting handling
Added a comment regarding rate limiting and retry behavior.
2026-01-16 10:26:45 +00:00
Ryan Ghadimi 9dd77993e7 Update packages/cache/RELEASES.md
Co-authored-by: Bassem Dghaidi <568794+Link-@users.noreply.github.com>
2026-01-16 10:25:44 +00:00
Ryan Ghadimi dd1bb93c72 New error type for cache RL 2026-01-16 10:00:15 +00:00
Ryan Ghadimi 7292b3508f update release doc 2026-01-16 09:51:21 +00:00
Ryan Ghadimi 4a47af6481 bump pkg 2026-01-16 09:46:28 +00:00
Ryan Ghadimi a68693e20a tests & releases 2026-01-16 09:44:57 +00:00
Ryan Ghadimi acf4bd70fb Add handling for 429s from cache service 2026-01-14 17:01:59 +00:00
Tingluo Huang 7ae5c2f423 Merge pull request #2237 from actions/users/tihuang/bump
Bump version to 2.2.0 and update dependencies for @actions/core, @actions/github, and @actions/http-client
2026-01-08 11:41:34 -05:00
Tingluo Huang d5470e6023 . 2026-01-08 16:19:53 +00:00
Tingluo Huang e68ab4b91a Bump version to 3.0.0 and update dependencies for @actions/core, @actions/github, and @actions/http-client 2026-01-08 14:34:05 +00:00
Tingluo Huang d3a48dd52f Merge pull request #2233 from actions/copilot/update-http-client-dependency
Update selected packages to consume @actions/http-client@3.0.1
2026-01-08 09:04:43 -05:00
Tingluo Huang c4d47c1922 Merge pull request #2236 from actions/users/tihuang/bump
Bump dependency version for actions/github and actions/tool-cache.
2026-01-08 08:38:35 -05:00
Tingluo Huang 5fc5cdde44 Bump dependency version for actions/github and actions/tool-cache. 2026-01-08 04:58:48 +00:00
copilot-swe-agent[bot] 2a9d836b08 Revert @actions/attest http-client dependency to ^2.2.3
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 23:17:02 +00:00
copilot-swe-agent[bot] 3a3b073ef2 Revert changes to github, tool-cache packages and .gitignore
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 22:38:20 +00:00
copilot-swe-agent[bot] d3a0fb260e Revert @actions/attest version to 2.1.0 - no new release needed
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 22:33:05 +00:00
copilot-swe-agent[bot] be4fdc505f Fix package-lock.json to mark typescript as dev dependency
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 22:10:30 +00:00
copilot-swe-agent[bot] 6be37922c5 Add .nx/ to .gitignore and remove cached build artifacts
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 22:04:45 +00:00
copilot-swe-agent[bot] dfc20acda2 Verify changes with tests - all package-specific tests passing
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 22:03:56 +00:00
copilot-swe-agent[bot] dc1fec82a6 Update all packages to use @actions/http-client@^3.0.1 and bump patch versions
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 21:55:41 +00:00
copilot-swe-agent[bot] 9339b3573b Initial plan 2026-01-07 21:51:58 +00:00
Tingluo Huang 67a08de5c7 Merge pull request #2231 from actions/copilot/prepare-http-client-release
Release @actions/http-client v3.0.1
2026-01-07 15:35:32 -05:00
copilot-swe-agent[bot] d73fffceed Combine duplicate RELEASES.md entries into single line
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 18:44:34 +00:00
copilot-swe-agent[bot] 16f0b3d28e Revert .gitignore change as requested
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 18:40:39 +00:00
copilot-swe-agent[bot] 398e2cb68b Change version from 3.1.0 to 3.0.1 as requested
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 18:31:01 +00:00
copilot-swe-agent[bot] 4b9031fa77 Bump http-client version to 3.1.0 and update RELEASES.md
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-07 18:13:07 +00:00
copilot-swe-agent[bot] 959cb66bd5 Initial plan 2026-01-07 18:02:29 +00:00
Tingluo Huang 3e0b611f99 Merge pull request #2229 from actions/copilot/extend-user-agent-http-requests
Extend user-agent with orchestration ID and add default user-agent
2026-01-07 10:42:56 -05:00
copilot-swe-agent[bot] 83c13c81ba Improve test cleanup and add missing test coverage
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 19:19:35 +00:00
copilot-swe-agent[bot] bccbba401a Fix lint error: remove unnecessary escape in regex
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 18:30:18 +00:00
copilot-swe-agent[bot] 3a191eecf6 Add default user-agent 'actions/http-client' when none provided
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 18:10:12 +00:00
copilot-swe-agent[bot] 97f5a6f0dc Simplify constructor by handling undefined in helper method
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 18:03:26 +00:00
copilot-swe-agent[bot] 48a7cdbf9c Remove .gitignore change for .nx/ directory
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:54:40 +00:00
copilot-swe-agent[bot] 3f1933edf9 Revert unrelated version bumps in package-lock.json files
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:50:28 +00:00
copilot-swe-agent[bot] 2215c8e5aa Restrict sanitization to only allow 0-9, a-z, _, -, .
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:37:28 +00:00
copilot-swe-agent[bot] af6de2cb95 Move orchestration ID logic to constructor for efficiency
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:30:28 +00:00
copilot-swe-agent[bot] 1dc58e3080 Rename github_orchestration_id to actions_orchestration_id
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:20:43 +00:00
copilot-swe-agent[bot] 20596c1d96 Move hyphen to end of character class for cleaner regex
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 16:30:09 +00:00
copilot-swe-agent[bot] 557f80fd03 Fix regex to properly escape hyphen in character class
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 16:28:52 +00:00
copilot-swe-agent[bot] 32c52bb78a Use product/version format and sanitize orchestration ID
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 16:26:29 +00:00
copilot-swe-agent[bot] 6d9a3fe547 Format code and update .gitignore to exclude .nx cache
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 15:36:15 +00:00
copilot-swe-agent[bot] 4e1c194b34 Add ACTIONS_ORCHESTRATION_ID support to http-client user-agent
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 15:32:55 +00:00
copilot-swe-agent[bot] 09cb71a033 Initial plan 2026-01-06 15:22:42 +00:00
Salman Chishti 2506e78e82 Merge pull request #2212 from actions/artifact-v5.0.1-release
docs(artifact): release @actions/artifact v5.0.1
2025-12-12 15:39:59 +00:00
Salman Muin Kayser Chishti f8003d52ff docs: add PR reference to artifact v5.0.1 release notes 2025-12-12 15:33:41 +00:00
Salman Muin Kayser Chishti e263dfb89d Merge remote-tracking branch 'origin/main' into artifact-v5.0.1-release 2025-12-12 15:33:18 +00:00
Salman Chishti 2e53bd8485 Merge pull request #2214 from actions/cache-v5.0.1-release
docs(cache): release @actions/cache v5.0.1
2025-12-12 15:30:16 +00:00
Salman Chishti b5e3b25b34 Merge pull request #2211 from actions/fix-artifact-storage-blob
fix(artifact): update @azure/storage-blob to fix Node.js 24 punycode deprecation
2025-12-12 15:29:23 +00:00
Salman Muin Kayser Chishti b71834a510 fix(artifact): update @azure/storage-blob to ^12.29.1 and remove deprecated packages 2025-12-12 15:01:31 +00:00
Salman Muin Kayser Chishti c6f0239e63 Merge remote-tracking branch 'origin/main' into fix-artifact-storage-blob 2025-12-12 14:59:31 +00:00
Salman Muin Kayser Chishti c655f38a0f docs(cache): add PR reference to v5.0.1 release notes 2025-12-12 14:53:26 +00:00
Salman Muin Kayser Chishti cf8caa4e0d Merge remote-tracking branch 'origin/main' into cache-v5.0.1-release 2025-12-12 14:50:27 +00:00
Salman Chishti 8734e578c6 Merge pull request #2213 from actions/fix-cache-storage-blob
fix(cache): update @azure/storage-blob to fix Node.js 24 punycode deprecation
2025-12-12 14:40:41 +00:00
Salman Muin Kayser Chishti 74ac6db523 fix(cache): update @azure/storage-blob to ^12.29.1 to address punycode deprecation 2025-12-12 14:05:14 +00:00
Salman Muin Kayser Chishti 6fc2f678c8 docs(cache): bump to v5.0.1 and add release notes 2025-12-12 13:42:58 +00:00
Salman Muin Kayser Chishti 5ef62e14dd fix(cache): update @azure/storage-blob to ^12.29.1 to fix punycode deprecation
- Updated @azure/storage-blob from ^12.13.0 to ^12.29.1
- Newer storage-blob uses @azure/core-rest-pipeline instead of deprecated @azure/core-http
- Fixes Node.js 24 deprecation warning for punycode module
2025-12-12 13:41:31 +00:00
Salman Muin Kayser Chishti 7b29e67278 docs(artifact): bump to v5.0.1 and add release notes 2025-12-12 13:40:07 +00:00
Salman Muin Kayser Chishti 9d2227dbb0 fix(artifact): update @azure/storage-blob to ^12.29.1 to fix punycode deprecation
- Removed direct @azure/core-http dependency
- Updated @azure/storage-blob from ^12.15.0 to ^12.29.1
- Newer storage-blob uses @azure/core-rest-pipeline instead of deprecated @azure/core-http
- Fixes Node.js 24 deprecation warning for punycode module
2025-12-12 13:38:13 +00:00
Salman Chishti 5a8462ec27 Merge pull request #2210 from actions/prepare-artifact-release
docs(artifact): add v5.0.0 release notes
2025-12-11 21:42:59 +00:00
Salman Muin Kayser Chishti fcaf488df6 chore(artifact): bump version to v5.0.0 2025-12-11 20:45:49 +00:00
Salman Muin Kayser Chishti 2b48e40e62 docs(artifact): add v5.0.0 release notes 2025-12-11 20:37:18 +00:00
Salman Chishti 44ec738e27 Merge pull request #2209 from actions/version-bumps
chore(artifact): bump dependencies for Node.js 24 support
2025-12-11 20:23:43 +00:00
Salman Muin Kayser Chishti 3af0128b01 chore(artifact): bump dependencies for Node.js 24 support 2025-12-11 19:20:51 +00:00
Salman Chishti e74405f68c Merge pull request #2194 from actions/prepare-cache-release-v5.0.0
Prepare cache v5 release
2025-12-11 16:00:48 +00:00
Salman Muin Kayser Chishti cc6abe3c3a chore(releases): update release notes for v5.0.0 to remove punycode deprecation warning 2025-12-11 14:43:23 +00:00
Salman Muin Kayser Chishti c6502bc679 PR number update in releases 2025-12-11 14:33:30 +00:00
Salman Muin Kayser Chishti bdd6eb4293 update releases 2025-12-11 14:32:58 +00:00
Salman Muin Kayser Chishti 6785788751 Merge remote-tracking branch 'origin/main' into prepare-cache-release-v5.0.0 2025-12-11 14:27:41 +00:00
Salman Chishti ddf2d52556 Merge pull request #2198 from actions/cache-bump-deps
chore(cache): bump @actions/* dependencies to v2/v3
2025-12-11 14:25:35 +00:00
Salman Muin Kayser Chishti 7c1b12a15e chore(cache): update @actions/core to 2.0.1 2025-12-11 13:57:58 +00:00
Salman Muin Kayser Chishti fdbf9e3ec2 Merge remote-tracking branch 'origin/main' into cache-bump-deps 2025-12-11 13:54:20 +00:00
Salman Muin Kayser Chishti 369aa55cdc update to core 2.0.1 which has exec 2.0.0 2025-12-11 13:54:17 +00:00
Brian DeHamer e1191599bb Merge pull request #2203 from actions/node-update-for-publish
Use node24 for publishing
2025-12-10 14:19:00 -08:00
Brian DeHamer c043714a35 use node24 for publishing
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-12-10 14:14:15 -08:00
Brian DeHamer 3ac6e0fdf2 Merge pull request #2201 from actions/npm-trusted-publishing
Enable npm trusted publishing
2025-12-10 13:32:35 -08:00
Brian DeHamer d9f9074fee npm trusted publishing
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-12-10 13:27:16 -08:00
Salman Chishti 2c52220624 Merge pull request #2199 from actions/core-bump-exec
prepare @actions/exec 2.0.1 relesae + chore(core): bump @actions/exec from ^1.1.1 to ^2.0.0
2025-12-10 12:08:47 +00:00
Salman Muin Kayser Chishti b2e6a5a284 chore(core): bump @actions/exec from ^1.1.1 to ^2.0.0
Aligns with cache package which already uses exec@2.0.0, avoiding nested duplicate dependencies.
2025-12-10 11:54:17 +00:00
Salman Muin Kayser Chishti e48877e66c chore(cache): bump @actions/* dependencies to v2/v3
- @actions/core: ^1.11.1 → ^2.0.0
- @actions/exec: ^1.0.1 → ^2.0.0
- @actions/glob: ^0.1.0 → ^0.5.0
- @actions/http-client: ^2.1.1 → ^3.0.0
- @actions/io: ^1.0.1 → ^2.0.0
2025-12-10 11:38:25 +00:00
Salman Chishti bdddd872e3 Merge pull request #2197 from actions/cache-remove-ms-rest-js
fix(cache): replace @azure/ms-rest-js with @azure/core-rest-pipeline
2025-12-10 11:36:53 +00:00
Salman Muin Kayser Chishti 8a2701f328 fix(cache): replace @azure/ms-rest-js with @azure/core-rest-pipeline
Remove abandoned @azure/ms-rest-js dependency which pulls in node-fetch@v2, causing punycode deprecation warnings on Node.js 24+.

The TransferProgressEvent type is now imported from @azure/core-rest-pipeline instead.
2025-12-10 11:23:06 +00:00
Salman Muin Kayser Chishti eb7ff8401e chore(cache): regenerate package-lock.json with Node 24 2025-12-10 11:09:56 +00:00
Salman Muin Kayser Chishti 45ec4a2087 chore: update dependencies and remove deprecated package
- Removed `@azure/ms-rest-js` dependency to fix Node.js 24+ punycode deprecation warning.
  - The `TransferProgressEvent` type is now imported from `@azure/core-rest-pipeline`.
- Updated `package.json` to reflect the new dependency.
- Updated tests to import `TransferProgressEvent` from the new package.
- Updated `package-lock.json` to remove `@azure/ms-rest-js` and include `@azure/core-rest-pipeline`.
- Bumped versions of several dependencies including `@azure/storage-blob` and `@azure/storage-common`.
2025-12-10 11:04:34 +00:00
Meredith Lancaster 02869fefb4 Merge pull request #2196 from actions/update-attest-storage-record-params
Refactor attest package createStorageRecord function params
2025-12-09 11:49:14 -08:00
Meredith Lancaster 701191f50e fix linter issues
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-09 11:40:40 -08:00
Meredith Lancaster 539724611c param name
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-09 11:39:12 -08:00
Meredith Lancaster 3d01d7ed69 Update packages/attest/README.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-09 11:38:06 -08:00
Meredith Lancaster d75223fd4a split mega param into several different ones
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-09 11:37:04 -08:00
Meredith Lancaster 056c217a52 Merge pull request #2192 from actions/malancas/create-artifact-metadata-storage-record
Add the `createStorageRecord` function to the `attest` package for creating artifact storage records
2025-12-09 08:55:21 -08:00
Meredith Lancaster d795a0ad0d linter fix
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-09 08:32:31 -08:00
Salman Muin Kayser Chishti b0464628c0 Prepare cache v5 release 2025-12-09 16:11:32 +00:00
Meredith Lancaster 0380590fdd fix expected endpoint response
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-09 08:02:38 -08:00
Salman Chishti 5e183dabac Merge pull request #2193 from actions/fix-audit-vulnerabilities
chore: fix npm audit vulnerabilities (glob, js-yaml)
2025-12-09 15:39:33 +00:00
Meredith Lancaster 97b7fa81c8 regenerate package lock
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 19:22:04 -08:00
Meredith Lancaster 87afd16bb2 bump to next minor version
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 19:19:29 -08:00
Meredith Lancaster c40fa0d905 formatting
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 19:19:11 -08:00
Meredith Lancaster dc9f635a0d Update packages/attest/src/artifactMetadata.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 16:30:37 -08:00
Meredith Lancaster 7847d31696 Update packages/attest/README.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 16:30:25 -08:00
Meredith Lancaster 10d3b034e0 fix linter issues
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 16:22:59 -08:00
Meredith Lancaster 8eca440361 fix test and function calls
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 15:59:25 -08:00
Meredith Lancaster 6ec87f46b7 add back param parsing function
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 15:39:26 -08:00
Meredith Lancaster d1f9584cda fix test calls
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 15:33:01 -08:00
Meredith Lancaster b8933d0495 reorganize function options and document
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 15:25:34 -08:00
Meredith Lancaster 0a988d204e rename file
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 15:16:26 -08:00
Meredith Lancaster 136f9dfe37 fix header link
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 14:07:17 -08:00
Meredith Lancaster ed78411ffb fix expected response
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 14:03:23 -08:00
Meredith Lancaster dd097c7f4e add section on createStorageRecord func
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 13:57:00 -08:00
Meredith Lancaster f01262913d table of contents
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 13:55:24 -08:00
Meredith Lancaster c034e76488 fix function exporting and test results
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 13:49:54 -08:00
Meredith Lancaster 9ca26d4946 regenerate package lock
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 13:17:18 -08:00
Meredith Lancaster 417dbfff73 use parameter objects and add tests
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 13:17:08 -08:00
Salman Muin Kayser Chishti 8883833d6d chore: fix npm audit vulnerabilities (glob, js-yaml) 2025-12-08 21:14:00 +00:00
Meredith Lancaster 79efd648ac condense parameters
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 11:02:59 -08:00
Meredith Lancaster e8c242695d add function for creating storage record
Signed-off-by: Meredith Lancaster <malancas@github.com>
2025-12-08 10:49:24 -08:00
Salman Chishti 48f166f6d5 Merge pull request #2175 from actions/prepare-core-1.12.0-release
Prepare @actions/core 2.0.0 release
2025-12-08 16:28:47 +00:00
Salman Muin Kayser Chishti 4bc377e1b4 Timeout time back to normal, as it was like this for debugging 2025-12-08 12:47:19 +00:00
Salman Muin Kayser Chishti bf1b64008f fix: use detached:true on all platforms for exec stream tests
On Windows, detached:true is needed to properly keep stdio handles
open after the parent process exits.
2025-12-08 12:35:33 +00:00
Salman Muin Kayser Chishti 894f77901e fix: improve exec stream tests cross-platform handling
- Update spawn-wait-for-file.js to use proper stdio inheritance
- Add small delay before exit to ensure child process inherits handles
- Simplify test code to use the helper script instead of shell commands
2025-12-08 12:28:52 +00:00
Tingting Wang 7993066184 Merge pull request #2174 from actions/dependabot/npm_and_yarn/packages/attest/tar-7.5.2
Bump tar from 7.5.1 to 7.5.2 in /packages/attest
2025-12-05 17:13:09 -08:00
dependabot[bot] f014075da9 Bump tar from 7.5.1 to 7.5.2 in /packages/attest
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.1 to 7.5.2.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.1...v7.5.2)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-06 01:06:03 +00:00
Tingting Wang 4500de75c1 Merge pull request #2187 from actions/dependabot/npm_and_yarn/packages/attest/glob-10.5.0
Bump glob from 10.4.5 to 10.5.0 in /packages/attest
2025-12-05 17:04:14 -08:00
dependabot[bot] 47017fa24b Bump glob from 10.4.5 to 10.5.0 in /packages/attest
Bumps [glob](https://github.com/isaacs/node-glob) from 10.4.5 to 10.5.0.
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v10.4.5...v10.5.0)

---
updated-dependencies:
- dependency-name: glob
  dependency-version: 10.5.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-19 17:36:35 +00:00
Salman Muin Kayser Chishti d97deb1f60 tests(exec): use platform-aware spawn options in spawn-wait-for-file script (detach on Unix, hide window on Windows) 2025-11-18 15:45:59 +00:00
Salman Muin Kayser Chishti df111e1104 tests(glob): set GITHUB_WORKSPACE to __dirname in hash-files.test 2025-11-18 15:32:19 +00:00
Salman Muin Kayser Chishti a3588a70ba update hash files test 2025-11-18 14:21:47 +00:00
Salman Chishti 6b63a2bfc3 Merge pull request #2176 from actions/prepare-exec-2.0.0-release
Prepare @actions/exec 2.0.0 release
2025-11-18 14:13:24 +00:00
Salman Muin Kayser Chishti 290017ff81 update package json 2025-11-04 13:53:28 +00:00
Salman Chishti 2a876cd69d Update packages/exec/RELEASES.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-04 13:50:24 +00:00
Salman Muin Kayser Chishti 7cba4c8084 npm install 2025-10-31 16:02:54 +00:00
Salman Muin Kayser Chishti f79b906406 Prepare @actions/exec 2.0.0 release 2025-10-31 15:55:29 +00:00
Salman Muin Kayser Chishti 1bcc453b44 Prepare @actions/core 2.0.0 release 2025-10-31 15:52:21 +00:00
Salman Chishti dcae869a03 Merge pull request #2167 from actions/prepare-http-client-3.0.0-release
Prepare @actions/http-client 3.0.0 release
2025-10-31 15:27:38 +00:00
Salman Chishti 23769d04c7 Merge pull request #2166 from actions/prepare-io-2.0.0-release
Prepare @actions/io 2.0.0 release
2025-10-31 15:27:26 +00:00
Daniel Kennedy d3ab50471b Merge pull request #2168 from actions/danwkennedy/prepare-4.0.0
Artifact: prepare `v4.0.0`
2025-10-24 13:38:36 -04:00
Daniel Kennedy 1388fd1cac Artifact: prepare 4.0.0 2025-10-24 13:28:26 -04:00
Bassem Dghaidi 5b446d2657 Merge pull request #2165 from austenstone/max-list-artifact-2k
fix: artifact pagination bugs and configurable artifact count limits
2025-10-24 17:23:44 +02:00
Austen Stone 006d6978c1 linting 2025-10-22 11:44:21 -04:00
Austen Stone 02afeb1577 style: wrap ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env var assignment for readability 2025-10-22 11:42:01 -04:00
Salman Chishti d47594b536 Update packages/http-client/RELEASES.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-22 15:44:09 +01:00
Salman Muin Kayser Chishti 2823824b94 Prepare @actions/http-client 3.0.0 release 2025-10-22 15:40:17 +01:00
Austen Stone cbc06d6766 fix: ensure max artifact count variable is treated as a string 2025-10-22 07:47:51 -04:00
Austen Stone 9bb6708527 fix: remove redundant check for max artifact count variable 2025-10-22 07:41:31 -04:00
Austen Stone be1151df02 Apply suggestion from @Link-
Co-authored-by: Bassem Dghaidi <568794+Link-@users.noreply.github.com>
2025-10-22 07:39:45 -04:00
Salman Muin Kayser Chishti 130842f4e8 Prepare @actions/io 2.0.0 release 2025-10-21 15:55:10 +01:00
Salman Chishti ab82301c62 Merge pull request #2164 from actions/prepare-attest-2.0.0-release
Prepare @actions/attest 2.0.0 release
2025-10-21 15:08:28 +01:00
Austen Stone fea4f6b5c5 fix: resolve critical pagination bugs and add comprehensive testing
- Fix off-by-one error in pagination loop (< to <=) that prevented fetching last page
- Add Math.ceil() to maxNumberOfPages calculation for proper limit handling
- Replace hardcoded 2000 limit with configurable getMaxArtifactListCount()
- Add pagination test for multi-page artifact listing
- Add environment variable test for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT
- Add comprehensive test coverage for getMaxArtifactListCount() function

Fixes compound bug where pagination and limit logic capped results at 900 artifacts instead of intended 1000.
2025-10-21 09:22:11 -04:00
Salman Muin Kayser Chishti d3ade9ecfc Prepare @actions/attest 2.0.0 release 2025-10-20 12:07:20 +01:00
functionstackx fb592eec03 Update packages/artifact/src/internal/find/list-artifacts.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-17 18:05:06 -04:00
functionstackx 70e79399a2 fix: bumping max list artifact to 2k 2025-10-16 23:13:34 -04:00
Eugene acb230b99a Merge pull request #2160 from actions/ejahnGithub-patch-1
Remove unnecessary Buffer to Uint8Array conversion
2025-10-16 12:22:23 -04:00
Eugene 5e0fa1aaaa Remove unnecessary Buffer to Uint8Array conversion
Removed unnecessary conversion of Buffer to Uint8Array for compatibility.
2025-10-16 12:08:05 -04:00
Salman Chishti ac2468e605 Support Nodejs.24 - Merge pull request #2110 from actions/salmanmkc/node24
Support Node.js 24
2025-10-16 16:25:47 +01:00
Salman Muin Kayser Chishti 3c8fcfce19 del file 2025-10-16 14:37:05 +01:00
Salman Muin Kayser Chishti 45467b9199 LInt 2025-10-16 14:34:09 +01:00
Salman Muin Kayser Chishti 700a55077d spacing 2025-10-16 14:27:39 +01:00
Salman Muin Kayser Chishti 6fa8f07827 Update based on testing to add trailing back slash to all results 2025-10-16 13:52:43 +01:00
Salman Muin Kayser Chishti d16e86a709 Add workflow to test readlink behavior on Windows across Node versions 2025-10-16 13:03:06 +01:00
Salman Muin Kayser Chishti ae3ac0db0c change back to lstat 2025-10-15 17:25:34 +01:00
Salman Muin Kayser Chishti b319d6afff Add comment to explain the method and return types 2025-10-15 17:14:54 +01:00
Salman Muin Kayser Chishti b8ac8fc14a lint 2025-10-15 17:08:33 +01:00
Salman Muin Kayser Chishti 028d621193 Merge remote-tracking branch 'origin/main' into salmanmkc/node24 2025-10-15 16:41:54 +01:00
Salman Muin Kayser Chishti b0d901f9c2 rebase led to this changing so reverting 2025-10-15 16:37:38 +01:00
Salman Muin Kayser Chishti 394e804dc8 remove skip lib check 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti d402248c45 Lint fix 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 66e8437b3e Revert "Io util package usage update"
This reverts commit 783332a4b57e9455ec3a361c4e16f659a35f3a97.
2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 9c7501a5f3 Io util package usage update 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 3b4b5725f0 Update packages, core doesn't need updates and update to use IO util update 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 9a364e607b update io utils 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 625c3f4856 change version for http-client 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 1c3a637017 Update documentation 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti ec0ca1b19b fix typo 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 57cd003e61 Update tests to use HTTPS for postman-echo.com and adjust proxy environment variable 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti b5befc6c6d Update HTTP tests to use HTTPS for postman-echo.com 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti 88a490d2ce override for node-fetch 2025-10-15 16:28:21 +01:00
Salman Muin Kayser Chishti a8d1fb0687 remove node 18 2025-10-15 16:27:29 +01:00
Salman Muin Kayser Chishti 347c887e54 package json 2025-10-15 16:27:29 +01:00
Salman Muin Kayser Chishti d5af54ee78 Update package versions 2025-10-15 16:27:29 +01:00
Salman Muin Kayser Chishti 44b9401378 Remove the need to update packages/core 2025-10-15 16:27:29 +01:00
Salman Muin Kayser Chishti fb5ae2a0e0 Keep attest at the same version 2025-10-15 16:27:29 +01:00
Salman Muin Kayser Chishti 8024983ab0 Update workflows and documentation to use the latest versions of first party actions that are available (checkout, setup-node, github-script)
=
2025-10-15 16:27:29 +01:00
Salman Muin Kayser Chishti d44f9b8f13 update some version numbers, will revise in a bit 2025-10-15 16:27:29 +01:00
Daniel Kennedy 9b4ee219ef fix: only mock the cpus() function on the os module instead of the whole module 2025-10-15 16:26:39 +01:00
Daniel Kennedy ee5d8970ad Take a direct dependency on @azure/core-http 2025-10-15 16:26:39 +01:00
dependabot[bot] 2874e3a741 Bump the artifact-minor-patch group in /packages/artifact with 5 updates
Bumps the artifact-minor-patch group in /packages/artifact with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) | `1.10.0` | `1.11.1` |
| [@azure/storage-blob](https://github.com/Azure/azure-sdk-for-js) | `12.15.0` | `12.28.0` |
| [@protobuf-ts/plugin](https://github.com/timostamm/protobuf-ts/tree/HEAD/packages/plugin) | `2.9.1` | `2.11.1` |
| [typedoc](https://github.com/TypeStrong/TypeDoc) | `0.25.4` | `0.28.13` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.2.2` | `5.9.2` |

Updates `@actions/core` from 1.10.0 to 1.11.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Updates `@azure/storage-blob` from 12.15.0 to 12.28.0
- [Release notes](https://github.com/Azure/azure-sdk-for-js/releases)
- [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md)
- [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/storage-blob_12.15.0...@azure/storage-blob_12.28.0)

Updates `@protobuf-ts/plugin` from 2.9.1 to 2.11.1
- [Release notes](https://github.com/timostamm/protobuf-ts/releases)
- [Commits](https://github.com/timostamm/protobuf-ts/commits/v2.11.1/packages/plugin)

Updates `typedoc` from 0.25.4 to 0.28.13
- [Release notes](https://github.com/TypeStrong/TypeDoc/releases)
- [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.25.4...v0.28.13)

Updates `typescript` from 5.2.2 to 5.9.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.2.2...v5.9.2)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-version: 1.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: "@azure/storage-blob"
  dependency-version: 12.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: "@protobuf-ts/plugin"
  dependency-version: 2.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: typedoc
  dependency-version: 0.28.13
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: typescript
  dependency-version: 5.9.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-15 16:25:54 +01:00
Daniel Kennedy ad4afeeff1 Update the group names 2025-10-15 16:24:47 +01:00
Daniel Kennedy f9bdf6a054 Dependabot: add support for /packages/artifact and `/packages/cache 2025-10-15 16:24:47 +01:00
Bassem Dghaidi 59c7ebde79 Prepapre cache v4.1.0 release 2025-10-15 16:24:47 +01:00
Ryan Ghadimi 0c907a43d3 no need to resolve 2025-10-15 16:23:02 +01:00
Ryan Ghadimi d1c1fc4108 lint 2025-10-15 16:23:02 +01:00
Ryan Ghadimi 36f30e6d37 new error state, tests to cover 2025-10-15 16:23:02 +01:00
Ryan Ghadimi 308e05bc50 remove cache size limit 2025-10-15 16:23:02 +01:00
Salman Muin Kayser Chishti 33a9b6c09c update with dist updates 2025-10-15 16:22:51 +01:00
Daniel Kennedy ddc5fa4ae8 Merge pull request #2133 from actions/danwkennedy/test-blob-stream-timeout
Test: add a timeout test for downloading chunks from the stream
2025-09-25 10:54:19 -04:00
Daniel Kennedy 9b08f07cd3 Fix linting 2025-09-25 09:26:13 -04:00
Daniel Kennedy d26e9423f4 Test: add a timeout test for downloading chunks from the stream 2025-09-25 09:11:38 -04:00
Daniel Kennedy 714f93aedc Merge pull request #2124 from akashchi/reject-on-download-failure
[ARTIFACT] Reject download promise if timeout was reached
2025-09-25 09:06:20 -04:00
Andrei Kashchikhin 844423665b lint 2025-09-25 10:53:34 +02:00
Daniel Kennedy f2ba502b92 Merge pull request #2136 from actions/dependabot/npm_and_yarn/packages/artifact/artifact-minor-patch-612b72ffd4
Bump the artifact-minor-patch group in /packages/artifact with 5 updates
2025-09-24 20:21:48 -04:00
Daniel Kennedy 1db3130eb3 fix: only mock the cpus() function on the os module instead of the whole module 2025-09-24 20:01:53 -04:00
Daniel Kennedy ca8a35d78f Take a direct dependency on @azure/core-http 2025-09-24 16:46:53 -04:00
dependabot[bot] f7f057193f Bump the artifact-minor-patch group in /packages/artifact with 5 updates
Bumps the artifact-minor-patch group in /packages/artifact with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) | `1.10.0` | `1.11.1` |
| [@azure/storage-blob](https://github.com/Azure/azure-sdk-for-js) | `12.15.0` | `12.28.0` |
| [@protobuf-ts/plugin](https://github.com/timostamm/protobuf-ts/tree/HEAD/packages/plugin) | `2.9.1` | `2.11.1` |
| [typedoc](https://github.com/TypeStrong/TypeDoc) | `0.25.4` | `0.28.13` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.2.2` | `5.9.2` |


Updates `@actions/core` from 1.10.0 to 1.11.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Updates `@azure/storage-blob` from 12.15.0 to 12.28.0
- [Release notes](https://github.com/Azure/azure-sdk-for-js/releases)
- [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md)
- [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/storage-blob_12.15.0...@azure/storage-blob_12.28.0)

Updates `@protobuf-ts/plugin` from 2.9.1 to 2.11.1
- [Release notes](https://github.com/timostamm/protobuf-ts/releases)
- [Commits](https://github.com/timostamm/protobuf-ts/commits/v2.11.1/packages/plugin)

Updates `typedoc` from 0.25.4 to 0.28.13
- [Release notes](https://github.com/TypeStrong/TypeDoc/releases)
- [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.25.4...v0.28.13)

Updates `typescript` from 5.2.2 to 5.9.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.2.2...v5.9.2)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-version: 1.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: "@azure/storage-blob"
  dependency-version: 12.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: "@protobuf-ts/plugin"
  dependency-version: 2.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: typedoc
  dependency-version: 0.28.13
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
- dependency-name: typescript
  dependency-version: 5.9.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: artifact-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 20:07:58 +00:00
Daniel Kennedy 8e146e124e Merge pull request #2134 from actions/danwkennedy/dependabot-artifact-cache
Dependabot: add support for `/packages/artifact` and `/packages/cache`
2025-09-24 16:06:29 -04:00
Daniel Kennedy 1ea77a84d7 Update the group names 2025-09-24 16:04:16 -04:00
Daniel Kennedy 7da95b182e Dependabot: add support for /packages/artifact and `/packages/cache 2025-09-24 16:00:44 -04:00
Andrei Kashchikhin 7c689a5156 use error in both reject and destroy 2025-09-24 17:05:25 +02:00
Andrei Kashchikhin 8c6c662cda Merge remote-tracking branch 'upstream/main' into reject-on-download-failure 2025-09-24 17:03:35 +02:00
Bassem Dghaidi 3898ed70c4 Merge pull request #2132 from actions/Link-/cache-4.1.0
Prepare cache `v4.1.0` release
2025-09-24 14:35:45 +02:00
Bassem Dghaidi 9a41b33065 Prepapre cache v4.1.0 release 2025-09-24 05:23:58 -07:00
Salman Muin Kayser Chishti 7aea3e735f changes 2025-09-08 15:37:51 +01:00
Salman Muin Kayser Chishti b1eb18b224 http 2025-09-08 15:36:39 +01:00
Salman Muin Kayser Chishti 48e42b1fdd linting 2025-09-04 15:24:57 +01:00
Salman Muin Kayser Chishti b738f10ef3 package updates 2025-09-04 15:15:02 +01:00
Salman Muin Kayser Chishti 8f32f385e0 Bump package versions, and fix issues 2025-09-04 14:16:27 +01:00
Salman Muin Kayser Chishti 011f07d1dc package changes 2025-09-04 12:58:54 +01:00
Salman Muin Kayser Chishti aa7077acfb Override to fix npm audit stuff 2025-09-04 12:49:31 +01:00
Salman Muin Kayser Chishti 86207b5042 remove engines 24 reuqirement from toolkit and fix test 2025-09-04 12:41:43 +01:00
Andrei Kashchikhin 523ce8ccda add reject 2025-09-01 11:52:11 +02:00
Ryan Ghadimi f58042f9cc Merge pull request #2118 from actions/ghadimir/cache_size_restriction
Remove 10GB Cache Size Limit for Cache Service V2
2025-08-21 15:14:38 +01:00
Ryan Ghadimi 091616a0b8 no need to resolve 2025-08-13 13:38:51 +00:00
Ryan Ghadimi 8da1e670b6 lint 2025-08-13 13:37:36 +00:00
Ryan Ghadimi 06f7fd9df1 new error state, tests to cover 2025-08-13 13:00:46 +00:00
Ryan Ghadimi 0fe20e9d56 remove cache size limit 2025-08-13 10:14:18 +00:00
Salman Muin Kayser Chishti f82db4c00b audit fix 2025-08-08 12:26:34 +01:00
Salman Muin Kayser Chishti b8cca0c71f fix lint errors 2025-08-08 04:02:29 +01:00
Salman Muin Kayser Chishti 6f0cb0c45e Merge branch 'main' into salmanmkc/node24 2025-08-08 03:54:30 +01:00
Salman Muin Kayser Chishti 944ede4d09 custom readlink implementation for Windows compatibility with trailing backslashes 2025-08-08 03:46:42 +01:00
Bassem Dghaidi 227b1ce741 Merge pull request #2115 from actions/Link-/release-4.0.5
Prepare release `4.0.5`
2025-08-07 13:08:34 +02:00
Bassem Dghaidi 447ee85f36 Prepare release 4.0.5 2025-08-07 04:00:47 -07:00
Bassem Dghaidi a6be3de743 Merge pull request #2114 from actions/Link-/fix-cache-tests
Update cache package compilation step to only install runtime dependencies
2025-08-07 12:58:32 +02:00
Bassem Dghaidi 26b94036cb Merge branch 'Link-/fix-cache-tests' of github.com:actions/toolkit into Link-/fix-cache-tests 2025-08-07 03:50:04 -07:00
Bassem Dghaidi f3e6fb165e Fix linter complaints 2025-08-07 03:49:51 -07:00
Bassem Dghaidi 3a607d0f00 Update .github/workflows/cache-tests.yml
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-07 12:40:20 +02:00
Bassem Dghaidi c9316bb4a7 Update cache package compilation step to install only runtime dependencies 2025-08-07 03:38:19 -07:00
Bassem Dghaidi ec43e5810d Merge pull request #2113 from actions/Link-/fix-runtime-deps
Reintroduce `@protobuf-ts/runtime-rpc` as a runtime dependency
2025-08-07 12:31:57 +02:00
Bassem Dghaidi 01715621b0 Replace @protobuf-ts/runtime with higher level dep @protobuf-ts/runtime-rpc 2025-08-07 03:21:24 -07:00
Bassem Dghaidi 6c64260c6d Reintroduce @protobuf-ts/runtime as a runtime dependency v2.11.1 2025-08-07 03:15:33 -07:00
Bassem Dghaidi bf3fc9226a Merge pull request #2111 from actions/Link-/cache-4.0.4
Prepare `@actions/cache` 4.0.4
2025-08-06 21:11:24 +02:00
Bassem Dghaidi c6723084aa Prepare release 4.0.4 2025-08-06 11:37:53 -07:00
Salman Muin Kayser Chishti bcb928642f format 2025-08-06 12:57:10 +01:00
Salman Muin Kayser Chishti 8c3fc9ed99 Update test to use mock 2025-08-06 12:49:50 +01:00
Salman Muin Kayser Chishti 1ef3214cee update for types 2025-08-01 11:50:25 +01:00
Salman Muin Kayser Chishti ece2273b24 updates 2025-07-31 23:48:44 +01:00
Salman Muin Kayser Chishti 717b895584 support node 24 2025-07-31 23:37:22 +01:00
Bassem Dghaidi 8ff772deb1 Merge pull request #2106 from actions/Link-/optimise-cache-deps
Move `@protobuf-ts/plugin` to dev dependencies
2025-07-31 14:03:14 +02:00
Bassem Dghaidi 8a3652e16d Optimise cache dependencies 2025-07-31 04:20:29 -07:00
Salman Chishti eb6226501b Merge pull request #2076 from esainane/what-the-word-is-is
Fix typo in `core/README.md`
2025-07-31 12:03:28 +01:00
Bassem Dghaidi d65ee66d9b Move @protobuf-ts/plugin to dev dependencies 2025-07-28 07:58:41 -07:00
Bassem Dghaidi 6d3feab2bf Merge pull request #2100 from actions/copilot/fix-2099
Improve cache service availability determination and implement conditional error logging
2025-07-28 16:49:10 +02:00
Bassem Dghaidi 79e1d8bb74 Merge pull request #2101 from actions/Link-/clarify-cache-hit-log
Explicit logging of cache key and restore key matches
2025-07-18 15:20:45 +02:00
copilot-swe-agent[bot] a0907ed2e2 Remove .nx/ from .gitignore as requested
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 13:49:49 +00:00
copilot-swe-agent[bot] bd54a2413a Fix v1 cache service to only check ACTIONS_CACHE_URL
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 13:39:13 +00:00
copilot-swe-agent[bot] 89397db14b Restore server error test and confirm logCacheError function removal
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 13:01:02 +00:00
copilot-swe-agent[bot] d48d6b62a4 Remove logCacheError function and implement inline 5xx error detection as requested
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 12:42:37 +00:00
copilot-swe-agent[bot] bab3dcf7f3 Complete PR feedback implementation: all cache tests passing
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 12:26:40 +00:00
copilot-swe-agent[bot] c51178a15e Implement 5xx server error detection and fix most cache tests
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 12:23:44 +00:00
copilot-swe-agent[bot] bbc6082700 Add .nx/ to .gitignore to exclude build cache files 2025-07-14 12:09:41 +00:00
copilot-swe-agent[bot] cf3aaeb491 Update tests to expect warnings instead of errors for non-5xx cache failures
Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 12:07:37 +00:00
Bassem Dghaidi cf4886cccb Fix linting issues 2025-07-14 03:49:28 -07:00
Bassem Dghaidi 0c5da92b52 Fix logging of cache key and restore key matches 2025-07-14 03:45:17 -07:00
copilot-swe-agent[bot] 513216f1dd Fix tests to expect errors instead of warnings for cache failures
- Update restoreCacheV2.test.ts, restoreCache.test.ts, saveCacheV2.test.ts, and saveCache.test.ts
- Change test expectations from core.warning to core.error for cache operation failures
- All tests now pass successfully

Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 10:38:47 +00:00
copilot-swe-agent[bot] 3c90578c30 Improve cache service availability determination and change warnings to errors
- Update isFeatureAvailable() to leverage ACTIONS_CACHE_SERVICE_V2 feature flag
- For v2: check ACTIONS_RESULTS_URL availability
- For v1: check either ACTIONS_CACHE_URL or ACTIONS_RESULTS_URL availability
- Change warning logs to error logs for cache failures
- Add comprehensive tests covering all scenarios

Co-authored-by: Link- <568794+Link-@users.noreply.github.com>
2025-07-14 10:32:34 +00:00
copilot-swe-agent[bot] be5a2ce677 Initial plan 2025-07-14 10:19:51 +00:00
Ben De St Paer-Gotch 683703c114 Merge pull request #2086 from actions/nebuk89-patch-1
Update README.md
2025-06-16 10:06:48 +01:00
Sai Nane dbb1ea35ff Fix typo in core/README.md 2025-05-27 04:27:17 +00:00
178 changed files with 11480 additions and 10113 deletions
+27
View File
@@ -0,0 +1,27 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "npm"
directory: "/packages/artifact"
schedule:
interval: "daily"
groups:
# Group minor and patch updates together but keep major separate
artifact-minor-patch:
update-types:
- "minor"
- "patch"
- package-ecosystem: "npm"
directory: "/packages/cache"
schedule:
interval: "daily"
groups:
# Group minor and patch updates together but keep major separate
cache-minor-patch:
update-types:
- "minor"
- "patch"
+11 -11
View File
@@ -22,12 +22,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set Node.js 20.x
uses: actions/setup-node@v4
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 20.x
node-version: 24.x
# Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
# without these to just compile the artifacts package
@@ -47,7 +47,7 @@ jobs:
echo -n 'hello from file 2' > artifact-path/second.txt
- name: Upload Artifacts
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const {default: artifact} = require('./packages/artifact/lib/artifact')
@@ -77,12 +77,12 @@ jobs:
needs: [upload]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set Node.js 20.x
uses: actions/setup-node@v4
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 20.x
node-version: 24.x
# Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
# without these to just compile the artifacts package
@@ -96,7 +96,7 @@ jobs:
working-directory: packages/artifact
- name: List and Download Artifacts
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const {default: artifactClient} = require('./packages/artifact/lib/artifact')
@@ -165,7 +165,7 @@ jobs:
}
}
- name: Delete Artifacts
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const {default: artifactClient} = require('./packages/artifact/lib/artifact')
+4 -4
View File
@@ -18,12 +18,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set Node.js 20.x
uses: actions/setup-node@v4
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 20.x
node-version: 24.x
- name: npm install
run: npm install
+10 -12
View File
@@ -22,12 +22,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set Node.js 20.x
uses: actions/setup-node@v4
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 20.x
node-version: 24.x
# In order to save & restore cache from a shell script, certain env variables need to be set that are only available in the
# node context. This runs a local action that gets and sets the necessary env variables that are needed
@@ -39,9 +39,11 @@ jobs:
- name: Install root npm packages
run: npm ci
# We need to install only runtime dependencies (omit dev dependencies) to verify that what we're shipping is all
# that is needed
- name: Compile cache package
run: |
npm ci
npm ci --omit=dev
npm run tsc
working-directory: packages/cache
@@ -53,10 +55,8 @@ jobs:
shell: bash
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache
# We're using node -e to call the functions directly available in the @actions/cache package
- name: Save cache using saveCache()
run: |
node -e "Promise.resolve(require('./packages/cache/lib/cache').saveCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
run: node packages/cache/__tests__/save-cache.mjs ${{ runner.os }} ${{ github.run_id }}
- name: Delete cache folders before restoring
shell: bash
@@ -65,8 +65,7 @@ jobs:
rm -rf ~/test-cache
- name: Restore cache using restoreCache() with http-client
run: |
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}',[],{useAzureSdk: false}))"
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} false
- name: Verify cache restored with http-client
shell: bash
@@ -81,8 +80,7 @@ jobs:
rm -rf ~/test-cache
- name: Restore cache using restoreCache() with Azure SDK
run: |
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} true
- name: Verify cache restored with Azure SDK
shell: bash
+7 -11
View File
@@ -17,16 +17,16 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v5
- shell: bash
run: |
rm "C:\Program Files\Git\usr\bin\tar.exe"
- name: Set Node.js 20.x
uses: actions/setup-node@v1
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 20.x
node-version: 24.x
# In order to save & restore cache from a shell script, certain env variables need to be set that are only available in the
# node context. This runs a local action that gets and sets the necessary env variables that are needed
@@ -52,10 +52,8 @@ jobs:
shell: bash
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache
# We're using node -e to call the functions directly available in the @actions/cache package
- name: Save cache using saveCache()
run: |
node -e "Promise.resolve(require('./packages/cache/lib/cache').saveCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
run: node packages/cache/__tests__/save-cache.mjs ${{ runner.os }} ${{ github.run_id }}
- name: Delete cache folders before restoring
shell: bash
@@ -64,8 +62,7 @@ jobs:
rm -rf ~/test-cache
- name: Restore cache using restoreCache() with http-client
run: |
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}',[],{useAzureSdk: false}))"
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} false
- name: Verify cache restored with http-client
shell: bash
@@ -80,8 +77,7 @@ jobs:
rm -rf ~/test-cache
- name: Restore cache using restoreCache() with Azure SDK
run: |
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} true
- name: Verify cache restored with Azure SDK
shell: bash
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
+9 -9
View File
@@ -28,15 +28,15 @@ jobs:
steps:
- name: setup repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: verify package exists
run: ls packages/${{ github.event.inputs.package }}
- name: Set Node.js 20.x
uses: actions/setup-node@v4
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 20.x
node-version: 24.x
- name: npm install
run: npm install
@@ -69,16 +69,16 @@ jobs:
id-token: write
steps:
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 24.x
- name: download artifact
uses: actions/download-artifact@v4
with:
name: ${{ github.event.inputs.package }}
- name: setup authentication
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> .npmrc
env:
NPM_TOKEN: ${{ secrets.TOKEN }}
- name: publish
run: npm publish --provenance *.tgz
+5 -5
View File
@@ -18,19 +18,19 @@ jobs:
matrix:
runs-on: [ubuntu-latest, macos-latest-large, windows-latest]
# Node 18 is the current default Node version in hosted runners, so users may still use the toolkit with it when running tests (see https://github.com/actions/toolkit/issues/1841)
# Node 20 is the currently support Node version for actions - https://docs.github.com/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runsusing-for-javascript-actions
node-version: [18.x, 20.x]
# Node 20 is the currently supported stable Node version for actions - https://docs.github.com/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runsusing-for-javascript-actions
# Node 24 is the new version being added with support in actions runners
node-version: [20.x, 24.x]
fail-fast: false
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node-version }}
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
if: ${{ github.repository_owner == 'actions' }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Update Octokit
working-directory: packages/github
run: |
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
os: [ubuntu-16.04, windows-2019]
runs-on: ${{matrix.os}}
actions:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
version: ${{matrix.node}}
- run: |
+1 -1
View File
@@ -18,7 +18,7 @@ e.g. To use https://github.com/actions/setup-node, users will author:
```yaml
steps:
using: actions/setup-node@v4
using: actions/setup-node@v5
```
# Define Metadata
+28 -2
View File
@@ -4,8 +4,34 @@ module.exports = {
roots: ['<rootDir>/packages'],
testEnvironment: 'node',
testMatch: ['**/__tests__/*.test.ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
'^@actions/core$': '<rootDir>/packages/core/lib/core.js',
'^@actions/exec$': '<rootDir>/packages/exec/lib/exec.js',
'^@actions/io$': '<rootDir>/packages/io/lib/io.js',
'^@actions/io/lib/io-util$': '<rootDir>/packages/io/lib/io-util.js',
'^@actions/http-client$': '<rootDir>/packages/http-client/lib/index.js',
'^@actions/http-client/lib/auth$': '<rootDir>/packages/http-client/lib/auth.js',
'^@actions/http-client/lib/interfaces$': '<rootDir>/packages/http-client/lib/interfaces.js',
'^@actions/github$': '<rootDir>/packages/github/lib/github.js',
'^@actions/github/lib/utils$': '<rootDir>/packages/github/lib/utils.js',
'^@actions/glob$': '<rootDir>/packages/glob/lib/glob.js',
'^@actions/tool-cache$': '<rootDir>/packages/tool-cache/lib/tool-cache.js',
'^@actions/cache$': '<rootDir>/packages/cache/lib/cache.js'
},
transform: {
'^.+\\.(ts|js)$': ['ts-jest', {
diagnostics: {warnOnly: true},
tsconfig: {
allowJs: true,
esModuleInterop: true,
module: 'commonjs',
moduleResolution: 'node'
}
}]
},
transformIgnorePatterns: [
'/node_modules/(?!(@octokit|@actions/github|@actions/http-client|@actions/io|@actions/exec|@actions/core|@actions/glob|@actions/tool-cache|@actions/cache|universal-user-agent|before-after-hook)/)'
],
verbose: true
}
+6685 -4916
View File
File diff suppressed because it is too large Load Diff
+16 -2
View File
@@ -1,6 +1,6 @@
{
"name": "root",
"private": true,
"private": true,
"scripts": {
"audit-all": "lerna run audit-moderate",
"bootstrap": "lerna exec -- npm install",
@@ -17,7 +17,7 @@
},
"devDependencies": {
"@types/jest": "^29.5.4",
"@types/node": "^20.5.7",
"@types/node": "^24.1.0",
"@types/signale": "^1.4.1",
"concurrently": "^6.1.0",
"eslint": "^8.0.1",
@@ -32,5 +32,19 @@
"prettier": "^3.0.0",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"overrides": {
"semver": "^7.6.0",
"tar": "^6.2.1",
"@octokit/plugin-paginate-rest": "^14.0.0",
"@octokit/request": "^10.0.7",
"@octokit/request-error": "^7.1.0",
"@octokit/core": "^7.0.6",
"tmp": "^0.2.4",
"@types/node": "^24.1.0",
"brace-expansion": "^2.0.2",
"form-data": "^4.0.4",
"uri-js": "npm:uri-js-replace@^1.0.1",
"node-fetch": "^3.3.2"
}
}
-1
View File
@@ -4,7 +4,6 @@ Interact programmatically with [Actions Artifacts](https://docs.github.com/en/ac
This is the core library that powers the [`@actions/upload-artifact`](https://github.com/actions/upload-artifact) and [`@actions/download-artifact`](https://github.com/actions/download-artifact) actions.
- [`@actions/artifact`](#actionsartifact)
- [v2 - What's New](#v2---whats-new)
- [Improvements](#improvements)
+66 -44
View File
@@ -1,122 +1,144 @@
# @actions/artifact Releases
### 2.3.3
## 5.0.3
- Bump `@actions/http-client` to `3.0.2`
## 5.0.1
- Fix Node.js 24 punycode deprecation warning by updating `@azure/storage-blob` from `^12.15.0` to `^12.29.1` [#2211](https://github.com/actions/toolkit/pull/2211)
- Removed direct `@azure/core-http` dependency (now uses `@azure/core-rest-pipeline` via storage-blob)
## 5.0.0
- Dependency updates for Node.js 24 runtime support
- Update `@actions/core` to v2
- Update `@actions/http-client` to v3
## 4.0.0
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
- Fix: artifact pagination bugs and configurable artifact count limits [#2165](https://github.com/actions/toolkit/pull/2165)
- Fix: reject the promise on timeout [#2124](https://github.com/actions/toolkit/pull/2124)
- Update dependency versions
## 2.3.3
- Dependency updates [#2049](https://github.com/actions/toolkit/pull/2049)
### 2.3.2
## 2.3.2
- Added masking for Shared Access Signature (SAS) artifact URLs [#1982](https://github.com/actions/toolkit/pull/1982)
- Change hash to digest for consistent terminology across runner logs [#1991](https://github.com/actions/toolkit/pull/1991)
- Change hash to digest for consistent terminology across runner logs [#1991](https://github.com/actions/toolkit/pull/1991)
### 2.3.1
## 2.3.1
- Fix comment typo on expectedHash. [#1986](https://github.com/actions/toolkit/pull/1986)
### 2.3.0
## 2.3.0
- Allow ArtifactClient to perform digest comparisons, if supplied. [#1975](https://github.com/actions/toolkit/pull/1975)
### 2.2.2
## 2.2.2
- Default concurrency to 5 for uploading artifacts [#1962](https://github.com/actions/toolkit/pull/1962)
### 2.2.1
## 2.2.1
- Add `ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY` and `ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS` environment variables [#1928](https://github.com/actions/toolkit/pull/1928)
### 2.2.0
## 2.2.0
- Return artifact digest on upload [#1896](https://github.com/actions/toolkit/pull/1896)
### 2.1.11
## 2.1.11
- Fixed a bug with relative symlinks resolution [#1844](https://github.com/actions/toolkit/pull/1844)
- Use native `crypto` [#1815](https://github.com/actions/toolkit/pull/1815)
### 2.1.10
## 2.1.10
- Fixed a regression with symlinks not being automatically resolved [#1830](https://github.com/actions/toolkit/pull/1830)
- Fixed a regression with chunk timeout [#1786](https://github.com/actions/toolkit/pull/1786)
### 2.1.9
## 2.1.9
- Fixed artifact upload chunk timeout logic [#1774](https://github.com/actions/toolkit/pull/1774)
- Use lazy stream to prevent issues with open file limits [#1771](https://github.com/actions/toolkit/pull/1771)
### 2.1.8
## 2.1.8
- Allows `*.localhost` domains for hostname checks for local development.
### 2.1.7
## 2.1.7
- Update unzip-stream dependency and reverted to using `unzip.Extract()`
### 2.1.6
## 2.1.6
- Will retry on invalid request responses.
### 2.1.5
## 2.1.5
- Bumped `archiver` dependency to 7.0.1
### 2.1.4
## 2.1.4
- Adds info-level logging for zip extraction
### 2.1.3
## 2.1.3
- Fixes a bug in the extract logic updated in 2.1.2
### 2.1.2
## 2.1.2
- Updated the stream extract functionality to use `unzip.Parse()` instead of `unzip.Extract()` for greater control of unzipping artifacts
### 2.1.1
## 2.1.1
- Updated `isGhes` check to include `.ghe.com` and `.ghe.localhost` as accepted hosts
### 2.1.0
## 2.1.0
- Added `ArtifactClient#deleteArtifact` to delete artifacts by name [#1626](https://github.com/actions/toolkit/pull/1626)
- Update error messaging to be more useful [#1628](https://github.com/actions/toolkit/pull/1628)
### 2.0.1
## 2.0.1
- Patch to fix transient request timeouts https://github.com/actions/download-artifact/issues/249
- Patch to fix transient request timeouts <https://github.com/actions/download-artifact/issues/249>
### 2.0.0
## 2.0.0
- Major release. Supports new Artifact backend for improved speed, reliability and behavior.
- Numerous API changes, [some breaking](./README.md#breaking-changes).
- [Blog post with more info](https://github.blog/2024-02-12-get-started-with-v4-of-github-actions-artifacts/)
### 1.1.1
## 1.1.1
- Fixed a bug in Node16 where if an HTTP download finished too quickly (<1ms, e.g. when it's mocked) we attempt to delete a temp file that has not been created yet [#1278](https://github.com/actions/toolkit/pull/1278/commits/b9de68a590daf37c6747e38d3cb4f1dd2cfb791c)
### 1.1.0
## 1.1.0
- Add `x-actions-results-crc64` and `x-actions-results-md5` checksum headers on upload [#1063](https://github.com/actions/toolkit/pull/1063)
### 1.0.2
## 1.0.2
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
### 1.0.1
## 1.0.1
- Update to v2.0.0 of `@actions/http-client`
### 1.0.0
## 1.0.0
- Update `lockfileVersion` to `v2` in `package-lock.json` [#1009](https://github.com/actions/toolkit/pull/1009)
### 0.6.1
## 0.6.1
- Fix for failing 0 byte file uploads on Windows [#962](https://github.com/actions/toolkit/pull/962)
### 0.6.0
## 0.6.0
- Support upload from named pipes [#748](https://github.com/actions/toolkit/pull/748)
- Fixes to percentage values being greater than 100% when downloading all artifacts [#889](https://github.com/actions/toolkit/pull/889)
@@ -125,49 +147,49 @@
- Faster upload speeds for certain types of large files by exempting gzip compression [#956](https://github.com/actions/toolkit/pull/956)
- More detailed logging when dealing with chunked uploads [#957](https://github.com/actions/toolkit/pull/957)
### 0.5.2
## 0.5.2
- Add HTTP 500 as a retryable status code for artifact upload and download.
### 0.5.1
## 0.5.1
- Bump @actions/http-client to version 1.0.11 to fix proxy related issues during artifact upload and download
### 0.5.0
## 0.5.0
- Improved retry-ability for all http calls during artifact upload and download if an error is encountered
### 0.4.2
## 0.4.2
- Improved retry-ability when a partial artifact download is encountered
### 0.4.1
## 0.4.1
- Update to latest @actions/core version
### 0.4.0
## 0.4.0
- Add option to specify custom retentions on artifacts
-
### 0.3.5
## 0.3.5
- Retry in the event of a 413 response
### 0.3.3
## 0.3.3
- Increase chunk size during upload from 4MB to 8MB
- Improve user-agent strings during API calls to help internally diagnose issues
### 0.3.2
## 0.3.2
- Fix to ensure readstreams get correctly reset in the event of a retry
### 0.3.1
## 0.3.1
- Fix to ensure temporary gzip files get correctly deleted during artifact upload
- Remove spaces as a forbidden character during upload
### 0.3.0
## 0.3.0
- Fixes to gzip decompression when downloading artifacts
- Support handling 429 response codes
@@ -176,13 +198,13 @@
- Clearer error message if storage quota has been reached
- Improved logging and output during artifact download
### 0.2.0
## 0.2.0
- Fixes to TCP connections not closing
- GZip file compression to speed up downloads
- Improved logging and output
- Extra documentation
### 0.1.0
## 0.1.0
- Initial release
@@ -1,10 +1,10 @@
import * as http from 'http'
import * as net from 'net'
import {HttpClient} from '@actions/http-client'
import * as config from '../src/internal/shared/config'
import {internalArtifactTwirpClient} from '../src/internal/shared/artifact-twirp-client'
import {noopLogs} from './common'
import {NetworkError, UsageError} from '../src/internal/shared/errors'
import * as config from '../src/internal/shared/config.js'
import {internalArtifactTwirpClient} from '../src/internal/shared/artifact-twirp-client.js'
import {noopLogs} from './common.js'
import {NetworkError, UsageError} from '../src/internal/shared/errors.js'
jest.mock('@actions/http-client')
+51 -5
View File
@@ -1,10 +1,14 @@
import * as config from '../src/internal/shared/config'
import * as config from '../src/internal/shared/config.js'
import os from 'os'
// Mock the 'os' module
jest.mock('os', () => ({
cpus: jest.fn()
}))
// Mock the `cpus()` function in the `os` module
jest.mock('os', () => {
const osActual = jest.requireActual('os')
return {
...osActual,
cpus: jest.fn()
}
})
beforeEach(() => {
jest.resetModules()
@@ -101,3 +105,45 @@ describe('uploadConcurrencyEnv', () => {
}).toThrow()
})
})
describe('getMaxArtifactListCount', () => {
beforeEach(() => {
delete process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT
})
it('should return default 1000 when no env set', () => {
expect(config.getMaxArtifactListCount()).toBe(1000)
})
it('should return value set in ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT', () => {
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '2000'
expect(config.getMaxArtifactListCount()).toBe(2000)
})
it('should throw if value set in ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT is invalid', () => {
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = 'abc'
expect(() => {
config.getMaxArtifactListCount()
}).toThrow(
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
)
})
it('should throw if ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT is < 1', () => {
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '0'
expect(() => {
config.getMaxArtifactListCount()
}).toThrow(
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
)
})
it('should throw if ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT is negative', () => {
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '-100'
expect(() => {
config.getMaxArtifactListCount()
}).toThrow(
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
)
})
})
@@ -4,11 +4,11 @@ import type {RequestInterface} from '@octokit/types'
import {
deleteArtifactInternal,
deleteArtifactPublic
} from '../src/internal/delete/delete-artifact'
import * as config from '../src/internal/shared/config'
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated'
import * as util from '../src/internal/shared/util'
import {noopLogs} from './common'
} from '../src/internal/delete/delete-artifact.js'
import * as config from '../src/internal/shared/config.js'
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated/index.js'
import * as util from '../src/internal/shared/util.js'
import {noopLogs} from './common.js'
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
@@ -11,12 +11,12 @@ import {
downloadArtifactInternal,
downloadArtifactPublic,
streamExtractExternal
} from '../src/internal/download/download-artifact'
import {getUserAgentString} from '../src/internal/shared/user-agent'
import {noopLogs} from './common'
import * as config from '../src/internal/shared/config'
import {ArtifactServiceClientJSON} from '../src/generated'
import * as util from '../src/internal/shared/util'
} from '../src/internal/download/download-artifact.js'
import {getUserAgentString} from '../src/internal/shared/user-agent.js'
import {noopLogs} from './common.js'
import * as config from '../src/internal/shared/config.js'
import {ArtifactServiceClientJSON} from '../src/generated/index.js'
import * as util from '../src/internal/shared/util.js'
type MockedDownloadArtifact = jest.MockedFunction<
RestEndpointMethods['actions']['downloadArtifact']
@@ -111,6 +111,16 @@ const mockGetArtifactSuccess = jest.fn(() => {
}
})
const mockGetArtifactHung = jest.fn(() => {
const message = new http.IncomingMessage(new net.Socket())
message.statusCode = 200
// Don't push any data or call push(null) to end the stream
// This creates a stream that hangs and never completes
return {
message
}
})
const mockGetArtifactFailure = jest.fn(() => {
const message = new http.IncomingMessage(new net.Socket())
message.statusCode = 500
@@ -611,4 +621,32 @@ describe('download-artifact', () => {
})
})
})
describe('streamExtractExternal', () => {
it('should fail if the timeout is exceeded', async () => {
const mockSlowGetArtifact = jest.fn(mockGetArtifactHung)
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
() => {
return {
get: mockSlowGetArtifact
}
}
)
try {
await streamExtractExternal(
fixtures.blobStorageUrl,
fixtures.workspaceDir,
{timeout: 2}
)
expect(true).toBe(false) // should not be called
} catch (e) {
expect(e).toBeInstanceOf(Error)
expect(e.message).toContain('did not respond in 2ms')
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
expect(mockSlowGetArtifact).toHaveBeenCalledTimes(1)
}
})
})
})
@@ -3,15 +3,15 @@ import type {RequestInterface} from '@octokit/types'
import {
getArtifactInternal,
getArtifactPublic
} from '../src/internal/find/get-artifact'
import * as config from '../src/internal/shared/config'
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated'
import * as util from '../src/internal/shared/util'
import {noopLogs} from './common'
} from '../src/internal/find/get-artifact.js'
import * as config from '../src/internal/shared/config.js'
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated/index.js'
import * as util from '../src/internal/shared/util.js'
import {noopLogs} from './common.js'
import {
ArtifactNotFoundError,
InvalidResponseError
} from '../src/internal/shared/errors'
} from '../src/internal/shared/errors.js'
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
@@ -3,12 +3,12 @@ import type {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-method
import {
listArtifactsInternal,
listArtifactsPublic
} from '../src/internal/find/list-artifacts'
import * as config from '../src/internal/shared/config'
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated'
import * as util from '../src/internal/shared/util'
import {noopLogs} from './common'
import {Artifact} from '../src/internal/shared/interfaces'
} from '../src/internal/find/list-artifacts.js'
import * as config from '../src/internal/shared/config.js'
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated/index.js'
import * as util from '../src/internal/shared/util.js'
import {noopLogs} from './common.js'
import {Artifact} from '../src/internal/shared/interfaces.js'
import {RequestInterface} from '@octokit/types'
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
@@ -170,6 +170,126 @@ describe('list-artifact', () => {
)
).rejects.toThrow('boom')
})
it('should handle pagination correctly when fetching multiple pages', async () => {
const mockRequest = github.getOctokit(fixtures.token)
.request as MockedRequest
const manyArtifacts = Array.from({length: 150}, (_, i) => ({
id: i + 1,
name: `artifact-${i + 1}`,
size: 100,
createdAt: new Date('2023-12-01')
}))
mockRequest
.mockResolvedValueOnce({
status: 200,
headers: {},
url: '',
data: {
...artifactsToListResponse(manyArtifacts.slice(0, 100)),
total_count: 150
}
})
.mockResolvedValueOnce({
status: 200,
headers: {},
url: '',
data: {
...artifactsToListResponse(manyArtifacts.slice(100, 150)),
total_count: 150
}
})
const response = await listArtifactsPublic(
fixtures.runId,
fixtures.owner,
fixtures.repo,
fixtures.token,
false
)
// Verify that both API calls were made
expect(mockRequest).toHaveBeenCalledTimes(2)
// Should return all 150 artifacts across both pages
expect(response.artifacts).toHaveLength(150)
// Verify we got artifacts from both pages
expect(response.artifacts[0].name).toBe('artifact-1')
expect(response.artifacts[99].name).toBe('artifact-100')
expect(response.artifacts[100].name).toBe('artifact-101')
expect(response.artifacts[149].name).toBe('artifact-150')
})
it('should respect ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT environment variable', async () => {
const originalEnv = process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '150'
jest.resetModules()
try {
const {listArtifactsPublic: listArtifactsPublicReloaded} = await import(
'../src/internal/find/list-artifacts'
)
const githubReloaded = await import('@actions/github')
const mockRequest = (githubReloaded.getOctokit as jest.Mock)(
fixtures.token
).request as MockedRequest
const manyArtifacts = Array.from({length: 200}, (_, i) => ({
id: i + 1,
name: `artifact-${i + 1}`,
size: 100,
createdAt: new Date('2023-12-01')
}))
mockRequest
.mockResolvedValueOnce({
status: 200,
headers: {},
url: '',
data: {
...artifactsToListResponse(manyArtifacts.slice(0, 100)),
total_count: 200
}
})
.mockResolvedValueOnce({
status: 200,
headers: {},
url: '',
data: {
...artifactsToListResponse(manyArtifacts.slice(100, 150)),
total_count: 200
}
})
const response = await listArtifactsPublicReloaded(
fixtures.runId,
fixtures.owner,
fixtures.repo,
fixtures.token,
false
)
// Should only return 150 artifacts due to the limit
expect(response.artifacts).toHaveLength(150)
expect(response.artifacts[0].name).toBe('artifact-1')
expect(response.artifacts[149].name).toBe('artifact-150')
} finally {
// Restore original environment variable
if (originalEnv !== undefined) {
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = originalEnv
} else {
delete process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT
}
// Reset modules again to restore original state
jest.resetModules()
}
})
})
describe('internal', () => {
@@ -1,9 +1,9 @@
import {
validateArtifactName,
validateFilePath
} from '../src/internal/upload/path-and-artifact-name-validation'
} from '../src/internal/upload/path-and-artifact-name-validation.js'
import {noopLogs} from './common'
import {noopLogs} from './common.js'
describe('Path and artifact name validation', () => {
beforeAll(() => {
@@ -1,5 +1,5 @@
import {Timestamp} from '../src/generated'
import * as retention from '../src/internal/upload/retention'
import {Timestamp} from '../src/generated/index.js'
import * as retention from '../src/internal/upload/retention.js'
describe('retention', () => {
beforeEach(() => {
@@ -1,12 +1,12 @@
import * as uploadZipSpecification from '../src/internal/upload/upload-zip-specification'
import * as zip from '../src/internal/upload/zip'
import * as util from '../src/internal/shared/util'
import * as config from '../src/internal/shared/config'
import {ArtifactServiceClientJSON} from '../src/generated'
import * as blobUpload from '../src/internal/upload/blob-upload'
import {uploadArtifact} from '../src/internal/upload/upload-artifact'
import {noopLogs} from './common'
import {FilesNotFoundError} from '../src/internal/shared/errors'
import * as uploadZipSpecification from '../src/internal/upload/upload-zip-specification.js'
import * as zip from '../src/internal/upload/zip.js'
import * as util from '../src/internal/shared/util.js'
import * as config from '../src/internal/shared/config.js'
import {ArtifactServiceClientJSON} from '../src/generated/index.js'
import * as blobUpload from '../src/internal/upload/blob-upload.js'
import {uploadArtifact} from '../src/internal/upload/upload-artifact.js'
import {noopLogs} from './common.js'
import {FilesNotFoundError} from '../src/internal/shared/errors.js'
import {BlockBlobUploadStreamOptions} from '@azure/storage-blob'
import * as fs from 'fs'
import * as path from 'path'
@@ -108,7 +108,7 @@ describe('upload-artifact', () => {
fixtures.files.map(file => ({
sourcePath: path.join(fixtures.uploadDirectory, file.name),
destinationPath: file.name,
stats: new fs.Stats()
stats: fs.statSync(path.join(fixtures.uploadDirectory, file.name))
}))
)
jest.spyOn(config, 'getRuntimeToken').mockReturnValue(fixtures.runtimeToken)
@@ -4,8 +4,8 @@ import {promises as fs} from 'fs'
import {
getUploadZipSpecification,
validateRootDirectory
} from '../src/internal/upload/upload-zip-specification'
import {noopLogs} from './common'
} from '../src/internal/upload/upload-zip-specification.js'
import {noopLogs} from './common.js'
const root = path.join(__dirname, '_temp', 'upload-specification')
const goodItem1Path = path.join(
+3 -3
View File
@@ -1,6 +1,6 @@
import * as config from '../src/internal/shared/config'
import * as util from '../src/internal/shared/util'
import {maskSigUrl, maskSecretUrls} from '../src/internal/shared/util'
import * as config from '../src/internal/shared/config.js'
import * as util from '../src/internal/shared/util.js'
import {maskSigUrl, maskSecretUrls} from '../src/internal/shared/util.js'
import {setSecret, debug} from '@actions/core'
export const testRuntimeToken =
+917 -788
View File
File diff suppressed because it is too large Load Diff
+28 -16
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/artifact",
"version": "2.3.3",
"version": "6.0.0",
"preview": true,
"description": "Actions artifact lib",
"keywords": [
@@ -10,8 +10,15 @@
],
"homepage": "https://github.com/actions/toolkit/tree/main/packages/artifact",
"license": "MIT",
"type": "module",
"main": "lib/artifact.js",
"types": "lib/artifact.d.ts",
"exports": {
".": {
"types": "./lib/artifact.d.ts",
"import": "./lib/artifact.js"
}
},
"directories": {
"lib": "lib",
"test": "__tests__"
@@ -32,7 +39,7 @@
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
"test": "cd ../../ && npm run test ./packages/artifact",
"bootstrap": "cd ../../ && npm run bootstrap",
"tsc-run": "tsc",
"tsc-run": "tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/",
"tsc": "npm run bootstrap && npm run tsc-run",
"gen:docs": "typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"
},
@@ -40,25 +47,30 @@
"url": "https://github.com/actions/toolkit/issues"
},
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/github": "^6.0.1",
"@actions/http-client": "^2.1.0",
"@azure/storage-blob": "^12.15.0",
"@octokit/core": "^5.2.1",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-retry": "^3.0.9",
"@octokit/request": "^8.4.1",
"@octokit/request-error": "^5.1.1",
"@actions/core": "^3.0.0",
"@actions/github": "^9.0.0",
"@actions/http-client": "^4.0.0",
"@azure/storage-blob": "^12.30.0",
"@octokit/core": "^7.0.6",
"@octokit/plugin-request-log": "^6.0.0",
"@octokit/plugin-retry": "^8.0.0",
"@octokit/request": "^10.0.7",
"@octokit/request-error": "^7.1.0",
"@protobuf-ts/plugin": "^2.2.3-alpha.1",
"@protobuf-ts/runtime": "^2.9.4",
"archiver": "^7.0.1",
"jwt-decode": "^3.1.2",
"jwt-decode": "^4.0.0",
"unzip-stream": "^0.3.1"
},
"devDependencies": {
"@types/archiver": "^5.3.2",
"@types/archiver": "^7.0.0",
"@types/unzip-stream": "^0.3.4",
"typedoc": "^0.25.4",
"typedoc-plugin-markdown": "^3.17.1",
"typescript": "^5.2.2"
"typedoc": "^0.28.16",
"typedoc-plugin-markdown": "^4.9.0",
"typescript": "^5.9.3"
},
"overrides": {
"uri-js": "npm:uri-js-replace@^1.0.1",
"node-fetch": "^3.3.2"
}
}
+4 -4
View File
@@ -1,8 +1,8 @@
import {ArtifactClient, DefaultArtifactClient} from './internal/client'
import {ArtifactClient, DefaultArtifactClient} from './internal/client.js'
export * from './internal/shared/interfaces'
export * from './internal/shared/errors'
export * from './internal/client'
export * from './internal/shared/interfaces.js'
export * from './internal/shared/errors.js'
export * from './internal/client.js'
const client: ArtifactClient = new DefaultArtifactClient()
export default client
+4 -4
View File
@@ -1,4 +1,4 @@
export * from './google/protobuf/timestamp'
export * from './google/protobuf/wrappers'
export * from './results/api/v1/artifact'
export * from './results/api/v1/artifact.twirp-client'
export * from './google/protobuf/timestamp.js'
export * from './google/protobuf/wrappers.js'
export * from './results/api/v1/artifact.js'
export * from './results/api/v1/artifact.twirp-client.js'
@@ -12,9 +12,9 @@ import type { PartialMessage } from "@protobuf-ts/runtime";
import { reflectionMergePartial } from "@protobuf-ts/runtime";
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
import { MessageType } from "@protobuf-ts/runtime";
import { Int64Value } from "../../../google/protobuf/wrappers";
import { StringValue } from "../../../google/protobuf/wrappers";
import { Timestamp } from "../../../google/protobuf/timestamp";
import { Int64Value } from "../../../google/protobuf/wrappers.js";
import { StringValue } from "../../../google/protobuf/wrappers.js";
import { Timestamp } from "../../../google/protobuf/timestamp.js";
/**
* @generated from protobuf message github.actions.results.api.v1.MigrateArtifactRequest
*/
@@ -9,7 +9,7 @@ import {
GetSignedArtifactURLResponse,
DeleteArtifactRequest,
DeleteArtifactResponse,
} from "./artifact";
} from "./artifact.js";
//==================================//
// Client Code //
+11 -8
View File
@@ -1,5 +1,5 @@
import {warning} from '@actions/core'
import {isGhes} from './shared/config'
import {isGhes} from './shared/config.js'
import {
UploadArtifactOptions,
UploadArtifactResponse,
@@ -10,19 +10,22 @@ import {
DownloadArtifactResponse,
FindOptions,
DeleteArtifactResponse
} from './shared/interfaces'
import {uploadArtifact} from './upload/upload-artifact'
} from './shared/interfaces.js'
import {uploadArtifact} from './upload/upload-artifact.js'
import {
downloadArtifactPublic,
downloadArtifactInternal
} from './download/download-artifact'
} from './download/download-artifact.js'
import {
deleteArtifactPublic,
deleteArtifactInternal
} from './delete/delete-artifact'
import {getArtifactPublic, getArtifactInternal} from './find/get-artifact'
import {listArtifactsPublic, listArtifactsInternal} from './find/list-artifacts'
import {GHESNotSupportedError} from './shared/errors'
} from './delete/delete-artifact.js'
import {getArtifactPublic, getArtifactInternal} from './find/get-artifact.js'
import {
listArtifactsPublic,
listArtifactsInternal
} from './find/list-artifacts.js'
import {GHESNotSupportedError} from './shared/errors.js'
/**
* Generic interface for the artifact client.
@@ -1,21 +1,21 @@
import {info, debug} from '@actions/core'
import {getOctokit} from '@actions/github'
import {DeleteArtifactResponse} from '../shared/interfaces'
import {getUserAgentString} from '../shared/user-agent'
import {getRetryOptions} from '../find/retry-options'
import {DeleteArtifactResponse} from '../shared/interfaces.js'
import {getUserAgentString} from '../shared/user-agent.js'
import {getRetryOptions} from '../find/retry-options.js'
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
import {requestLog} from '@octokit/plugin-request-log'
import {retry} from '@octokit/plugin-retry'
import {OctokitOptions} from '@octokit/core/dist-types/types'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
import {getBackendIdsFromToken} from '../shared/util'
import type {OctokitOptions} from '@octokit/core/types'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
import {getBackendIdsFromToken} from '../shared/util.js'
import {
DeleteArtifactRequest,
ListArtifactsRequest,
StringValue
} from '../../generated'
import {getArtifactPublic} from '../find/get-artifact'
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors'
} from '../../generated/index.js'
import {getArtifactPublic} from '../find/get-artifact.js'
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors.js'
export async function deleteArtifactPublic(
artifactName: string,
@@ -10,17 +10,17 @@ import {
DownloadArtifactOptions,
DownloadArtifactResponse,
StreamExtractResponse
} from '../shared/interfaces'
import {getUserAgentString} from '../shared/user-agent'
import {getGitHubWorkspaceDir} from '../shared/config'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
} from '../shared/interfaces.js'
import {getUserAgentString} from '../shared/user-agent.js'
import {getGitHubWorkspaceDir} from '../shared/config.js'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
import {
GetSignedArtifactURLRequest,
Int64Value,
ListArtifactsRequest
} from '../../generated'
import {getBackendIdsFromToken} from '../shared/util'
import {ArtifactNotFoundError} from '../shared/errors'
} from '../../generated/index.js'
import {getBackendIdsFromToken} from '../shared/util.js'
import {ArtifactNotFoundError} from '../shared/errors.js'
const scrubQueryParameters = (url: string): string => {
const parsed = new URL(url)
@@ -64,7 +64,8 @@ async function streamExtract(
export async function streamExtractExternal(
url: string,
directory: string
directory: string,
opts: {timeout: number} = {timeout: 30 * 1000}
): Promise<StreamExtractResponse> {
const client = new httpClient.HttpClient(getUserAgentString())
const response = await client.get(url)
@@ -74,16 +75,17 @@ export async function streamExtractExternal(
)
}
const timeout = 30 * 1000 // 30 seconds
let sha256Digest: string | undefined = undefined
return new Promise((resolve, reject) => {
const timerFn = (): void => {
response.message.destroy(
new Error(`Blob storage chunk did not respond in ${timeout}ms`)
const timeoutError = new Error(
`Blob storage chunk did not respond in ${opts.timeout}ms`
)
response.message.destroy(timeoutError)
reject(timeoutError)
}
const timer = setTimeout(timerFn, timeout)
const timer = setTimeout(timerFn, opts.timeout)
const hashStream = crypto.createHash('sha256').setEncoding('hex')
const passThrough = new stream.PassThrough()
@@ -1,16 +1,20 @@
import {getOctokit} from '@actions/github'
import {retry} from '@octokit/plugin-retry'
import * as core from '@actions/core'
import {OctokitOptions} from '@octokit/core/dist-types/types'
import type {OctokitOptions} from '@octokit/core/types'
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
import {getRetryOptions} from './retry-options'
import {getRetryOptions} from './retry-options.js'
import {requestLog} from '@octokit/plugin-request-log'
import {GetArtifactResponse} from '../shared/interfaces'
import {getBackendIdsFromToken} from '../shared/util'
import {getUserAgentString} from '../shared/user-agent'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
import {ListArtifactsRequest, StringValue, Timestamp} from '../../generated'
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors'
import {GetArtifactResponse} from '../shared/interfaces.js'
import {getBackendIdsFromToken} from '../shared/util.js'
import {getUserAgentString} from '../shared/user-agent.js'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
import {
ListArtifactsRequest,
StringValue,
Timestamp
} from '../../generated/index.js'
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors.js'
export async function getArtifactPublic(
artifactName: string,
@@ -1,20 +1,20 @@
import {info, warning, debug} from '@actions/core'
import {getOctokit} from '@actions/github'
import {ListArtifactsResponse, Artifact} from '../shared/interfaces'
import {getUserAgentString} from '../shared/user-agent'
import {getRetryOptions} from './retry-options'
import {ListArtifactsResponse, Artifact} from '../shared/interfaces.js'
import {getUserAgentString} from '../shared/user-agent.js'
import {getRetryOptions} from './retry-options.js'
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
import {requestLog} from '@octokit/plugin-request-log'
import {retry} from '@octokit/plugin-retry'
import {OctokitOptions} from '@octokit/core/dist-types/types'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
import {getBackendIdsFromToken} from '../shared/util'
import {ListArtifactsRequest, Timestamp} from '../../generated'
import type {OctokitOptions} from '@octokit/core/types'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
import {getBackendIdsFromToken} from '../shared/util.js'
import {getMaxArtifactListCount} from '../shared/config.js'
import {ListArtifactsRequest, Timestamp} from '../../generated/index.js'
// Limiting to 1000 for perf reasons
const maximumArtifactCount = 1000
const maximumArtifactCount = getMaxArtifactListCount()
const paginationCount = 100
const maxNumberOfPages = maximumArtifactCount / paginationCount
const maxNumberOfPages = Math.ceil(maximumArtifactCount / paginationCount)
export async function listArtifactsPublic(
workflowRunId: number,
@@ -59,7 +59,7 @@ export async function listArtifactsPublic(
const totalArtifactCount = listArtifactResponse.total_count
if (totalArtifactCount > maximumArtifactCount) {
warning(
`Workflow run ${workflowRunId} has more than 1000 artifacts. Results will be incomplete as only the first ${maximumArtifactCount} artifacts will be returned`
`Workflow run ${workflowRunId} has ${totalArtifactCount} artifacts, exceeding the limit of ${maximumArtifactCount}. Results will be incomplete as only the first ${maximumArtifactCount} artifacts will be returned`
)
numberOfPages = maxNumberOfPages
}
@@ -81,7 +81,7 @@ export async function listArtifactsPublic(
// Iterate over any remaining pages
for (
currentPageNumber;
currentPageNumber < numberOfPages;
currentPageNumber <= numberOfPages;
currentPageNumber++
) {
debug(`Fetching page ${currentPageNumber} of artifact list`)
@@ -1,5 +1,5 @@
import * as core from '@actions/core'
import {OctokitOptions} from '@octokit/core/dist-types/types'
import type {OctokitOptions} from '@octokit/core/types'
import {RequestRequestOptions} from '@octokit/types'
export type RetryOptions = {
@@ -1,11 +1,11 @@
import {HttpClient, HttpClientResponse, HttpCodes} from '@actions/http-client'
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
import {info, debug} from '@actions/core'
import {ArtifactServiceClientJSON} from '../../generated'
import {getResultsServiceUrl, getRuntimeToken} from './config'
import {getUserAgentString} from './user-agent'
import {NetworkError, UsageError} from './errors'
import {maskSecretUrls} from './util'
import {ArtifactServiceClientJSON} from '../../generated/index.js'
import {getResultsServiceUrl, getRuntimeToken} from './config.js'
import {getUserAgentString} from './user-agent.js'
import {NetworkError, UsageError} from './errors.js'
import {maskSecretUrls} from './util.js'
// The twirp http client must implement this interface
interface Rpc {
@@ -97,3 +97,19 @@ export function getUploadChunkTimeout(): number {
return timeout
}
// This value can be changed with ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT variable.
// Defaults to 1000 as a safeguard for rate limiting.
export function getMaxArtifactListCount(): number {
const maxCountVar =
process.env['ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT'] || '1000'
const maxCount = parseInt(maxCountVar)
if (isNaN(maxCount) || maxCount < 1) {
throw new Error(
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
)
}
return maxCount
}
@@ -0,0 +1,7 @@
// This file exists as a CommonJS module to read the version from package.json.
// In an ESM package, using `require()` directly in .ts files requires disabling
// ESLint rules and doesn't work reliably across all Node.js versions.
// By keeping this as a .cjs file, we can use require() naturally and export
// the version for the ESM modules to import.
const packageJson = require('../../../package.json')
module.exports = { version: packageJson.version }
@@ -1,9 +1,8 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
const packageJson = require('../../../package.json')
import {version} from './package-version.cjs'
/**
* Ensure that this User Agent String is used in all HTTP calls so that we can monitor telemetry between different versions of this package
*/
export function getUserAgentString(): string {
return `@actions/artifact-${packageJson.version}`
return `@actions/artifact-${version}`
}
@@ -1,6 +1,6 @@
import * as core from '@actions/core'
import {getRuntimeToken} from './config'
import jwt_decode from 'jwt-decode'
import {getRuntimeToken} from './config.js'
import {jwtDecode} from 'jwt-decode'
import {debug, setSecret} from '@actions/core'
export interface BackendIds {
@@ -20,7 +20,7 @@ const InvalidJwtError = new Error(
// workflow run and workflow job run backend ids
export function getBackendIdsFromToken(): BackendIds {
const token = getRuntimeToken()
const decoded = jwt_decode<ActionsToken>(token)
const decoded = jwtDecode<ActionsToken>(token)
if (!decoded.scp) {
throw InvalidJwtError
}
@@ -1,15 +1,15 @@
import {BlobClient, BlockBlobUploadStreamOptions} from '@azure/storage-blob'
import {TransferProgressEvent} from '@azure/core-http'
import {ZipUploadStream} from './zip'
import {TransferProgressEvent} from '@azure/core-http-compat'
import {ZipUploadStream} from './zip.js'
import {
getUploadChunkSize,
getConcurrency,
getUploadChunkTimeout
} from '../shared/config'
} from '../shared/config.js'
import * as core from '@actions/core'
import * as crypto from 'crypto'
import * as stream from 'stream'
import {NetworkError} from '../shared/errors'
import {NetworkError} from '../shared/errors.js'
export interface BlobUploadResponse {
/**
@@ -1,4 +1,4 @@
import {Timestamp} from '../../generated'
import {Timestamp} from '../../generated/index.js'
import * as core from '@actions/core'
export function getExpiration(retentionDays?: number): Timestamp | undefined {
@@ -2,24 +2,24 @@ import * as core from '@actions/core'
import {
UploadArtifactOptions,
UploadArtifactResponse
} from '../shared/interfaces'
import {getExpiration} from './retention'
import {validateArtifactName} from './path-and-artifact-name-validation'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
} from '../shared/interfaces.js'
import {getExpiration} from './retention.js'
import {validateArtifactName} from './path-and-artifact-name-validation.js'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
import {
UploadZipSpecification,
getUploadZipSpecification,
validateRootDirectory
} from './upload-zip-specification'
import {getBackendIdsFromToken} from '../shared/util'
import {uploadZipToBlobStorage} from './blob-upload'
import {createZipUploadStream} from './zip'
} from './upload-zip-specification.js'
import {getBackendIdsFromToken} from '../shared/util.js'
import {uploadZipToBlobStorage} from './blob-upload.js'
import {createZipUploadStream} from './zip.js'
import {
CreateArtifactRequest,
FinalizeArtifactRequest,
StringValue
} from '../../generated'
import {FilesNotFoundError, InvalidResponseError} from '../shared/errors'
} from '../../generated/index.js'
import {FilesNotFoundError, InvalidResponseError} from '../shared/errors.js'
export async function uploadArtifact(
name: string,
@@ -1,7 +1,7 @@
import * as fs from 'fs'
import {info} from '@actions/core'
import {normalize, resolve} from 'path'
import {validateFilePath} from './path-and-artifact-name-validation'
import {validateFilePath} from './path-and-artifact-name-validation.js'
export interface UploadZipSpecification {
/**
+3 -3
View File
@@ -1,9 +1,9 @@
import * as stream from 'stream'
import {realpath} from 'fs/promises'
import * as archiver from 'archiver'
import archiver from 'archiver'
import * as core from '@actions/core'
import {UploadZipSpecification} from './upload-zip-specification'
import {getUploadChunkSize} from '../shared/config'
import {UploadZipSpecification} from './upload-zip-specification.js'
import {getUploadChunkSize} from '../shared/config.js'
export const DEFAULT_COMPRESSION_LEVEL = 6
+2
View File
@@ -4,6 +4,8 @@
"baseUrl": "./",
"outDir": "./lib",
"rootDir": "./src",
"module": "node16",
"moduleResolution": "node16",
"paths": {
"@actions/core": [
"../core"
+76
View File
@@ -15,6 +15,14 @@ initiated.
See [Using artifact attestations to establish provenance for builds](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)
for more information on artifact attestations.
## Table of Contents
- [Usage](#usage)
- [attest](#attest)
- [attestProvenance](#attestprovenance)
- [Attestation](#attestation)
- [Sigstore Instance](#sigstore-instance)
- [Storage](#storage)
## Usage
### `attest`
@@ -165,6 +173,74 @@ export type Attestation = {
For details about the Sigstore bundle format, see the [Bundle protobuf
specification](https://github.com/sigstore/protobuf-specs/blob/main/protos/sigstore_bundle.proto).
### createStorageRecord
The `createStorageRecord` function creates an
[artifact metadata storage record](https://docs.github.com/en/rest/orgs/artifact-metadata?apiVersion=2022-11-28#create-artifact-metadata-storage-record)
on behalf of an attested artifact. It accepts parameters defining artifact
and package registry details. The storage record contains metadata about where the artifact is stored on a given package registry.
```js
const { createStorageRecord } = require('@actions/attest');
const core = require('@actions/core');
async function run() {
// In order to persist attestations to the repo, this should be a token with
// repository write permissions.
const ghToken = core.getInput('gh-token');
const record = await createStorageRecord(
artifactOptions: {
name: 'my-artifact-name',
digest: { 'sha256': '36ab4667...'},
version: "v1.0.0"
},
packageRegistryOptions: {
registryUrl: "https://my-fave-pkg-registry.com"
},
token: ghToken
);
console.log(record);
}
run();
```
The `createStorageRecord` function supports the following options:
```typescript
// Artifact details to associate the record with
export type ArtifactOptions = {
// The name of the artifact
name: string
// The digest of the artifact
digest: string
// The version of the artifact
version?: string
// The status of the artifact
status?: string
}
// Includes details about the package registry the artifact was published to
export type PackageRegistryOptions = {
// The URL of the package registry
registryUrl: string
// The URL of the artifact in the package registry
artifactUrl?: string
// The package registry repository the artifact was published to.
repo?: string
// The path of the artifact in the package registry repository.
path?: string
}
// GitHub token for writing attestations.
token: string
// Optional parameters for the write operation.
// The number of times to retry the request.
retryAttempts?: number
// HTTP headers to include in request to Artifact Metadata API.
headers?: RequestHeaders
```
## Sigstore Instance
When generating the signed attestation there are two different Sigstore
+18
View File
@@ -1,5 +1,23 @@
# @actions/attest Releases
### 2.2.1
- Bump `@actions/http-client` to `3.0.2`
- Bump `undici` to `6.23.0`
### 2.2.0
- Bump @actions/core from 1.11.1 to 2.0.2
- Bump @actions/github from 6.0.0 to 7.0.0
- Bump @actions/http-client from 2.2.3 to 3.0.1
### 2.0.0
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
- Bump @sigstore/bundle from 3.0.0 to 3.1.0
- Bump @sigstore/sign from 3.0.0 to 3.1.0
- Bump jose from 5.2.3 to 5.10.0
### 1.6.0
- Update `buildSLSAProvenancePredicate` to populate `workflow.ref` field from the `ref` claim in the OIDC token [#1969](https://github.com/actions/toolkit/pull/1969)
@@ -0,0 +1,137 @@
import {MockAgent, setGlobalDispatcher} from 'undici'
import {createStorageRecord} from '../src/artifactMetadata'
describe('createStorageRecord', () => {
const originalEnv = process.env
const token = 'token'
const headers = {'X-GitHub-Foo': 'true'}
const artifactOptions = {
name: 'my-lib',
version: '1.0.0',
digest: `sha256:${'a'.repeat(64)}`
}
const packageRegistryOptions = {
registryUrl: 'https://my-registry.org'
}
const mockAgent = new MockAgent()
setGlobalDispatcher(mockAgent)
beforeEach(() => {
process.env = {
...originalEnv,
GITHUB_REPOSITORY: 'foo/bar'
}
})
afterEach(() => {
process.env = originalEnv
})
describe('when the api call is successful', () => {
beforeEach(() => {
mockAgent
.get('https://api.github.com')
.intercept({
path: '/orgs/foo/artifacts/metadata/storage-record',
method: 'POST',
headers: {authorization: `token ${token}`, ...headers},
body: JSON.stringify({
name: 'my-lib',
version: '1.0.0',
digest: `sha256:${'a'.repeat(64)}`,
registry_url: 'https://my-registry.org'
})
})
.reply(200, {storage_records: [{id: 123}, {id: 456}]})
})
it('persists the storage record', async () => {
await expect(
createStorageRecord(
artifactOptions,
packageRegistryOptions,
token,
undefined,
headers
)
).resolves.toEqual([123, 456])
})
})
describe('when the api call fails', () => {
beforeEach(() => {
mockAgent
.get('https://api.github.com')
.intercept({
path: '/orgs/foo/artifacts/metadata/storage-record',
method: 'POST',
headers: {authorization: `token ${token}`},
body: JSON.stringify({
name: 'my-lib',
version: '1.0.0',
digest: `sha256:${'a'.repeat(64)}`,
registry_url: 'https://my-registry.org'
})
})
.reply(500, 'oops')
})
it('throws an error', async () => {
await expect(
createStorageRecord(
artifactOptions,
packageRegistryOptions,
token,
0,
headers
)
).rejects.toThrow(/oops/)
})
})
describe('when the api call fails but succeeds on retry', () => {
beforeEach(() => {
const pool = mockAgent.get('https://api.github.com')
pool
.intercept({
path: '/orgs/foo/artifacts/metadata/storage-record',
method: 'POST',
headers: {authorization: `token ${token}`},
body: JSON.stringify({
...artifactOptions,
registry_url: packageRegistryOptions.registryUrl
})
})
.reply(500, 'oops')
.times(1)
pool
.intercept({
path: '/orgs/foo/artifacts/metadata/storage-record',
method: 'POST',
headers: {authorization: `token ${token}`},
body: JSON.stringify({
...artifactOptions,
registry_url: packageRegistryOptions.registryUrl
})
})
.reply(200, {storage_records: [{id: 123}, {id: 456}]})
.times(1)
})
it('persists the storage record', async () => {
await expect(
createStorageRecord(
artifactOptions,
packageRegistryOptions,
token,
undefined,
headers
)
).resolves.toEqual([123, 456])
})
})
})
+419 -1739
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/attest",
"version": "1.6.0",
"version": "2.2.1",
"description": "Actions attestation lib",
"keywords": [
"github",
@@ -35,20 +35,20 @@
"url": "https://github.com/actions/toolkit/issues"
},
"devDependencies": {
"@sigstore/mock": "^0.8.0",
"@sigstore/mock": "^0.10.0",
"@sigstore/rekor-types": "^3.0.0",
"@types/jsonwebtoken": "^9.0.6",
"nock": "^13.5.1",
"undici": "^5.28.5"
"undici": "^6.23.0"
},
"dependencies": {
"@actions/core": "^1.11.1",
"@actions/github": "^6.0.0",
"@actions/http-client": "^2.2.3",
"@actions/core": "^2.0.2",
"@actions/github": "^7.0.0",
"@actions/http-client": "^3.0.2",
"@octokit/plugin-retry": "^6.0.1",
"@sigstore/bundle": "^3.0.0",
"@sigstore/sign": "^3.0.0",
"jose": "^5.2.3"
"@sigstore/bundle": "^3.1.0",
"@sigstore/sign": "^3.1.0",
"jose": "^5.10.0"
},
"overrides": {
"@octokit/plugin-retry": {
+85
View File
@@ -0,0 +1,85 @@
import * as github from '@actions/github'
import {retry} from '@octokit/plugin-retry'
import {RequestHeaders} from '@octokit/types'
const CREATE_STORAGE_RECORD_REQUEST =
'POST /orgs/{owner}/artifacts/metadata/storage-record'
const DEFAULT_RETRY_COUNT = 5
/**
* Options for creating a storage record for an attested artifact.
*/
export type ArtifactOptions = {
// Includes details about the attested artifact
// The name of the artifact
name: string
// The digest of the artifact
digest: string
// The version of the artifact
version?: string
// The status of the artifact
status?: string
}
// Includes details about the package registry the artifact was published to
export type PackageRegistryOptions = {
// The URL of the package registry
registryUrl: string
// The URL of the artifact in the package registry
artifactUrl?: string
// The package registry repository the artifact was published to.
repo?: string
// The path of the artifact in the package registry repository.
path?: string
}
/**
* Writes a storage record on behalf of an artifact that has been attested
* @param artifactOptions - parameters for the storage record API request.
* @param packageRegistryOptions - parameters for the package registry API request.
* @param token - GitHub token used to authenticate the request.
* @param retryAttempts - The number of retries to attempt if the request fails.
* @param headers - Additional headers to include in the request.
*
* @returns The ID of the storage record.
* @throws Error if the storage record fails to persist.
*/
export async function createStorageRecord(
artifactOptions: ArtifactOptions,
packageRegistryOptions: PackageRegistryOptions,
token: string,
retryAttempts?: number,
headers?: RequestHeaders
): Promise<number[]> {
const retries = retryAttempts ?? DEFAULT_RETRY_COUNT
const octokit = github.getOctokit(token, {retry: {retries}}, retry)
try {
const response = await octokit.request(CREATE_STORAGE_RECORD_REQUEST, {
owner: github.context.repo.owner,
headers,
...buildRequestParams(artifactOptions, packageRegistryOptions)
})
const data =
typeof response.data == 'string'
? JSON.parse(response.data)
: response.data
return data?.storage_records.map((r: {id: number}) => r.id)
} catch (err) {
const message = err instanceof Error ? err.message : err
throw new Error(`Failed to persist storage record: ${message}`)
}
}
function buildRequestParams(
artifactOptions: ArtifactOptions,
packageRegistryOptions: PackageRegistryOptions
): Record<string, unknown> {
const {registryUrl, artifactUrl, ...rest} = packageRegistryOptions
return {
...artifactOptions,
registry_url: registryUrl,
artifact_url: artifactUrl,
...rest
}
}
+1
View File
@@ -1,3 +1,4 @@
export {createStorageRecord} from './artifactMetadata'
export {AttestOptions, attest} from './attest'
export {
AttestProvenanceOptions,
+5 -1
View File
@@ -29,7 +29,11 @@ export const writeAttestation = async (
owner: github.context.repo.owner,
repo: github.context.repo.repo,
headers: options.headers,
data: {bundle: attestation}
bundle: attestation as {
mediaType?: string
verificationMaterial?: {[key: string]: unknown}
dsseEnvelope?: {[key: string]: unknown}
}
})
const data =
+97 -46
View File
@@ -1,22 +1,73 @@
# @actions/cache Releases
### 4.0.3
## 6.0.0
- **Breaking change**: Package is now ESM-only
- CommonJS consumers must use dynamic `import()` instead of `require()`
## 5.0.5
- Bump `@actions/glob` to `0.5.1`
## 5.0.4
- Bump `@actions/http-client` to `3.0.2`
## 5.0.3
Prevent retries for rate limited cache operations [2243](https://github.com/actions/toolkit/pull/2243).
## 5.0.1
- Fix Node.js 24 punycode deprecation warning by updating `@azure/storage-blob` from `^12.13.0` to `^12.29.1` [#2213](https://github.com/actions/toolkit/pull/2213)
- Newer storage-blob uses `@azure/core-rest-pipeline` instead of deprecated `@azure/core-http`, which eliminates the transitive dependency on `node-fetch@2``whatwg-url@5``tr46@0.0.3` that used the deprecated punycode module
## 5.0.0
- Remove `@azure/ms-rest-js` dependency [#2197](https://github.com/actions/toolkit/pull/2197)
- The `TransferProgressEvent` type is now imported from `@azure/core-rest-pipeline` instead of `@azure/ms-rest-js`
- Bump `@actions/core` from `^1.11.1` to `^2.0.0` [#2198](https://github.com/actions/toolkit/pull/2198)
- Bump `@actions/exec` from `^1.0.1` to `^2.0.0` [#2198](https://github.com/actions/toolkit/pull/2198)
- Bump `@actions/glob` from `^0.1.0` to `^0.5.0` [#2198](https://github.com/actions/toolkit/pull/2198)
- Bump `@actions/http-client` from `^2.1.1` to `^3.0.0` [#2198](https://github.com/actions/toolkit/pull/2198)
- Bump `@actions/io` from `^1.0.1` to `^2.0.0` [#2198](https://github.com/actions/toolkit/pull/2198)
- Add support for Node.js 24 [#2110](https://github.com/actions/toolkit/pull/2110)
- Add `node-fetch` override to resolve audit vulnerabilities [#2110](https://github.com/actions/toolkit/pull/2110)
## 4.1.0
- Remove client side 10GiB cache size limit check & update twirp client [#2118](https://github.com/actions/toolkit/pull/2118)
## 4.0.5
- Reintroduce @protobuf-ts/runtime-rpc as a runtime dependency [#2113](https://github.com/actions/toolkit/pull/2113)
## 4.0.4
⚠️ Faulty patch release. Upgrade to 4.0.5 instead.
- Optimized cache dependencies by moving `@protobuf-ts/plugin` to dev dependencies [#2106](https://github.com/actions/toolkit/pull/2106)
- Improved cache service availability determination for different cache service versions (v1 and v2) [#2100](https://github.com/actions/toolkit/pull/2100)
- Enhanced server error handling: 5xx HTTP errors are now logged as errors instead of warnings [#2099](https://github.com/actions/toolkit/pull/2099)
- Fixed cache hit logging to properly distinguish between exact key matches and restore key matches [#2101](https://github.com/actions/toolkit/pull/2101)
## 4.0.3
- Added masking for Shared Access Signature (SAS) cache entry URLs [#1982](https://github.com/actions/toolkit/pull/1982)
- Improved debugging by logging both the cache version alongside the keys requested when a cache restore fails [#1994](https://github.com/actions/toolkit/pull/1994)
### 4.0.2
## 4.0.2
- Wrap create failures in ReserveCacheError [#1966](https://github.com/actions/toolkit/pull/1966)
### 4.0.1
## 4.0.1
- Remove runtime dependency on `twirp-ts` [#1947](https://github.com/actions/toolkit/pull/1947)
- Cache miss as debug, not warning annotation [#1954](https://github.com/actions/toolkit/pull/1954)
### 4.0.0
## 4.0.0
#### Important changes
### Important changes
The cache backend service has been rewritten from the ground up for improved performance and reliability. The [@actions/cache](https://github.com/actions/toolkit/tree/main/packages/cache) package now integrates with the new cache service (v2) APIs.
@@ -30,182 +81,182 @@ Upgrading to the recommended version should not break or require any changes to
Read more about the change & access the migration guide: [reference to the announcement](https://github.com/actions/toolkit/discussions/1890).
#### Minor changes
### Minor changes
- Update `@actions/core` to `1.11.0`
- Update `semver` `6.3.1`
- Add `twirp-ts` `2.5.0` to dependencies
### 3.3.0
## 3.3.0
- Update `@actions/core` to `1.11.1`
- Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824), [#1842](https://github.com/actions/toolkit/pull/1842)
### 3.2.4
## 3.2.4
- Updated `isGhes` check to include `.ghe.com` and `.ghe.localhost` as accepted hosts
### 3.2.3
## 3.2.3
- Fixed a bug that mutated path arguments to `getCacheVersion` [#1378](https://github.com/actions/toolkit/pull/1378)
### 3.2.2
## 3.2.2
- Add new default cache download method to improve performance and reduce hangs [#1484](https://github.com/actions/toolkit/pull/1484)
### 3.2.1
## 3.2.1
- Updated @azure/storage-blob to `v12.13.0`
### 3.2.0
## 3.2.0
- Add `lookupOnly` to cache restore `DownloadOptions`.
### 3.1.4
## 3.1.4
- Fix zstd not being used due to `zstd --version` output change in zstd 1.5.4 release. See [#1353](https://github.com/actions/toolkit/pull/1353).
### 3.1.3
## 3.1.3
- Fix to prevent from setting MYSYS environement variable globally [#1329](https://github.com/actions/toolkit/pull/1329).
### 3.1.2
## 3.1.2
- Fix issue with symlink restoration on windows.
### 3.1.1
## 3.1.1
- Reverted changes in 3.1.0 to fix issue with symlink restoration on windows.
- Added support for verbose logging about cache version during cache miss.
### 3.1.0
## 3.1.0
- Update actions/cache on windows to use gnu tar and zstd by default
- Update actions/cache on windows to fallback to bsdtar and zstd if gnu tar is not available.
- Added support for fallback to gzip to restore old caches on windows.
### 3.1.0-beta.3
## 3.1.0-beta.3
- Bug Fixes for fallback to gzip to restore old caches on windows and bsdtar if gnutar is not available.
### 3.1.0-beta.2
## 3.1.0-beta.2
- Added support for fallback to gzip to restore old caches on windows.
### 3.0.6
## 3.0.6
- Added `@azure/abort-controller` to dependencies to fix compatibility issue with ESM [#1208](https://github.com/actions/toolkit/issues/1208)
### 3.0.5
## 3.0.5
- Update `@actions/cache` to use `@actions/core@^1.10.0`
### 3.0.4
## 3.0.4
- Fix zstd not working for windows on gnu tar in issues [#888](https://github.com/actions/cache/issues/888) and [#891](https://github.com/actions/cache/issues/891).
- Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 60 minutes.
### 3.0.3
## 3.0.3
- Bug fixes for download stuck issue [#810](https://github.com/actions/cache/issues/810).
### 3.0.2
## 3.0.2
- Added 1 hour timeout for the download stuck issue [#810](https://github.com/actions/cache/issues/810).
### 3.0.1
## 3.0.1
- Fix [#833](https://github.com/actions/cache/issues/833) - cache doesn't work with github workspace directory.
- Fix [#809](https://github.com/actions/cache/issues/809) `zstd -d: no such file or directory` error on AWS self-hosted runners.
### 3.0.0
## 3.0.0
- Updated actions/cache to suppress Actions cache server error and log warning for those error [#1122](https://github.com/actions/toolkit/pull/1122)
### 2.0.6
## 2.0.6
- Fix `Tar failed with error: The process '/usr/bin/tar' failed with exit code 1` issue when temp directory where tar is getting created is actually the subdirectory of the path mentioned by the user for caching. ([issue](https://github.com/actions/cache/issues/689))
### 2.0.5
## 2.0.5
- Fix to avoid saving empty cache when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
### 2.0.4
## 2.0.4
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
### 2.0.3
## 2.0.3
- Update to v2.0.0 of `@actions/http-client`
### 2.0.0
## 2.0.0
- Added support to check if Actions cache service feature is available or not [#1028](https://github.com/actions/toolkit/pull/1028)
### 1.0.11
## 1.0.11
- Fix file downloads > 2GB([issue](https://github.com/actions/cache/issues/773))
### 1.0.10
## 1.0.10
- Update `lockfileVersion` to `v2` in `package-lock.json [#1022](https://github.com/actions/toolkit/pull/1022)
### 1.0.9
## 1.0.9
- Use @azure/ms-rest-js v2.6.0
- Use @azure/storage-blob v12.8.0
### 1.0.8
## 1.0.8
- Increase the allowed artifact cache size from 5GB to 10GB ([issue](https://github.com/actions/cache/discussions/497))
### 1.0.7
## 1.0.7
- Fixes permissions issue extracting archives with GNU tar on macOS ([issue](https://github.com/actions/cache/issues/527))
### 1.0.6
## 1.0.6
- Make caching more verbose [#650](https://github.com/actions/toolkit/pull/650)
- Use GNU tar on macOS if available [#701](https://github.com/actions/toolkit/pull/701)
### 1.0.5
## 1.0.5
- Fix to ensure Windows cache paths get resolved correctly
### 1.0.4
## 1.0.4
- Use @actions/core v1.2.6
- Fixes uploadChunk to throw an error if any unsuccessful response code is received
### 1.0.3
## 1.0.3
- Use http-client v1.0.9
- Fixes error handling so retries are not attempted on non-retryable errors (409 Conflict, for example)
- Adds 5 second delay between retry attempts
### 1.0.2
## 1.0.2
- Use posix archive format to add support for some tools
### 1.0.1
## 1.0.1
- Fix bug in downloading large files (> 2 GBs) with the Azure SDK
### 1.0.0
## 1.0.0
- Downloads Azure-hosted caches using the Azure SDK for speed and reliability
- Displays download progress
- Includes changes that break compatibility with earlier versions, including:
- `retry`, `retryTypedResponse`, and `retryHttpClientResponse` moved from `cacheHttpClient` to `requestUtils`
### 0.2.1
## 0.2.1
- Fix to await async function getCompressionMethod
### 0.2.0
## 0.2.0
- Fixes issues with the zstd compression algorithm on Windows and Ubuntu 16.04 [#469](https://github.com/actions/toolkit/pull/469)
### 0.1.0
## 0.1.0
- Initial release
+1 -1
View File
@@ -1,5 +1,5 @@
name: 'Set env variables'
description: 'Sets certain env variables so that e2e restore and save cache can be tested in a shell'
runs:
using: 'node12'
using: 'node20'
main: 'index.js'
+4 -3
View File
@@ -1,8 +1,9 @@
// Certain env variables are not set by default in a shell context and are only available in a node context from a running action
// In order to be able to restore and save cache e2e in a shell when running CI tests, we need these env variables set
const fs = require('fs');
const os = require('os');
const filePath = process.env[`GITHUB_ENV`]
import fs from 'fs'
import os from 'os'
const filePath = process.env['GITHUB_ENV']
fs.appendFileSync(filePath, `ACTIONS_CACHE_SERVICE_V2=true${os.EOL}`, {
encoding: 'utf8'
})
+63 -8
View File
@@ -1,14 +1,69 @@
import * as cache from '../src/cache'
test('isFeatureAvailable returns true if server url is set', () => {
try {
describe('isFeatureAvailable', () => {
const originalEnv = process.env
beforeEach(() => {
jest.resetModules()
process.env = {...originalEnv}
// Clean cache-related environment variables
delete process.env['ACTIONS_CACHE_URL']
delete process.env['ACTIONS_RESULTS_URL']
delete process.env['ACTIONS_CACHE_SERVICE_V2']
delete process.env['GITHUB_SERVER_URL']
})
afterAll(() => {
process.env = originalEnv
})
test('returns true for cache service v1 when ACTIONS_CACHE_URL is set', () => {
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
expect(cache.isFeatureAvailable()).toBe(true)
} finally {
delete process.env['ACTIONS_CACHE_URL']
}
})
})
test('isFeatureAvailable returns false if server url is not set', () => {
expect(cache.isFeatureAvailable()).toBe(false)
test('returns false for cache service v1 when only ACTIONS_RESULTS_URL is set', () => {
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
expect(cache.isFeatureAvailable()).toBe(false)
})
test('returns true for cache service v1 when both URLs are set', () => {
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
expect(cache.isFeatureAvailable()).toBe(true)
})
test('returns true for cache service v2 when ACTIONS_RESULTS_URL is set', () => {
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
expect(cache.isFeatureAvailable()).toBe(true)
})
test('returns false for cache service v2 when only ACTIONS_CACHE_URL is set', () => {
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
expect(cache.isFeatureAvailable()).toBe(false)
})
test('returns false when no cache URLs are set', () => {
expect(cache.isFeatureAvailable()).toBe(false)
})
test('returns false for cache service v2 when no URLs are set', () => {
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
expect(cache.isFeatureAvailable()).toBe(false)
})
test('returns true for GHES with v1 even when v2 flag is set', () => {
process.env['GITHUB_SERVER_URL'] = 'https://my-enterprise.github.com'
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
expect(cache.isFeatureAvailable()).toBe(true)
})
test('returns false for GHES with only ACTIONS_RESULTS_URL', () => {
process.env['GITHUB_SERVER_URL'] = 'https://my-enterprise.github.com'
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
expect(cache.isFeatureAvailable()).toBe(false)
})
})
+174
View File
@@ -0,0 +1,174 @@
import * as http from 'http'
import * as net from 'net'
import {HttpClient} from '@actions/http-client'
import * as core from '@actions/core'
import * as config from '../src/internal/config'
import * as cacheUtils from '../src/internal/cacheUtils'
import {internalCacheTwirpClient} from '../src/internal/shared/cacheTwirpClient'
jest.mock('@actions/http-client')
const clientOptions = {
maxAttempts: 5,
retryIntervalMs: 1,
retryMultiplier: 1.5
}
// noopLogs mocks the console.log and core.* functions to prevent output in the console while testing
const noopLogs = (): void => {
jest.spyOn(console, 'log').mockImplementation(() => {})
jest.spyOn(core, 'debug').mockImplementation(() => {})
jest.spyOn(core, 'info').mockImplementation(() => {})
jest.spyOn(core, 'warning').mockImplementation(() => {})
}
describe('cacheTwirpClient', () => {
beforeAll(() => {
noopLogs()
jest
.spyOn(config, 'getCacheServiceURL')
.mockReturnValue('http://localhost:8080')
jest.spyOn(cacheUtils, 'getRuntimeToken').mockReturnValue('token')
})
beforeEach(() => {
jest.clearAllMocks()
})
it('should fail immediately on 429 rate limit without retrying', async () => {
const mockPost = jest.fn(() => {
const msg = new http.IncomingMessage(new net.Socket())
msg.statusCode = 429
msg.statusMessage = 'Too Many Requests'
return {
message: msg,
readBody: async () => {
return Promise.resolve(`{"ok": false}`)
}
}
})
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
return {
post: mockPost
}
})
const client = internalCacheTwirpClient(clientOptions)
await expect(
client.CreateCacheEntry({
key: 'test-key',
version: 'test-version'
})
).rejects.toThrow(
'Failed to CreateCacheEntry: Rate limited: Failed request: (429) Too Many Requests'
)
// Should only be called once - no retries for 429
expect(mockPost).toHaveBeenCalledTimes(1)
})
it('should log warning with retry-after header on 429', async () => {
const warningSpy = jest.spyOn(core, 'warning')
const mockPost = jest.fn(() => {
const msg = new http.IncomingMessage(new net.Socket())
msg.statusCode = 429
msg.statusMessage = 'Too Many Requests'
msg.headers = {'retry-after': '60'}
return {
message: msg,
readBody: async () => {
return Promise.resolve(`{"ok": false}`)
}
}
})
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
return {
post: mockPost
}
})
const client = internalCacheTwirpClient(clientOptions)
await expect(
client.CreateCacheEntry({
key: 'test-key',
version: 'test-version'
})
).rejects.toThrow('Rate limited')
expect(mockPost).toHaveBeenCalledTimes(1)
expect(warningSpy).toHaveBeenCalledWith(
"You've hit a rate limit, your rate limit will reset in 60 seconds"
)
})
it('should not log warning if retry-after header is missing on 429', async () => {
const warningSpy = jest.spyOn(core, 'warning')
const mockPost = jest.fn(() => {
const msg = new http.IncomingMessage(new net.Socket())
msg.statusCode = 429
msg.statusMessage = 'Too Many Requests'
// No retry-after header
return {
message: msg,
readBody: async () => {
return Promise.resolve(`{"ok": false}`)
}
}
})
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
return {
post: mockPost
}
})
const client = internalCacheTwirpClient(clientOptions)
await expect(
client.CreateCacheEntry({
key: 'test-key',
version: 'test-version'
})
).rejects.toThrow('Rate limited')
expect(mockPost).toHaveBeenCalledTimes(1)
expect(warningSpy).not.toHaveBeenCalled()
})
it('should not log warning if retry-after header is invalid on 429', async () => {
const warningSpy = jest.spyOn(core, 'warning')
const mockPost = jest.fn(() => {
const msg = new http.IncomingMessage(new net.Socket())
msg.statusCode = 429
msg.statusMessage = 'Too Many Requests'
msg.headers = {'retry-after': 'invalid'}
return {
message: msg,
readBody: async () => {
return Promise.resolve(`{"ok": false}`)
}
}
})
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
return {
post: mockPost
}
})
const client = internalCacheTwirpClient(clientOptions)
await expect(
client.CreateCacheEntry({
key: 'test-key',
version: 'test-version'
})
).rejects.toThrow('Rate limited')
expect(mockPost).toHaveBeenCalledTimes(1)
expect(warningSpy).not.toHaveBeenCalled()
})
})
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env node
// Helper script to restore cache for e2e testing
import * as cache from '../lib/cache.js'
const [prefix, runId, useAzureSdk] = process.argv.slice(2)
if (!prefix || !runId) {
console.error('Usage: restore-cache.mjs <prefix> <runId> [useAzureSdk]')
process.exit(1)
}
const key = `test-${prefix}-${runId}`
const paths = ['test-cache', '~/test-cache']
const options = {useAzureSdk: useAzureSdk !== 'false'}
console.log(`Restoring cache with key: ${key}`)
console.log(`Paths: ${paths.join(', ')}`)
console.log(`Using Azure SDK: ${options.useAzureSdk}`)
const maxRetries = 3
const retryDelayMs = 5000
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(`Attempt ${attempt} of ${maxRetries}`)
const restoredKey = await cache.restoreCache(paths, key, [], options)
if (restoredKey) {
console.log(`Cache restored with key: ${restoredKey}`)
process.exit(0)
} else {
console.log('Cache not found on this attempt')
}
} catch (error) {
console.error(`Error on attempt ${attempt}:`, error.message)
}
if (attempt < maxRetries) {
console.log(`Waiting ${retryDelayMs / 1000}s before retry...`)
await new Promise(resolve => setTimeout(resolve, retryDelayMs))
}
}
console.error(`Failed to restore cache after ${maxRetries} attempts`)
process.exit(1)
+18 -6
View File
@@ -6,6 +6,8 @@ import * as cacheUtils from '../src/internal/cacheUtils'
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
import {ArtifactCacheEntry} from '../src/internal/contracts'
import * as tar from '../src/internal/tar'
import {HttpClientError} from '@actions/http-client'
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp-client'
jest.mock('../src/internal/cacheHttpClient')
jest.mock('../src/internal/cacheUtils')
@@ -73,18 +75,28 @@ test('restore with no cache found', async () => {
test('restore with server error should fail', async () => {
const paths = ['node_modules']
const key = 'node-test'
const logWarningMock = jest.spyOn(core, 'warning')
const logErrorMock = jest.spyOn(core, 'error')
jest.spyOn(cacheHttpClient, 'getCacheEntry').mockImplementation(() => {
throw new Error('HTTP Error Occurred')
})
// Set cache service to V2 to test error logging for server errors
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
process.env['ACTIONS_RESULTS_URL'] = 'https://results.local/'
jest
.spyOn(CacheServiceClientJSON.prototype, 'GetCacheEntryDownloadURL')
.mockImplementation(() => {
throw new HttpClientError('HTTP Error Occurred', 500)
})
const cacheKey = await restoreCache(paths, key)
expect(cacheKey).toBe(undefined)
expect(logWarningMock).toHaveBeenCalledTimes(1)
expect(logWarningMock).toHaveBeenCalledWith(
expect(logErrorMock).toHaveBeenCalledTimes(1)
expect(logErrorMock).toHaveBeenCalledWith(
'Failed to restore: HTTP Error Occurred'
)
// Clean up environment
delete process.env['ACTIONS_CACHE_SERVICE_V2']
delete process.env['ACTIONS_RESULTS_URL']
})
test('restore with restore keys and no cache found', async () => {
+9 -4
View File
@@ -8,6 +8,7 @@ import {restoreCache} from '../src/cache'
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp-client'
import {DownloadOptions} from '../src/options'
import {HttpClientError} from '@actions/http-client'
jest.mock('../src/internal/cacheHttpClient')
jest.mock('../src/internal/cacheUtils')
@@ -95,18 +96,18 @@ test('restore with no cache found', async () => {
test('restore with server error should fail', async () => {
const paths = ['node_modules']
const key = 'node-test'
const logWarningMock = jest.spyOn(core, 'warning')
const logErrorMock = jest.spyOn(core, 'error')
jest
.spyOn(CacheServiceClientJSON.prototype, 'GetCacheEntryDownloadURL')
.mockImplementation(() => {
throw new Error('HTTP Error Occurred')
throw new HttpClientError('HTTP Error Occurred', 500)
})
const cacheKey = await restoreCache(paths, key)
expect(cacheKey).toBe(undefined)
expect(logWarningMock).toHaveBeenCalledTimes(1)
expect(logWarningMock).toHaveBeenCalledWith(
expect(logErrorMock).toHaveBeenCalledTimes(1)
expect(logErrorMock).toHaveBeenCalledWith(
'Failed to restore: HTTP Error Occurred'
)
})
@@ -265,6 +266,7 @@ test('restore with zstd compressed cache found', async () => {
const cacheKey = await restoreCache(paths, key, [], options)
expect(cacheKey).toBe(key)
expect(logInfoMock).toHaveBeenCalledWith(`Cache hit for: ${key}`)
expect(getCacheVersionMock).toHaveBeenCalledWith(
paths,
compressionMethod,
@@ -342,6 +344,9 @@ test('restore with cache found for restore key', async () => {
const cacheKey = await restoreCache(paths, key, restoreKeys, options)
expect(cacheKey).toBe(restoreKeys[0])
expect(logInfoMock).toHaveBeenCalledWith(
`Cache hit for restore-key: ${restoreKeys[0]}`
)
expect(getCacheVersionMock).toHaveBeenCalledWith(
paths,
compressionMethod,
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env node
// Helper script to save cache for e2e testing
import * as cache from '../lib/cache.js'
const [prefix, runId] = process.argv.slice(2)
if (!prefix || !runId) {
console.error('Usage: save-cache.mjs <prefix> <runId>')
process.exit(1)
}
const key = `test-${prefix}-${runId}`
const paths = ['test-cache', '~/test-cache']
console.log(`Saving cache with key: ${key}`)
console.log(`Paths: ${paths.join(', ')}`)
try {
const cacheId = await cache.saveCache(paths, key)
console.log(`Cache saved with ID: ${cacheId}`)
} catch (error) {
console.error('Error saving cache:', error)
process.exit(1)
}
+37 -30
View File
@@ -7,11 +7,12 @@ import * as config from '../src/internal/config'
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
import * as tar from '../src/internal/tar'
import {TypedResponse} from '@actions/http-client/lib/interfaces'
import {HttpClientError} from '@actions/http-client'
import {
ReserveCacheResponse,
ITypedResponseWithError
} from '../src/internal/contracts'
import {HttpClientError} from '@actions/http-client'
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp-client'
jest.mock('../src/internal/cacheHttpClient')
jest.mock('../src/internal/cacheUtils')
@@ -223,46 +224,55 @@ test('save with reserve cache failure should fail', async () => {
test('save with server error should fail', async () => {
const filePath = 'node_modules'
const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const cachePaths = [path.resolve(filePath)]
const logWarningMock = jest.spyOn(core, 'warning')
const cacheId = 4
const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache')
.mockImplementation(async () => {
const response: TypedResponse<ReserveCacheResponse> = {
statusCode: 500,
result: {cacheId},
headers: {}
}
return response
})
const logErrorMock = jest.spyOn(core, 'error')
// Mock cache service version to V2
const getCacheServiceVersionMock = jest
.spyOn(config, 'getCacheServiceVersion')
.mockReturnValue('v2')
// Mock V2 CreateCacheEntry to succeed
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(
Promise.resolve({
ok: true,
signedUploadUrl: 'https://blob-storage.local?signed=true',
message: ''
})
)
// Mock the FinalizeCacheEntryUpload to succeed (since the error should happen in saveCache)
jest
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
.mockReturnValue(
Promise.resolve({ok: true, entryId: '4', message: 'Success'})
)
const createTarMock = jest.spyOn(tar, 'createTar')
// Mock the saveCache call to throw a server error
const saveCacheMock = jest
.spyOn(cacheHttpClient, 'saveCache')
.mockImplementationOnce(() => {
throw new Error('HTTP Error Occurred')
throw new HttpClientError('HTTP Error Occurred', 500)
})
const compression = CompressionMethod.Zstd
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
await saveCache([filePath], primaryKey)
expect(logWarningMock).toHaveBeenCalledTimes(1)
expect(logWarningMock).toHaveBeenCalledWith(
expect(logErrorMock).toHaveBeenCalledTimes(1)
expect(logErrorMock).toHaveBeenCalledWith(
'Failed to save: HTTP Error Occurred'
)
expect(reserveCacheMock).toHaveBeenCalledTimes(1)
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], {
cacheSize: undefined,
compressionMethod: compression,
enableCrossOsArchive: false
})
expect(createCacheEntryMock).toHaveBeenCalledTimes(1)
const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
const cachePaths = [path.resolve(filePath)]
expect(createTarMock).toHaveBeenCalledTimes(1)
expect(createTarMock).toHaveBeenCalledWith(
archiveFolder,
@@ -270,13 +280,10 @@ test('save with server error should fail', async () => {
compression
)
expect(saveCacheMock).toHaveBeenCalledTimes(1)
expect(saveCacheMock).toHaveBeenCalledWith(
cacheId,
archiveFile,
'',
undefined
)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
// Restore the getCacheServiceVersion mock to its original state
getCacheServiceVersionMock.mockRestore()
})
test('save with valid inputs uploads a cache', async () => {
+254 -39
View File
@@ -59,39 +59,6 @@ test('save with missing input should fail', async () => {
)
})
test('save with large cache outputs should fail using', async () => {
const paths = 'node_modules'
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const cachePaths = [path.resolve(paths)]
const createTarMock = jest.spyOn(tar, 'createTar')
const logWarningMock = jest.spyOn(core, 'warning')
const cacheSize = 11 * 1024 * 1024 * 1024 //~11GB, over the 10GB limit
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(cacheSize)
const compression = CompressionMethod.Gzip
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
const cacheId = await saveCache([paths], key)
expect(cacheId).toBe(-1)
expect(logWarningMock).toHaveBeenCalledWith(
'Failed to save: Cache size of ~11264 MB (11811160064 B) is over the 10GB limit, not saving cache.'
)
const archiveFolder = '/foo/bar'
expect(createTarMock).toHaveBeenCalledWith(
archiveFolder,
cachePaths,
compression
)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
})
test('create cache entry failure on non-ok response', async () => {
const paths = ['node_modules']
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
@@ -99,7 +66,7 @@ test('create cache entry failure on non-ok response', async () => {
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockResolvedValue({ok: false, signedUploadUrl: ''})
.mockResolvedValue({ok: false, signedUploadUrl: '', message: ''})
const createTarMock = jest.spyOn(tar, 'createTar')
const finalizeCacheEntryMock = jest.spyOn(
@@ -182,7 +149,7 @@ test('save cache fails if a signedUploadURL was not passed', async () => {
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL})
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
)
const createTarMock = jest.spyOn(tar, 'createTar')
@@ -240,7 +207,7 @@ test('finalize save cache failure', async () => {
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL})
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
)
const createTarMock = jest.spyOn(tar, 'createTar')
@@ -260,7 +227,7 @@ test('finalize save cache failure', async () => {
const finalizeCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
.mockReturnValue(Promise.resolve({ok: false, entryId: ''}))
.mockReturnValue(Promise.resolve({ok: false, entryId: '', message: ''}))
const cacheId = await saveCache([paths], key, options)
@@ -319,7 +286,7 @@ test('save with valid inputs uploads a cache', async () => {
jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL})
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
)
const saveCacheMock = jest.spyOn(cacheHttpClient, 'saveCache')
@@ -332,7 +299,9 @@ test('save with valid inputs uploads a cache', async () => {
const finalizeCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
.mockReturnValue(Promise.resolve({ok: true, entryId: cacheId.toString()}))
.mockReturnValue(
Promise.resolve({ok: true, entryId: cacheId.toString(), message: ''})
)
const expectedCacheId = await saveCache([paths], key)
@@ -360,6 +329,252 @@ test('save with valid inputs uploads a cache', async () => {
expect(expectedCacheId).toBe(cacheId)
})
test('save with extremely large cache should succeed in v2 (no size limit)', async () => {
const paths = 'node_modules'
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const cachePaths = [path.resolve(paths)]
const signedUploadURL = 'https://blob-storage.local?signed=true'
const createTarMock = jest.spyOn(tar, 'createTar')
// Simulate a very large cache (20GB)
const archiveFileSize = 20 * 1024 * 1024 * 1024 // 20GB
const options: UploadOptions = {
archiveSizeBytes: archiveFileSize,
useAzureSdk: true,
uploadChunkSize: 64 * 1024 * 1024,
uploadConcurrency: 8
}
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(archiveFileSize)
const cacheId = 4
jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
)
const saveCacheMock = jest.spyOn(cacheHttpClient, 'saveCache')
const compression = CompressionMethod.Zstd
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValue(Promise.resolve(compression))
const cacheVersion = cacheUtils.getCacheVersion([paths], compression)
const finalizeCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
.mockReturnValue(
Promise.resolve({ok: true, entryId: cacheId.toString(), message: ''})
)
const expectedCacheId = await saveCache([paths], key)
const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
expect(saveCacheMock).toHaveBeenCalledWith(
-1,
archiveFile,
signedUploadURL,
options
)
expect(createTarMock).toHaveBeenCalledWith(
archiveFolder,
cachePaths,
compression
)
expect(finalizeCacheEntryMock).toHaveBeenCalledWith({
key,
version: cacheVersion,
sizeBytes: archiveFileSize.toString()
})
expect(getCompressionMock).toHaveBeenCalledTimes(1)
expect(expectedCacheId).toBe(cacheId)
})
test('save with create cache entry failure and specific error message', async () => {
const paths = ['node_modules']
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const infoLogMock = jest.spyOn(core, 'info')
const warningLogMock = jest.spyOn(core, 'warning')
const errorMessage = 'Cache storage quota exceeded for repository'
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockResolvedValue({ok: false, signedUploadUrl: '', message: errorMessage})
const createTarMock = jest.spyOn(tar, 'createTar')
const compression = CompressionMethod.Zstd
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockResolvedValueOnce(compression)
const archiveFileSize = 1024
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(archiveFileSize)
const cacheId = await saveCache(paths, key)
expect(cacheId).toBe(-1)
expect(warningLogMock).toHaveBeenCalledWith(
`Cache reservation failed: ${errorMessage}`
)
expect(infoLogMock).toHaveBeenCalledWith(
`Failed to save: Unable to reserve cache with key ${key}, another job may be creating this cache.`
)
expect(createCacheEntryMock).toHaveBeenCalledWith({
key,
version: cacheUtils.getCacheVersion(paths, compression)
})
expect(createTarMock).toHaveBeenCalledTimes(1)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
})
test('save with finalize cache entry failure and specific error message', async () => {
const paths = 'node_modules'
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const cachePaths = [path.resolve(paths)]
const logWarningMock = jest.spyOn(core, 'warning')
const signedUploadURL = 'https://blob-storage.local?signed=true'
const archiveFileSize = 1024
const errorMessage =
'Cache entry finalization failed due to concurrent access'
const options: UploadOptions = {
archiveSizeBytes: archiveFileSize,
useAzureSdk: true,
uploadChunkSize: 64 * 1024 * 1024,
uploadConcurrency: 8
}
const createCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
)
const createTarMock = jest.spyOn(tar, 'createTar')
const saveCacheMock = jest
.spyOn(cacheHttpClient, 'saveCache')
.mockResolvedValue()
const compression = CompressionMethod.Zstd
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
const cacheVersion = cacheUtils.getCacheVersion([paths], compression)
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(archiveFileSize)
const finalizeCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
.mockReturnValue(
Promise.resolve({ok: false, entryId: '', message: errorMessage})
)
const cacheId = await saveCache([paths], key, options)
expect(createCacheEntryMock).toHaveBeenCalledWith({
key,
version: cacheVersion
})
const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
expect(createTarMock).toHaveBeenCalledWith(
archiveFolder,
cachePaths,
compression
)
expect(saveCacheMock).toHaveBeenCalledWith(
-1,
archiveFile,
signedUploadURL,
options
)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
expect(finalizeCacheEntryMock).toHaveBeenCalledWith({
key,
version: cacheVersion,
sizeBytes: archiveFileSize.toString()
})
expect(cacheId).toBe(-1)
expect(logWarningMock).toHaveBeenCalledWith(errorMessage)
})
test('save with multiple large caches should succeed in v2 (testing 50GB)', async () => {
const paths = ['large-dataset', 'node_modules', 'build-artifacts']
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const cachePaths = paths.map(p => path.resolve(p))
const signedUploadURL = 'https://blob-storage.local?signed=true'
const createTarMock = jest.spyOn(tar, 'createTar')
// Simulate an extremely large cache (50GB)
const archiveFileSize = 50 * 1024 * 1024 * 1024 // 50GB
const options: UploadOptions = {
archiveSizeBytes: archiveFileSize,
useAzureSdk: true,
uploadChunkSize: 64 * 1024 * 1024,
uploadConcurrency: 8
}
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(archiveFileSize)
const cacheId = 7
jest
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
.mockReturnValue(
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
)
const saveCacheMock = jest.spyOn(cacheHttpClient, 'saveCache')
const compression = CompressionMethod.Zstd
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValue(Promise.resolve(compression))
const cacheVersion = cacheUtils.getCacheVersion(paths, compression)
const finalizeCacheEntryMock = jest
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
.mockReturnValue(
Promise.resolve({ok: true, entryId: cacheId.toString(), message: ''})
)
const expectedCacheId = await saveCache(paths, key)
const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
expect(saveCacheMock).toHaveBeenCalledWith(
-1,
archiveFile,
signedUploadURL,
options
)
expect(createTarMock).toHaveBeenCalledWith(
archiveFolder,
cachePaths,
compression
)
expect(finalizeCacheEntryMock).toHaveBeenCalledWith({
key,
version: cacheVersion,
sizeBytes: archiveFileSize.toString()
})
expect(getCompressionMock).toHaveBeenCalledTimes(1)
expect(expectedCacheId).toBe(cacheId)
})
test('save with non existing path should not save cache using v2 saveCache', async () => {
const path = 'node_modules'
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
+1 -1
View File
@@ -1,5 +1,5 @@
import * as uploadUtils from '../src/internal/uploadUtils'
import {TransferProgressEvent} from '@azure/ms-rest-js'
import {TransferProgressEvent} from '@azure/core-rest-pipeline'
test('upload progress tracked correctly', () => {
const progress = new uploadUtils.UploadProgress(1000)
+371 -817
View File
File diff suppressed because it is too large Load Diff
+25 -15
View File
@@ -1,7 +1,6 @@
{
"name": "@actions/cache",
"version": "4.0.3",
"preview": true,
"version": "6.0.0",
"description": "Actions cache lib",
"keywords": [
"github",
@@ -10,8 +9,15 @@
],
"homepage": "https://github.com/actions/toolkit/tree/main/packages/cache",
"license": "MIT",
"type": "module",
"main": "lib/cache.js",
"types": "lib/cache.d.ts",
"exports": {
".": {
"types": "./lib/cache.d.ts",
"import": "./lib/cache.js"
}
},
"directories": {
"lib": "lib",
"test": "__tests__"
@@ -31,26 +37,30 @@
"scripts": {
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
"test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc"
"tsc": "tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"
},
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"dependencies": {
"@actions/core": "^1.11.1",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^2.1.1",
"@actions/io": "^1.0.1",
"@azure/abort-controller": "^1.1.0",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.13.0",
"@protobuf-ts/plugin": "^2.9.4",
"semver": "^6.3.1"
"@actions/core": "^3.0.0",
"@actions/exec": "^3.0.0",
"@actions/glob": "^0.6.1",
"@actions/http-client": "^4.0.0",
"@actions/io": "^3.0.0",
"@azure/core-rest-pipeline": "^1.22.0",
"@azure/storage-blob": "^12.30.0",
"@protobuf-ts/runtime-rpc": "^2.11.1",
"semver": "^7.7.3"
},
"devDependencies": {
"@types/node": "^22.13.9",
"@types/semver": "^6.0.0",
"@protobuf-ts/plugin": "^2.9.4",
"@types/node": "^25.1.0",
"@types/semver": "^7.7.1",
"typescript": "^5.2.2"
},
"overrides": {
"uri-js": "npm:uri-js-replace@^1.0.1",
"node-fetch": "^3.3.2"
}
}
+86 -25
View File
@@ -1,18 +1,20 @@
import * as core from '@actions/core'
import * as path from 'path'
import * as utils from './internal/cacheUtils'
import * as cacheHttpClient from './internal/cacheHttpClient'
import * as cacheTwirpClient from './internal/shared/cacheTwirpClient'
import {getCacheServiceVersion, isGhes} from './internal/config'
import {DownloadOptions, UploadOptions} from './options'
import {createTar, extractTar, listTar} from './internal/tar'
import * as utils from './internal/cacheUtils.js'
import * as cacheHttpClient from './internal/cacheHttpClient.js'
import * as cacheTwirpClient from './internal/shared/cacheTwirpClient.js'
import {getCacheServiceVersion, isGhes} from './internal/config.js'
import {DownloadOptions, UploadOptions} from './options.js'
import {createTar, extractTar, listTar} from './internal/tar.js'
import {
CreateCacheEntryRequest,
FinalizeCacheEntryUploadRequest,
FinalizeCacheEntryUploadResponse,
GetCacheEntryDownloadURLRequest
} from './generated/results/api/v1/cache'
import {CacheFileSizeLimit} from './internal/constants'
} from './generated/results/api/v1/cache.js'
import {HttpClientError} from '@actions/http-client'
export type {DownloadOptions, UploadOptions}
export class ValidationError extends Error {
constructor(message: string) {
super(message)
@@ -29,6 +31,14 @@ export class ReserveCacheError extends Error {
}
}
export class FinalizeCacheError extends Error {
constructor(message: string) {
super(message)
this.name = 'FinalizeCacheError'
Object.setPrototypeOf(this, FinalizeCacheError.prototype)
}
}
function checkPaths(paths: string[]): void {
if (!paths || paths.length === 0) {
throw new ValidationError(
@@ -57,7 +67,18 @@ function checkKey(key: string): void {
* @returns boolean return true if Actions cache service feature is available, otherwise false
*/
export function isFeatureAvailable(): boolean {
return !!process.env['ACTIONS_CACHE_URL']
const cacheServiceVersion = getCacheServiceVersion()
// Check availability based on cache service version
switch (cacheServiceVersion) {
case 'v2':
// For v2, we need ACTIONS_RESULTS_URL
return !!process.env['ACTIONS_RESULTS_URL']
case 'v1':
default:
// For v1, we only need ACTIONS_CACHE_URL
return !!process.env['ACTIONS_CACHE_URL']
}
}
/**
@@ -186,8 +207,17 @@ async function restoreCacheV1(
if (typedError.name === ValidationError.name) {
throw error
} else {
// Supress all non-validation cache related errors because caching should be optional
core.warning(`Failed to restore: ${(error as Error).message}`)
// warn on cache restore failure and continue build
// Log server errors (5xx) as errors, all other errors as warnings
if (
typedError instanceof HttpClientError &&
typeof typedError.statusCode === 'number' &&
typedError.statusCode >= 500
) {
core.error(`Failed to restore: ${(error as Error).message}`)
} else {
core.warning(`Failed to restore: ${(error as Error).message}`)
}
}
} finally {
// Try to delete the archive to save space
@@ -264,7 +294,12 @@ async function restoreCacheV2(
return undefined
}
core.info(`Cache hit for: ${request.key}`)
const isRestoreKeyMatch = request.key !== response.matchedKey
if (isRestoreKeyMatch) {
core.info(`Cache hit for restore-key: ${response.matchedKey}`)
} else {
core.info(`Cache hit for: ${response.matchedKey}`)
}
if (options?.lookupOnly) {
core.info('Lookup only - skipping download')
@@ -305,7 +340,16 @@ async function restoreCacheV2(
throw error
} else {
// Supress all non-validation cache related errors because caching should be optional
core.warning(`Failed to restore: ${(error as Error).message}`)
// Log server errors (5xx) as errors, all other errors as warnings
if (
typedError instanceof HttpClientError &&
typeof typedError.statusCode === 'number' &&
typedError.statusCode >= 500
) {
core.error(`Failed to restore: ${(error as Error).message}`)
} else {
core.warning(`Failed to restore: ${(error as Error).message}`)
}
}
} finally {
try {
@@ -437,7 +481,16 @@ async function saveCacheV1(
} else if (typedError.name === ReserveCacheError.name) {
core.info(`Failed to save: ${typedError.message}`)
} else {
core.warning(`Failed to save: ${typedError.message}`)
// Log server errors (5xx) as errors, all other errors as warnings
if (
typedError instanceof HttpClientError &&
typeof typedError.statusCode === 'number' &&
typedError.statusCode >= 500
) {
core.error(`Failed to save: ${typedError.message}`)
} else {
core.warning(`Failed to save: ${typedError.message}`)
}
}
} finally {
// Try to delete the archive to save space
@@ -506,15 +559,6 @@ async function saveCacheV2(
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath)
core.debug(`File Size: ${archiveFileSize}`)
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
if (archiveFileSize > CacheFileSizeLimit && !isGhes()) {
throw new Error(
`Cache size of ~${Math.round(
archiveFileSize / (1024 * 1024)
)} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`
)
}
// Set the archive size in the options, will be used to display the upload progress
options.archiveSizeBytes = archiveFileSize
@@ -534,7 +578,10 @@ async function saveCacheV2(
try {
const response = await twirpClient.CreateCacheEntry(request)
if (!response.ok) {
throw new Error('Response was not ok')
if (response.message) {
core.warning(`Cache reservation failed: ${response.message}`)
}
throw new Error(response.message || 'Response was not ok')
}
signedUploadUrl = response.signedUploadUrl
} catch (error) {
@@ -563,6 +610,9 @@ async function saveCacheV2(
core.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`)
if (!finalizeResponse.ok) {
if (finalizeResponse.message) {
throw new FinalizeCacheError(finalizeResponse.message)
}
throw new Error(
`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`
)
@@ -575,8 +625,19 @@ async function saveCacheV2(
throw error
} else if (typedError.name === ReserveCacheError.name) {
core.info(`Failed to save: ${typedError.message}`)
} else if (typedError.name === FinalizeCacheError.name) {
core.warning(typedError.message)
} else {
core.warning(`Failed to save: ${typedError.message}`)
// Log server errors (5xx) as errors, all other errors as warnings
if (
typedError instanceof HttpClientError &&
typeof typedError.statusCode === 'number' &&
typedError.statusCode >= 500
) {
core.error(`Failed to save: ${typedError.message}`)
} else {
core.warning(`Failed to save: ${typedError.message}`)
}
}
} finally {
// Try to delete the archive to save space
+31 -5
View File
@@ -12,7 +12,7 @@ import type { PartialMessage } from "@protobuf-ts/runtime";
import { reflectionMergePartial } from "@protobuf-ts/runtime";
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
import { MessageType } from "@protobuf-ts/runtime";
import { CacheMetadata } from "../../entities/v1/cachemetadata";
import { CacheMetadata } from "../../entities/v1/cachemetadata.js";
/**
* @generated from protobuf message github.actions.results.api.v1.CreateCacheEntryRequest
*/
@@ -50,6 +50,12 @@ export interface CreateCacheEntryResponse {
* @generated from protobuf field: string signed_upload_url = 2;
*/
signedUploadUrl: string;
/**
* When !ok, this field may contain a human-readable error message used to create an annotation
*
* @generated from protobuf field: string message = 3;
*/
message: string;
}
/**
* @generated from protobuf message github.actions.results.api.v1.FinalizeCacheEntryUploadRequest
@@ -94,6 +100,12 @@ export interface FinalizeCacheEntryUploadResponse {
* @generated from protobuf field: int64 entry_id = 2;
*/
entryId: string;
/**
* When !ok, this field may contain a human-readable error message used to create an annotation
*
* @generated from protobuf field: string message = 3;
*/
message: string;
}
/**
* @generated from protobuf message github.actions.results.api.v1.GetCacheEntryDownloadURLRequest
@@ -211,11 +223,12 @@ class CreateCacheEntryResponse$Type extends MessageType<CreateCacheEntryResponse
constructor() {
super("github.actions.results.api.v1.CreateCacheEntryResponse", [
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
]);
}
create(value?: PartialMessage<CreateCacheEntryResponse>): CreateCacheEntryResponse {
const message = { ok: false, signedUploadUrl: "" };
const message = { ok: false, signedUploadUrl: "", message: "" };
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
if (value !== undefined)
reflectionMergePartial<CreateCacheEntryResponse>(this, message, value);
@@ -232,6 +245,9 @@ class CreateCacheEntryResponse$Type extends MessageType<CreateCacheEntryResponse
case /* string signed_upload_url */ 2:
message.signedUploadUrl = reader.string();
break;
case /* string message */ 3:
message.message = reader.string();
break;
default:
let u = options.readUnknownField;
if (u === "throw")
@@ -250,6 +266,9 @@ class CreateCacheEntryResponse$Type extends MessageType<CreateCacheEntryResponse
/* string signed_upload_url = 2; */
if (message.signedUploadUrl !== "")
writer.tag(2, WireType.LengthDelimited).string(message.signedUploadUrl);
/* string message = 3; */
if (message.message !== "")
writer.tag(3, WireType.LengthDelimited).string(message.message);
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -333,11 +352,12 @@ class FinalizeCacheEntryUploadResponse$Type extends MessageType<FinalizeCacheEnt
constructor() {
super("github.actions.results.api.v1.FinalizeCacheEntryUploadResponse", [
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ },
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
]);
}
create(value?: PartialMessage<FinalizeCacheEntryUploadResponse>): FinalizeCacheEntryUploadResponse {
const message = { ok: false, entryId: "0" };
const message = { ok: false, entryId: "0", message: "" };
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
if (value !== undefined)
reflectionMergePartial<FinalizeCacheEntryUploadResponse>(this, message, value);
@@ -354,6 +374,9 @@ class FinalizeCacheEntryUploadResponse$Type extends MessageType<FinalizeCacheEnt
case /* int64 entry_id */ 2:
message.entryId = reader.int64().toString();
break;
case /* string message */ 3:
message.message = reader.string();
break;
default:
let u = options.readUnknownField;
if (u === "throw")
@@ -372,6 +395,9 @@ class FinalizeCacheEntryUploadResponse$Type extends MessageType<FinalizeCacheEnt
/* int64 entry_id = 2; */
if (message.entryId !== "0")
writer.tag(2, WireType.Varint).int64(message.entryId);
/* string message = 3; */
if (message.message !== "")
writer.tag(3, WireType.LengthDelimited).string(message.message);
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -5,7 +5,7 @@ import {
FinalizeCacheEntryUploadResponse,
GetCacheEntryDownloadURLRequest,
GetCacheEntryDownloadURLResponse,
} from "./cache";
} from "./cache.js";
//==================================//
// Client Code //
@@ -11,7 +11,7 @@ import type { PartialMessage } from "@protobuf-ts/runtime";
import { reflectionMergePartial } from "@protobuf-ts/runtime";
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
import { MessageType } from "@protobuf-ts/runtime";
import { CacheScope } from "./cachescope";
import { CacheScope } from "./cachescope.js";
/**
* @generated from protobuf message github.actions.results.entities.v1.CacheMetadata
*/
+8 -8
View File
@@ -7,8 +7,8 @@ import {
} from '@actions/http-client/lib/interfaces'
import * as fs from 'fs'
import {URL} from 'url'
import * as utils from './cacheUtils'
import {uploadCacheArchiveSDK} from './uploadUtils'
import * as utils from './cacheUtils.js'
import {uploadCacheArchiveSDK} from './uploadUtils.js'
import {
ArtifactCacheEntry,
InternalCacheOptions,
@@ -17,25 +17,25 @@ import {
ReserveCacheResponse,
ITypedResponseWithError,
ArtifactCacheList
} from './contracts'
} from './contracts.js'
import {
downloadCacheHttpClient,
downloadCacheHttpClientConcurrent,
downloadCacheStorageSDK
} from './downloadUtils'
} from './downloadUtils.js'
import {
DownloadOptions,
UploadOptions,
getDownloadOptions,
getUploadOptions
} from '../options'
} from '../options.js'
import {
isSuccessStatusCode,
retryHttpClientResponse,
retryTypedResponse
} from './requestUtils'
import {getCacheServiceURL} from './config'
import {getUserAgentString} from './shared/user-agent'
} from './requestUtils.js'
import {getCacheServiceURL} from './config.js'
import {getUserAgentString} from './shared/user-agent.js'
function getCacheApiUrl(resource: string): string {
const baseUrl: string = getCacheServiceURL()
+1 -1
View File
@@ -11,7 +11,7 @@ import {
CacheFilename,
CompressionMethod,
GnuTarPathOnWindows
} from './constants'
} from './constants.js'
const versionSalt = '1.0'
@@ -1,4 +1,4 @@
import {CompressionMethod} from './constants'
import {CompressionMethod} from './constants.js'
import {TypedResponse} from '@actions/http-client/lib/interfaces'
import {HttpClientError} from '@actions/http-client'
+5 -7
View File
@@ -1,18 +1,16 @@
import * as core from '@actions/core'
import {HttpClient, HttpClientResponse} from '@actions/http-client'
import {BlockBlobClient} from '@azure/storage-blob'
import {TransferProgressEvent} from '@azure/ms-rest-js'
import {TransferProgressEvent} from '@azure/core-rest-pipeline'
import * as buffer from 'buffer'
import * as fs from 'fs'
import * as stream from 'stream'
import * as util from 'util'
import * as utils from './cacheUtils'
import {SocketTimeout} from './constants'
import {DownloadOptions} from '../options'
import {retryHttpClientResponse} from './requestUtils'
import {AbortController} from '@azure/abort-controller'
import * as utils from './cacheUtils.js'
import {SocketTimeout} from './constants.js'
import {DownloadOptions} from '../options.js'
import {retryHttpClientResponse} from './requestUtils.js'
/**
* Pipes the body of a HTTP response to a stream
+2 -2
View File
@@ -4,8 +4,8 @@ import {
HttpClientError,
HttpClientResponse
} from '@actions/http-client'
import {DefaultRetryDelay, DefaultRetryAttempts} from './constants'
import {ITypedResponseWithError} from './contracts'
import {DefaultRetryDelay, DefaultRetryAttempts} from './constants.js'
import {ITypedResponseWithError} from './contracts.js'
export function isSuccessStatusCode(statusCode?: number): boolean {
if (!statusCode) {
+27 -9
View File
@@ -1,12 +1,12 @@
import {info, debug} from '@actions/core'
import {getUserAgentString} from './user-agent'
import {NetworkError, UsageError} from './errors'
import {getCacheServiceURL} from '../config'
import {getRuntimeToken} from '../cacheUtils'
import {info, debug, warning} from '@actions/core'
import {getUserAgentString} from './user-agent.js'
import {NetworkError, RateLimitError, UsageError} from './errors.js'
import {getCacheServiceURL} from '../config.js'
import {getRuntimeToken} from '../cacheUtils.js'
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
import {HttpClient, HttpClientResponse, HttpCodes} from '@actions/http-client'
import {CacheServiceClientJSON} from '../../generated/results/api/v1/cache.twirp-client'
import {maskSecretUrls} from './util'
import {CacheServiceClientJSON} from '../../generated/results/api/v1/cache.twirp-client.js'
import {maskSecretUrls} from './util.js'
// The twirp http client must implement this interface
interface Rpc {
@@ -109,6 +109,21 @@ class CacheServiceClient implements Rpc {
errorMessage = `${errorMessage}: ${body.msg}`
}
// Handle rate limiting - don't retry, just warn and exit
// For more info, see https://docs.github.com/en/actions/reference/limits
if (statusCode === HttpCodes.TooManyRequests) {
const retryAfterHeader = response.message.headers['retry-after']
if (retryAfterHeader) {
const parsedSeconds = parseInt(retryAfterHeader, 10)
if (!isNaN(parsedSeconds) && parsedSeconds > 0) {
warning(
`You've hit a rate limit, your rate limit will reset in ${parsedSeconds} seconds`
)
}
}
throw new RateLimitError(`Rate limited: ${errorMessage}`)
}
} catch (error) {
if (error instanceof SyntaxError) {
debug(`Raw Body: ${rawBody}`)
@@ -118,6 +133,10 @@ class CacheServiceClient implements Rpc {
throw error
}
if (error instanceof RateLimitError) {
throw error
}
if (NetworkError.isNetworkErrorCode(error?.code)) {
throw new NetworkError(error?.code)
}
@@ -162,8 +181,7 @@ class CacheServiceClient implements Rpc {
HttpCodes.BadGateway,
HttpCodes.GatewayTimeout,
HttpCodes.InternalServerError,
HttpCodes.ServiceUnavailable,
HttpCodes.TooManyRequests
HttpCodes.ServiceUnavailable
]
return retryableStatusCodes.includes(statusCode)
+7
View File
@@ -70,3 +70,10 @@ export class UsageError extends Error {
return msg.includes('insufficient usage')
}
}
export class RateLimitError extends Error {
constructor(message: string) {
super(message)
this.name = 'RateLimitError'
}
}
@@ -0,0 +1,7 @@
// This file exists as a CommonJS module to read the version from package.json.
// In an ESM package, using `require()` directly in .ts files requires disabling
// ESLint rules and doesn't work reliably across all Node.js versions.
// By keeping this as a .cjs file, we can use require() naturally and export
// the version for the ESM modules to import.
const packageJson = require('../../../package.json')
module.exports = { version: packageJson.version }
+2 -3
View File
@@ -1,9 +1,8 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
const packageJson = require('../../../package.json')
import {version} from './package-version.cjs'
/**
* Ensure that this User Agent String is used in all HTTP calls so that we can monitor telemetry between different versions of this package
*/
export function getUserAgentString(): string {
return `@actions/cache-${packageJson.version}`
return `@actions/cache-${version}`
}
+3 -3
View File
@@ -2,15 +2,15 @@ import {exec} from '@actions/exec'
import * as io from '@actions/io'
import {existsSync, writeFileSync} from 'fs'
import * as path from 'path'
import * as utils from './cacheUtils'
import {ArchiveTool} from './contracts'
import * as utils from './cacheUtils.js'
import {ArchiveTool} from './contracts.js'
import {
CompressionMethod,
SystemTarPathOnWindows,
ArchiveToolType,
TarFilename,
ManifestFilename
} from './constants'
} from './constants.js'
const IS_WINDOWS = process.platform === 'win32'
+3 -3
View File
@@ -5,9 +5,9 @@ import {
BlockBlobClient,
BlockBlobParallelUploadOptions
} from '@azure/storage-blob'
import {TransferProgressEvent} from '@azure/ms-rest-js'
import {InvalidResponseError} from './shared/errors'
import {UploadOptions} from '../options'
import {TransferProgressEvent} from '@azure/core-rest-pipeline'
import {InvalidResponseError} from './shared/errors.js'
import {UploadOptions} from '../options.js'
/**
* Class for tracking the upload state and displaying stats.
+2
View File
@@ -4,6 +4,8 @@
"baseUrl": "./",
"outDir": "./lib",
"rootDir": "./src",
"module": "node16",
"moduleResolution": "node16",
"lib": [
"es6",
"dom"
+1 -1
View File
@@ -16,7 +16,7 @@ import * as core from '@actions/core';
#### Inputs/Outputs
Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` set to be false, the input should have a default value in `action.yml`.
Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` is set to be false, the input should have a default value in `action.yml`.
Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled.
+41 -5
View File
@@ -1,63 +1,99 @@
# @actions/core Releases
### 1.11.1
## 3.0.0
- **Breaking change**: Package is now ESM-only
- CommonJS consumers must use dynamic `import()` instead of `require()`
## 2.0.3
- Bump `@actions/http-client` to `3.0.2`
## 2.0.1
- Bump @actions/exec from 1.1.1 to 2.0.0 [#2199](https://github.com/actions/toolkit/pull/2199)
## 2.0.0
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
- Bump @actions/http-client from 2.0.1 to 3.0.0
## 1.11.1
- Fix uses of `crypto.randomUUID` on Node 18 and earlier [#1842](https://github.com/actions/toolkit/pull/1842)
### 1.11.0
- Add platform info utilities [#1551](https://github.com/actions/toolkit/pull/1551)
- Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824)
### 1.10.1
- Fix error message reference in oidc utils [#1511](https://github.com/actions/toolkit/pull/1511)
### 1.10.0
- `saveState` and `setOutput` now use environment files if available [#1178](https://github.com/actions/toolkit/pull/1178)
- `getMultilineInput` now correctly trims whitespace by default [#1185](https://github.com/actions/toolkit/pull/1185)
### 1.9.1
- Randomize delimiter when calling `core.exportVariable`
### 1.9.0
- Added `toPosixPath`, `toWin32Path` and `toPlatformPath` utilities [#1102](https://github.com/actions/toolkit/pull/1102)
### 1.8.2
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
### 1.8.1
- Update to v2.0.0 of `@actions/http-client`
### 1.8.0
- Deprecate `markdownSummary` extension export in favor of `summary`
- https://github.com/actions/toolkit/pull/1072
- https://github.com/actions/toolkit/pull/1073
- <https://github.com/actions/toolkit/pull/1072>
- <https://github.com/actions/toolkit/pull/1073>
### 1.7.0
- [Added `markdownSummary` extension](https://github.com/actions/toolkit/pull/1014)
### 1.6.0
- [Added OIDC Client function `getIDToken`](https://github.com/actions/toolkit/pull/919)
- [Added `file` parameter to `AnnotationProperties`](https://github.com/actions/toolkit/pull/896)
- [Added `file` parameter to `AnnotationProperties`](https://github.com/actions/toolkit/pull/896)
### 1.5.0
- [Added support for notice annotations and more annotation fields](https://github.com/actions/toolkit/pull/855)
### 1.4.0
- [Added the `getMultilineInput` function](https://github.com/actions/toolkit/pull/829)
### 1.3.0
- [Added the trimWhitespace option to getInput](https://github.com/actions/toolkit/pull/802)
- [Added the getBooleanInput function](https://github.com/actions/toolkit/pull/725)
### 1.2.7
- [Prepend newline for set-output](https://github.com/actions/toolkit/pull/772)
### 1.2.6
- [Update `exportVariable` and `addPath` to use environment files](https://github.com/actions/toolkit/pull/571)
### 1.2.5
- [Correctly bundle License File with package](https://github.com/actions/toolkit/pull/548)
### 1.2.4
- [Be more lenient in accepting non-string command inputs](https://github.com/actions/toolkit/pull/405)
- [Add Echo commands](https://github.com/actions/toolkit/pull/411)
@@ -78,7 +114,7 @@
- saveState and getState functions for wrapper tasks (on finally entry points that run post job)
### 1.1.3
### 1.1.3
- setSecret added to register a secret with the runner to be masked from the logs
- exportSecret which was not implemented and never worked was removed after clarification from product.
+1 -1
View File
@@ -1,4 +1,4 @@
import * as command from '../src/command'
import * as command from '../src/command.js'
import * as os from 'os'
/* eslint-disable @typescript-eslint/unbound-method */
+5 -2
View File
@@ -1,9 +1,9 @@
import * as fs from 'fs'
import * as os from 'os'
import * as path from 'path'
import * as core from '../src/core'
import * as core from '../src/core.js'
import {HttpClient} from '@actions/http-client'
import {toCommandProperties} from '../src/utils'
import {toCommandProperties} from '../src/utils.js'
/* eslint-disable @typescript-eslint/unbound-method */
@@ -677,5 +677,8 @@ describe('oidc-client-tests', () => {
const http = new HttpClient('actions/oidc-client')
const res = await http.get(getTokenEndPoint())
expect(res.message.statusCode).toBe(200)
// Consume the response to close the socket
await res.readBody()
res.message.destroy()
})
})
+1 -1
View File
@@ -1,6 +1,6 @@
import * as path from 'path'
import {toPlatformPath, toPosixPath, toWin32Path} from '../src/path-utils'
import {toPlatformPath, toPosixPath, toWin32Path} from '../src/path-utils.js'
describe('#toPosixPath', () => {
const cases: {
+1 -1
View File
@@ -1,5 +1,5 @@
import os from 'os'
import {platform} from '../src/core'
import {platform} from '../src/core.js'
describe('getInfo', () => {
it('returns the platform info', async () => {
+1 -1
View File
@@ -1,7 +1,7 @@
import * as fs from 'fs'
import * as os from 'os'
import path from 'path'
import {summary, SUMMARY_ENV_VAR} from '../src/summary'
import {summary, SUMMARY_ENV_VAR} from '../src/summary.js'
const testDirectoryPath = path.join(__dirname, 'test')
const testFilePath = path.join(testDirectoryPath, 'test-summary.md')
+44 -53
View File
@@ -1,89 +1,80 @@
{
"name": "@actions/core",
"version": "1.11.1",
"lockfileVersion": 2,
"version": "3.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@actions/core",
"version": "1.11.1",
"version": "3.0.0",
"license": "MIT",
"dependencies": {
"@actions/exec": "^1.1.1",
"@actions/http-client": "^2.0.1"
"@actions/exec": "^3.0.0",
"@actions/http-client": "^4.0.0"
},
"devDependencies": {
"@types/node": "^16.18.112"
"@types/node": "^25.1.0"
}
},
"node_modules/@actions/exec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
"license": "MIT",
"dependencies": {
"@actions/io": "^1.0.1"
"@actions/io": "^3.0.2"
}
},
"node_modules/@actions/http-client": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
"integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
"license": "MIT",
"dependencies": {
"tunnel": "^0.0.6"
"tunnel": "^0.0.6",
"undici": "^6.23.0"
}
},
"node_modules/@actions/io": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==",
"license": "MIT"
},
"node_modules/@types/node": {
"version": "16.18.112",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.112.tgz",
"integrity": "sha512-EKrbKUGJROm17+dY/gMi31aJlGLJ75e1IkTojt9n6u+hnaTBDs+M1bIdOawpk2m6YUAXq/R2W0SxCng1tndHCg==",
"dev": true
"version": "25.1.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz",
"integrity": "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
}
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"license": "MIT",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
}
},
"dependencies": {
"@actions/exec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"requires": {
"@actions/io": "^1.0.1"
},
"node_modules/undici": {
"version": "6.23.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
"license": "MIT",
"engines": {
"node": ">=18.17"
}
},
"@actions/http-client": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
"integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
"requires": {
"tunnel": "^0.0.6"
}
},
"@actions/io": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
},
"@types/node": {
"version": "16.18.112",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.112.tgz",
"integrity": "sha512-EKrbKUGJROm17+dY/gMi31aJlGLJ75e1IkTojt9n6u+hnaTBDs+M1bIdOawpk2m6YUAXq/R2W0SxCng1tndHCg==",
"dev": true
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"dev": true,
"license": "MIT"
}
}
}
+11 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/core",
"version": "1.11.1",
"version": "3.0.0",
"description": "Actions core lib",
"keywords": [
"github",
@@ -9,8 +9,15 @@
],
"homepage": "https://github.com/actions/toolkit/tree/main/packages/core",
"license": "MIT",
"type": "module",
"main": "lib/core.js",
"types": "lib/core.d.ts",
"exports": {
".": {
"types": "./lib/core.d.ts",
"import": "./lib/core.js"
}
},
"directories": {
"lib": "lib",
"test": "__tests__"
@@ -36,10 +43,10 @@
"url": "https://github.com/actions/toolkit/issues"
},
"dependencies": {
"@actions/exec": "^1.1.1",
"@actions/http-client": "^2.0.1"
"@actions/exec": "^3.0.0",
"@actions/http-client": "^4.0.0"
},
"devDependencies": {
"@types/node": "^16.18.112"
"@types/node": "^25.1.0"
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
import * as os from 'os'
import {toCommandValue} from './utils'
import {toCommandValue} from './utils.js'
// For internal use, subject to change.
+8 -8
View File
@@ -1,11 +1,11 @@
import {issue, issueCommand} from './command'
import {issueFileCommand, prepareKeyValueMessage} from './file-command'
import {toCommandProperties, toCommandValue} from './utils'
import {issue, issueCommand} from './command.js'
import {issueFileCommand, prepareKeyValueMessage} from './file-command.js'
import {toCommandProperties, toCommandValue} from './utils.js'
import * as os from 'os'
import * as path from 'path'
import {OidcClient} from './oidc-utils'
import {OidcClient} from './oidc-utils.js'
/**
* Interface for getInput options
@@ -400,19 +400,19 @@ export async function getIDToken(aud?: string): Promise<string> {
/**
* Summary exports
*/
export {summary} from './summary'
export {summary} from './summary.js'
/**
* @deprecated use core.summary
*/
export {markdownSummary} from './summary'
export {markdownSummary} from './summary.js'
/**
* Path exports
*/
export {toPosixPath, toWin32Path, toPlatformPath} from './path-utils'
export {toPosixPath, toWin32Path, toPlatformPath} from './path-utils.js'
/**
* Platform utilities exports
*/
export * as platform from './platform'
export * as platform from './platform.js'
+1 -1
View File
@@ -6,7 +6,7 @@
import * as crypto from 'crypto'
import * as fs from 'fs'
import * as os from 'os'
import {toCommandValue} from './utils'
import {toCommandValue} from './utils.js'
export function issueFileCommand(command: string, message: any): void {
const filePath = process.env[`GITHUB_${command}`]

Some files were not shown because too many files have changed in this diff Show More