Compare commits

...

100 Commits

Author SHA1 Message Date
Sankalp Kotewar 0f583c7958 Removed abortcontroller 2023-03-24 10:29:06 +00:00
Vallie Joseph 457303960f toolkit/io 1.1.3 release (#1374)
* updating version

* adding new minor version to package-lock

* updating release doc

* Update packages/io/RELEASES.md

Co-authored-by: Cory Miller <13227161+cory-miller@users.noreply.github.com>

---------

Co-authored-by: Cory Miller <13227161+cory-miller@users.noreply.github.com>
2023-03-15 15:10:56 -04:00
Vallie Joseph 463b49d872 Removing childprocess for rmRF (#1373)
* try awaiting spawn on windows

* formatting

* updating package-lock

* .

* .

* updating packages

* adding sync rm

* test with sync

* pointing to rmsync

* adding error handling

* testing rmsync

* adding try/catch

* adding windows conditional for locked file

* switch to contians

* fixing formatting

* fixing formatting

* fixing formatting

* adding enonet catch for windows files

* adding enonet catch for windows files

* adding catch for file not found

* updating stat call

* updating stat call

* adding conditonal for symlink

* removing symlink test

* adding ebusy check

* changing error check

* changing error check

* changing error check

* changing error check

* cleanup and comments

* Update packages/io/__tests__/io.test.ts

Co-authored-by: Cory Miller <13227161+cory-miller@users.noreply.github.com>

* Update packages/io/src/io-util.ts

Co-authored-by: Cory Miller <13227161+cory-miller@users.noreply.github.com>

* moving comment placement

* updating eperm

* change back to ebusy

* Update packages/io/__tests__/io.test.ts

Co-authored-by: Cory Miller <13227161+cory-miller@users.noreply.github.com>

* Formatting

* converting to async

---------

Co-authored-by: Cory Miller <13227161+cory-miller@users.noreply.github.com>
2023-03-15 14:51:02 -04:00
Sankalp Kotewar a91ee0b497 Merge pull request #1367 from actions/kotewar/update-readme
Update README for latest cache release changes
2023-03-09 16:36:44 +05:30
Sankalp Kotewar 94e340bfb1 Update README.md 2023-03-09 16:24:15 +05:30
Sankalp Kotewar 599c6164e8 Update README.md 2023-03-09 16:23:41 +05:30
Sankalp Kotewar b8261b0fb0 Update README.md 2023-03-09 16:21:20 +05:30
Sankalp Kotewar aeb16eeca1 Merge pull request #1363 from actions/kotewar/updating-blobstorage-client-to-12.13.0
Updating blob storage client to 12.13.0 in actions/cache
2023-03-09 16:01:52 +05:30
Sankalp Kotewar 7a11743b35 Fixed typo 2023-03-08 19:14:15 +00:00
Sankalp Kotewar fe92749762 Merge branch 'main' into kotewar/updating-blobstorage-client-to-12.13.0 2023-03-09 00:33:52 +05:30
Sankalp Kotewar 0e8edb0780 Merge pull request #1286 from cdce8p/cache-dry-run
Add cache restore `lookupOnly` option
2023-03-08 17:45:20 +05:30
Sankalp Kotewar 7d1daaf15e Fixed test case 2023-03-08 09:26:29 +00:00
Sankalp Kotewar 40ec298d4b updated segment timeout to 10 mins 2023-03-08 07:28:50 +00:00
Ferenc Hammerl 787b2cf270 Bump http-client to version 2.1.0 (#1364)
* Update package.json

* Update package.json

* Update RELEASES.md
2023-03-06 17:03:09 +01:00
Sankalp Kotewar 8e32b1fca3 updated version prefix to caret for ts dep 2023-03-06 13:38:19 +00:00
Sankalp Kotewar d9a2c5a9f9 updated comment with more info 2023-03-06 13:20:45 +00:00
Sankalp Kotewar e6e7b6156f updated segment size to 128MB for failing fast 2023-03-06 13:11:54 +00:00
Sankalp Kotewar f3de1e53d6 updated version 2023-03-06 12:36:29 +00:00
Sankalp Kotewar 703d5ac24a fixed lockfile 2023-03-06 12:22:47 +00:00
Sankalp Kotewar 97f21173cc upgraded typescript version
Upgrade ts version to support latest azure sdk
2023-03-06 12:18:32 +00:00
Sankalp Kotewar ce1bf116fc formatted and updated releases file 2023-03-06 11:56:51 +00:00
Sankalp Kotewar 9ba9ae31a9 updated azure storage blob to 12.13.0 2023-03-06 11:55:21 +00:00
Ferenc Hammerl 94ab8de5f3 Bypass proxy on loopback IPs (localhost, 127.*, ::1 etc) (#1361)
* Bypass proxy on loopback IPs

* Expect empty array instead of undefined

* Restore accidentally deleted test

* Fix formatting

* Fix linting

* Update proxy.ts

* Better ipv6 definitions

* Fix linting

* Update proxy.test.ts
2023-03-06 11:07:04 +01:00
Ferenc Hammerl d47e0bac60 Support '*' wildcard (#1355) 2023-03-06 11:02:29 +01:00
Ferenc Hammerl 1f4b3fac06 Revert "Bypass proxy on loopback IPs"
This reverts commit 8d92c9c903.
2023-03-01 13:48:44 +00:00
Ferenc Hammerl 8d92c9c903 Bypass proxy on loopback IPs 2023-03-01 13:45:12 +00:00
Marc Mueller e45a26f771 Update package version and changelog 2023-02-21 13:56:25 +01:00
Marc Mueller a3849b77ae Rename option to lookupOnly 2023-02-21 12:37:48 +01:00
Marc Mueller eb06c21794 Add cache restore dryRun option 2023-02-21 12:37:48 +01:00
Lovepreet Singh 0db3029fcf Merge pull request #1353 from actions/pdotl/zstd-version-fix
Hotfix Zstd breaking due to version change in runners
2023-02-21 00:50:51 +05:30
Lovepreet Singh e6e29846f2 Add debug statement for exact zstd version value and remove dependence on version for now 2023-02-20 19:13:38 +00:00
Lovepreet Singh 7c15bf6f40 Fix failing windows test 2023-02-20 18:50:26 +00:00
Lovepreet Singh bc713ab90d Add release info 2023-02-20 18:38:47 +00:00
Lovepreet Singh a9d266bb7c Fix lint issues 2023-02-20 15:26:04 +00:00
Lovepreet Singh cf3dd065b8 Add default value and rename args 2023-02-20 14:59:12 +00:00
Lovepreet Singh 6ec51745ad Update debug statement to include latest command 2023-02-20 14:23:53 +00:00
Lovepreet Singh 0f91c9c203 Bump version using npm 2023-02-20 13:53:17 +00:00
Lovepreet Singh e18b2d8a33 0.0.1 2023-02-20 13:43:31 +00:00
Lovepreet Singh 4fd425926c Fix version number 2023-02-20 13:43:24 +00:00
Lovepreet Singh 83dffb7746 Fix lint issues 2023-02-20 13:33:16 +00:00
Lovepreet Singh 1d1d5456e3 Removed code that checks for version less than 1.3.2 as it was not working. Defaulting to zstd without long as that is what is always happening currently. 2023-02-20 13:27:45 +00:00
Lovepreet Singh 9e06993ffc Hotfix zstd version change only 2023-02-20 13:08:22 +00:00
Lovepreet Singh 3630ea6eed Fix bug with version shortcircuiting because of version being null 2023-02-20 12:51:49 +00:00
Lovepreet Singh c2d3089f83 bump version 2023-02-20 10:32:34 +00:00
Lovepreet Singh 652109d32c Test passing quiet as argument 2023-02-20 10:30:41 +00:00
Lovepreet Singh f2aa430c9d Add debug statements 2023-02-20 10:05:34 +00:00
Felix Luthman d2b7d85e7c Standardize behaviour of no_proxy environmental variable (#1223)
* match no_proxy to subdomains

* strip leading dot + '*' match all + testcases

* Update proxy.test.ts

* Revert "Update proxy.test.ts"

This reverts commit 0e925a6dc5.

* remove support for leading dots and wildcard no_proxy

* change order of tests for logic consistency

* add test for working leading dot

* add check for partial domain, as opposed to subdomain
2023-02-13 15:00:05 +01:00
Ferenc Hammerl 409d616a6e Merge pull request #1333 from actions/dependabot/npm_and_yarn/http-cache-semantics-4.1.1
Bump http-cache-semantics from 4.1.0 to 4.1.1
2023-02-09 13:40:44 +01:00
Sampark Sharma e3c2a88bbf Release patch version update for cache (#1338) 2023-02-09 17:21:19 +05:30
Christoph Reiter ea21da6993 Don't set the MSYS env var globally (#1329)
b2d865f180 introduced a call to exportVariable() to export the MSYS env
var, which configures the symlink strategy for MSYS2/cygwin binaries it calls.

By setting the env var globally, this also changes the behaviour of other MSYS2
using tools in a CI job, and also overrides MSYS configuration set by the user,
which I think was not intended.

To avoid this leakage set the MSYS env var only for the commands which
@actions/cache calls.

Fixes #1312
2023-02-08 10:58:25 +05:30
dependabot[bot] c6005c2a3c Bump http-cache-semantics from 4.1.0 to 4.1.1
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-03 04:52:15 +00:00
John Sudol 1589a5c066 Update @actions/glob to 0.4.0 (#1321) 2023-01-25 09:23:29 -05:00
John Sudol d3801d332c Pass in the directory for hashFiles (#1318) 2023-01-24 14:12:47 -05:00
Josh Soref 5804607845 Grammar: set up (#1241) 2023-01-19 10:57:29 -05:00
Ferenc Hammerl c26f803662 Merge pull request #1300 from actions/fhammerl/setup-node-latest
Use newest version of actions
2023-01-19 16:16:02 +01:00
Héctor Molinero Fernández 6c1f9eaae8 [Artifacts] Add more extensions to the gzip compression exception list (#1118)
* [Artifacts] Add more extensions to the gzip compression exception list

* [Artifacts] Test .zip extension

* Exempt .zstd files from compression
2023-01-11 15:19:28 -05:00
Konrad Pabjan 412417d0b0 Document notice command
Ported over from https://github.com/actions/toolkit/pull/1105 which was merged into master instead of main
2023-01-11 14:18:20 -05:00
Rob Cowsill 71a6fceb8c core: Update "core.error" documentation (#905)
Change the `core.error` documentation to say that it won't automatically
fail the action. This matches the existing example in the "logging" section
2023-01-11 14:12:52 -05:00
Konrad Pabjan 34577b269e Remove error annotations why retrying artifact download (#1309) 2023-01-11 13:53:41 -05:00
Eric Cornelissen 06c3c38ef2 Fix reject call in package artifact's upload-zip.ts (#1125) 2023-01-06 10:15:36 -05:00
Ramiro Antonio 03d6c2479c Fix typo in AnnotationProperties doc (#1114) 2023-01-06 10:10:33 -05:00
Randolf J 411e8fa448 fix: use stat instead of lstat (#1190) 2023-01-06 10:07:56 -05:00
Luca Casonato 2c09aaef3b [artifact] exempt .tar.zst files from compression (#1184)
* [artifact] exempt .tar.zst files from compression

These files are already compressed with zstd - no need to attempt re-compression.

* fix missing comma

* fmt

* Update upload-gzip.ts
2023-01-05 16:00:03 -05:00
Sampark Sharma b2d865f180 Cache package release for compression change in windows with symlink fix (#1291)
* Cache package release for compression change in windows

This reverts commit 86fe4abd8e.

* Add env variable to enable windows symlinks

* Add cross os opt-in functionality for cache on windows

* Fix test

* Address review comments

* Fix test

* Fix tests

* Fix tests

* Fix tests

* Address review comments

* Address review comments

* Fix tests

* Fix tests

* Add npm version

* Add release details
2023-01-04 12:16:25 +05:30
Ferenc Hammerl 56146a6713 Bump actions to newer versions 2023-01-03 16:59:01 +01:00
Ferenc Hammerl 74f24b41d1 Use most recent setup-node 2023-01-03 16:43:09 +01:00
Ferenc Hammerl c0b323a0bb Merge pull request #1298 from actions/fhammerl/artifact-release-1-1-1
Artifact release 1.1.1
2023-01-03 15:52:36 +01:00
Ferenc Hammerl 83db1b8e43 Bump artifact package 2023-01-03 15:19:24 +01:00
Ferenc Hammerl 5b2351aebf Release notes for 1.1.1 2023-01-03 15:19:16 +01:00
Ferenc Hammerl f5024e4e97 Merge pull request #1278 from actions/fhammerl/node-v16-and-toolkit-fixes
Migrate dev environment and workflows to node16
2023-01-03 14:02:07 +01:00
Ferenc Hammerl 4ea08312c6 Fix json5 vuln 2023-01-03 13:37:01 +01:00
Ferenc Hammerl 5e9bcaca7c Update title with hint 2023-01-03 13:36:38 +01:00
Ferenc Hammerl af2d2ff198 Remove allow-list from audit
Releases can be made or PRs can be merged even if the workflow is failing
2023-01-03 13:34:55 +01:00
Ferenc Hammerl 3d46598e70 Add disabling explanation in audit-allow-list 2023-01-03 13:33:43 +01:00
Ferenc Hammerl 894a0490f9 Merge branch 'main' of https://github.com/actions/toolkit into fhammerl/node-v16-and-toolkit-fixes 2023-01-03 11:58:29 +01:00
Sampark Sharma 86fe4abd8e Revert "Cache package release for compression change in windows" (#1289)
* Revert "Cache package release for compression change in windows (#1281)"

This reverts commit b228732644.

* Update release version to patch
2022-12-27 16:00:28 +05:30
Sampark Sharma b228732644 Cache package release for compression change in windows (#1281)
* bsd + zstd fallback implementation

* bsd + zstd fallback implementation

* Fix tar operations

* Add -v option for testing

* Fix order of args for tar

* Add GNUtar as default on windows

* Fix test

* Fix tar tests

* Fix lint issues

* Fix windows gnutar test case

* Temporarily remove thhe condition that prevents zstd usage on windows unless with GNUtar

* Address some comments and correct compression commands

* Add windows bsdtar test

* Fix windows test

* Fix test

* Separate args

* Fix old tests

* Add new tests

* Fix tests

* Fix lint test

* Refactor code

* Address review comments

* Fix test

* Fix tar test

* Add await to async function calls

* Fix test

* Update for beta release

* Fix audit issues

* Add fallback to gzip compression if cache not found

* Fix test

* Add test

* Address review comments

* Revert Address review comments

* Release 3.1.0-beta.2 cache package

* Fix issues

* Reconfigure catch block

* Add debug logging for gzip fall back

* Fix test

* Add end to end test for cache using bsd on windows
and address review comments

* Fix test

* Fix test

* Fix tests

* Add better comments

* Update packages/cache/src/internal/cacheHttpClient.ts

Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>

* Address review comments

* Update for new beta cache package release

* Address bugbash issues

* Fix tests

* Release new actions/cache minor version

Co-authored-by: Lovepreet Singh <pdotl@github.com>
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-22 20:47:35 +05:30
Sampark Sharma 2a4f3544ad Merge pull request #1234 from actions/phantsure/version-logging
Add logs for cache version on miss
2022-12-22 11:48:58 +05:30
Sampark Sharma c23fe4b81f FIx test 2022-12-21 10:30:22 +00:00
Sampark Sharma 034d154f88 Merge branch 'phantsure/version-logging' of https://github.com/actions/toolkit into phantsure/version-logging 2022-12-21 10:27:13 +00:00
Sampark Sharma ccfa36f304 Address review comments 2022-12-21 10:24:52 +00:00
Ferenc Hammerl 2afea665ed Try sequential jest tests 2022-12-20 16:32:59 +01:00
Sampark Sharma e96dc8a69a Update packages/cache/src/internal/cacheHttpClient.ts
Co-authored-by: Bishal Prasad <bishal-pdmsft@github.com>
2022-12-16 18:17:37 +05:30
Sampark Sharma b8c50aa82d Fix response code 2022-12-16 05:55:53 +00:00
Sampark Sharma 24685611e2 Add current scope from github ref 2022-12-16 05:54:48 +00:00
Ferenc Hammerl 80d992795c Fix linting 2022-12-14 16:13:28 +01:00
Ferenc Hammerl b9de68a590 Await finish of filestream so file is created for node16 2022-12-14 15:57:48 +01:00
Ferenc Hammerl 1d61e5fb19 Fix linting 2022-12-14 01:38:01 +01:00
Ferenc Hammerl 4abb5a2ae0 Quote workflows for windows 2022-12-14 01:30:49 +01:00
Ferenc Hammerl 6b18932b86 Fix missing typescript casts 2022-12-14 01:28:46 +01:00
Ferenc Hammerl 56c460630a Fix audit 2022-12-14 01:27:55 +01:00
Ferenc Hammerl e1a991ffb7 Run workflows on 16 2022-12-14 01:19:05 +01:00
Ferenc Hammerl cc9ec0424e Test out checking for fileexists in rmFile 2022-12-14 01:17:17 +01:00
Ferenc Hammerl c91bdbadbf Update ts types to node16 2022-12-14 01:13:46 +01:00
Ferenc Hammerl 23811ac52f Update nock to work with node 16 2022-12-13 18:21:57 +01:00
Sampark Sharma e559a15ca6 Fix test 2022-12-13 11:36:10 +00:00
Sampark Sharma 816c1b3760 Fix tests 2022-12-13 11:25:40 +00:00
Sampark Sharma b9d1dd898e Address review comments 2022-11-15 11:04:24 +00:00
Sampark Sharma aaac0e6c98 Address review comments 2022-11-15 10:32:24 +00:00
Sampark Sharma a735d9bcd4 Add logs for cache version on miss 2022-11-14 06:31:26 +00:00
62 changed files with 4212 additions and 2479 deletions
+9 -9
View File
@@ -22,12 +22,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set Node.js 12.x
uses: actions/setup-node@v1
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 16.x
# In order to upload & download artifacts 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
@@ -55,16 +55,16 @@ jobs:
- name: Create files that will be uploaded
run: |
mkdir artifact-path
echo ${{ env.non-gzip-artifact-content }} > artifact-path/world.txt
echo ${{ env.gzip-artifact-content }} > artifact-path/gzip.txt
echo '${{ env.non-gzip-artifact-content }}' > artifact-path/world.txt
echo '${{ env.gzip-artifact-content }}' > artifact-path/gzip.txt
touch artifact-path/empty.txt
# We're using node -e to call the functions directly available in the @actions/artifact package
- name: Upload artifacts using uploadArtifact()
run: |
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-1',['artifact-path/world.txt'], '${{ github.workspace }}'))"
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-2',['artifact-path/gzip.txt'], '${{ github.workspace }}'))"
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-3',['artifact-path/empty.txt'], '${{ github.workspace }}'))"
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-1',['artifact-path/world.txt'], process.argv[1]))" "${{ github.workspace }}"
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-2',['artifact-path/gzip.txt'], process.argv[1]))" "${{ github.workspace }}"
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-3',['artifact-path/empty.txt'], process.argv[1]))" "${{ github.workspace }}"
- name: Download artifacts using downloadArtifact()
run: |
+6 -7
View File
@@ -18,12 +18,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set Node.js 12.x
uses: actions/setup-node@v1
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 16.x
- name: npm install
run: npm install
@@ -31,9 +31,8 @@ jobs:
- name: Bootstrap
run: npm run bootstrap
- name: audit tools
# `|| npm audit` to pretty-print the output if vulnerabilies are found after filtering.
run: npm audit --audit-level=moderate --json | scripts/audit-allow-list || npm audit --audit-level=moderate
- name: audit tools (without allow-list)
run: npm audit --audit-level=moderate
- name: audit packages
run: npm run audit-all
+4 -4
View File
@@ -22,12 +22,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set Node.js 12.x
uses: actions/setup-node@v1
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 16.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
+90
View File
@@ -0,0 +1,90 @@
name: cache-windows-bsd-unit-tests
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- shell: bash
run: |
rm "C:\Program Files\Git\usr\bin\tar.exe"
- name: Set Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: 12.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
- name: Set env variables
uses: ./packages/cache/__tests__/__fixtures__/
# 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 cache package
- name: Install root npm packages
run: npm ci
- name: Compile cache package
run: |
npm ci
npm run tsc
working-directory: packages/cache
- name: Generate files in working directory
shell: bash
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} test-cache
- name: Generate files outside working directory
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 }}'))"
- name: Delete cache folders before restoring
shell: bash
run: |
rm -rf test-cache
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}))"
- name: Verify cache restored with http-client
shell: bash
run: |
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} test-cache
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} ~/test-cache
- name: Delete cache folders before restoring
shell: bash
run: |
rm -rf test-cache
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 }}'))"
- name: Verify cache restored with Azure SDK
shell: bash
run: |
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} test-cache
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} ~/test-cache
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
+6 -6
View File
@@ -13,15 +13,15 @@ jobs:
steps:
- name: setup repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: verify package exists
run: ls packages/${{ github.event.inputs.package }}
- name: Set Node.js 12.x
uses: actions/setup-node@v1
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 16.x
- name: npm install
run: npm install
@@ -40,7 +40,7 @@ jobs:
working-directory: packages/${{ github.event.inputs.package }}
- name: upload artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ${{ github.event.inputs.package }}
path: packages/${{ github.event.inputs.package }}/*.tgz
@@ -52,7 +52,7 @@ jobs:
steps:
- name: download artifact
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: ${{ github.event.inputs.package }}
+5 -5
View File
@@ -23,12 +23,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set Node.js 12.x
uses: actions/setup-node@v1
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 16.x
- name: npm install
run: npm install
@@ -40,7 +40,7 @@ jobs:
run: npm run build
- name: npm test
run: npm test
run: npm test -- --runInBand
env:
GITHUB_TOKEN: ${{ github.token }}
+2 -2
View File
@@ -9,7 +9,7 @@ jobs:
if: ${{ github.repository_owner == 'actions' }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Update Octokit
working-directory: packages/github
run: |
@@ -30,7 +30,7 @@ jobs:
fi
- name: Create PR
if: ${{steps.status.outputs.createPR}}
uses: actions/github-script@v2
uses: actions/github-script@v6
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
os: [ubuntu-16.04, windows-2019]
runs-on: ${{matrix.os}}
actions:
- uses: actions/setup-node@v1
- uses: actions/setup-node@v3
with:
version: ${{matrix.node}}
- run: |
+3
View File
@@ -100,9 +100,12 @@ There are several commands to emit different levels of log output:
| log level | example usage |
|---|---|
| [debug](action-debugging.md) | `echo "::debug::My debug message"` |
| notice | `echo "::notice::My notice message"` |
| warning | `echo "::warning::My warning message"` |
| error | `echo "::error::My error message"` |
Additional syntax options are described at [the workflow command documentation](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message).
### Command Echoing
By default, the echoing of commands to stdout only occurs if [Step Debugging is enabled](./action-debugging.md#How-to-Access-Step-Debug-Logs)
+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@v1
using: actions/setup-node@v3
```
# Define Metadata
+2810 -1648
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -15,7 +15,7 @@
},
"devDependencies": {
"@types/jest": "^27.0.2",
"@types/node": "^12.20.13",
"@types/node": "^16.18.1",
"@types/signale": "^1.4.1",
"@typescript-eslint/parser": "^4.0.0",
"concurrently": "^6.1.0",
+5 -1
View File
@@ -89,4 +89,8 @@
### 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)
- Add `x-actions-results-crc64` and `x-actions-results-md5` checksum headers on upload [#1063](https://github.com/actions/toolkit/pull/1063)
### 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)
+94 -19
View File
@@ -6,13 +6,28 @@ import {promises as fs} from 'fs'
import {createGZipFileOnDisk} from '../src/internal/upload-gzip'
const root = path.join(__dirname, '_temp', 'upload-gzip')
const tempGzipFilePath = path.join(root, 'file1.gzip')
const tempZipFilePath = path.join(root, 'file2.zip')
const tempTarlzFilePath = path.join(root, 'file3.tar.lz')
const tempGzFilePath = path.join(root, 'file4.tar.gz')
const tempBz2FilePath = path.join(root, 'file5.tar.bz2')
const temp7zFilePath = path.join(root, 'file6.7z')
const tempNormalFilePath = path.join(root, 'file6.txt')
const tempGzFilePath = path.join(root, 'file.gz')
const tempGzipFilePath = path.join(root, 'file.gzip')
const tempTgzFilePath = path.join(root, 'file.tgz')
const tempTazFilePath = path.join(root, 'file.taz')
const tempZFilePath = path.join(root, 'file.Z')
const tempTaZFilePath = path.join(root, 'file.taZ')
const tempBz2FilePath = path.join(root, 'file.bz2')
const tempTbzFilePath = path.join(root, 'file.tbz')
const tempTbz2FilePath = path.join(root, 'file.tbz2')
const tempTz2FilePath = path.join(root, 'file.tz2')
const tempLzFilePath = path.join(root, 'file.lz')
const tempLzmaFilePath = path.join(root, 'file.lzma')
const tempTlzFilePath = path.join(root, 'file.tlz')
const tempLzoFilePath = path.join(root, 'file.lzo')
const tempXzFilePath = path.join(root, 'file.xz')
const tempTxzFilePath = path.join(root, 'file.txz')
const tempZstFilePath = path.join(root, 'file.zst')
const tempZstdFilePath = path.join(root, 'file.zstd')
const tempTzstFilePath = path.join(root, 'file.tzst')
const tempZipFilePath = path.join(root, 'file.zip')
const temp7zFilePath = path.join(root, 'file.7z')
const tempNormalFilePath = path.join(root, 'file.txt')
jest.mock('../src/internal/config-variables')
@@ -27,11 +42,26 @@ beforeAll(async () => {
// clear temp directory and create files that will be "uploaded"
await io.rmRF(root)
await fs.mkdir(path.join(root))
await fs.writeFile(tempGzFilePath, 'a file with a .gz file extension')
await fs.writeFile(tempGzipFilePath, 'a file with a .gzip file extension')
await fs.writeFile(tempZipFilePath, 'a file with a .zip file extension')
await fs.writeFile(tempTarlzFilePath, 'a file with a tar.lz file extension')
await fs.writeFile(tempGzFilePath, 'a file with a gz file file extension')
await fs.writeFile(tempTgzFilePath, 'a file with a .tgz file extension')
await fs.writeFile(tempTazFilePath, 'a file with a .taz file extension')
await fs.writeFile(tempZFilePath, 'a file with a .Z file extension')
await fs.writeFile(tempTaZFilePath, 'a file with a .taZ file extension')
await fs.writeFile(tempBz2FilePath, 'a file with a .bz2 file extension')
await fs.writeFile(tempTbzFilePath, 'a file with a .tbz file extension')
await fs.writeFile(tempTbz2FilePath, 'a file with a .tbz2 file extension')
await fs.writeFile(tempTz2FilePath, 'a file with a .tz2 file extension')
await fs.writeFile(tempLzFilePath, 'a file with a .lz file extension')
await fs.writeFile(tempLzmaFilePath, 'a file with a .lzma file extension')
await fs.writeFile(tempTlzFilePath, 'a file with a .tlz file extension')
await fs.writeFile(tempLzoFilePath, 'a file with a .lzo file extension')
await fs.writeFile(tempXzFilePath, 'a file with a .xz file extension')
await fs.writeFile(tempTxzFilePath, 'a file with a .txz file extension')
await fs.writeFile(tempZstFilePath, 'a file with a .zst file extension')
await fs.writeFile(tempZstdFilePath, 'a file with a .zstd file extension')
await fs.writeFile(tempTzstFilePath, 'a file with a .tzst file extension')
await fs.writeFile(tempZipFilePath, 'a file with a .zip file extension')
await fs.writeFile(temp7zFilePath, 'a file with a .7z file extension')
await fs.writeFile(tempNormalFilePath, 'a file with a .txt file extension')
})
@@ -40,21 +70,66 @@ test('Number.MAX_SAFE_INTEGER is returned when an existing compressed file is us
// create temporary file
const tempFile = await tmp.file()
expect(await createGZipFileOnDisk(tempGzipFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempZipFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTarlzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempGzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempGzipFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTgzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTazFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempZFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTaZFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempBz2FilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTbzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTbz2FilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTz2FilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempLzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempLzmaFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTlzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempLzoFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempXzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTxzFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempZstFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempZstdFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempTzstFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(tempZipFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
expect(await createGZipFileOnDisk(temp7zFilePath, tempFile.path)).toEqual(
Number.MAX_SAFE_INTEGER
)
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@actions/artifact",
"version": "1.1.0",
"version": "1.1.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@actions/artifact",
"version": "1.1.0",
"version": "1.1.1",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.9.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/artifact",
"version": "1.1.0",
"version": "1.1.1",
"preview": true,
"description": "Actions artifact lib",
"keywords": [
@@ -203,7 +203,7 @@ Note: The size of downloaded zips can differ significantly from the reported siz
await createDirectoriesForArtifact(
downloadSpecification.directoryStructure
)
core.info('Directory structure has been setup for the artifact')
core.info('Directory structure has been set up for the artifact')
await createEmptyFilesForArtifact(
downloadSpecification.emptyFilesToCreate
)
@@ -219,6 +219,13 @@ export class DownloadHttpClient {
fileDownloadPath: string
): Promise<void> => {
destinationStream.close()
// await until file is created at downloadpath; node15 and up fs.createWriteStream had not created a file yet
await new Promise<void>(resolve => {
destinationStream.on('close', resolve)
if (destinationStream.writableFinished) {
resolve()
}
})
await rmFile(fileDownloadPath)
destinationStream = fs.createWriteStream(fileDownloadPath)
}
@@ -304,7 +311,7 @@ export class DownloadHttpClient {
const gunzip = zlib.createGunzip()
response.message
.on('error', error => {
core.error(
core.info(
`An error occurred while attempting to read the response stream`
)
gunzip.close()
@@ -313,7 +320,7 @@ export class DownloadHttpClient {
})
.pipe(gunzip)
.on('error', error => {
core.error(
core.info(
`An error occurred while attempting to decompress the response stream`
)
destinationStream.close()
@@ -324,7 +331,7 @@ export class DownloadHttpClient {
resolve()
})
.on('error', error => {
core.error(
core.info(
`An error occurred while writing a downloaded file to ${destinationStream.path}`
)
reject(error)
@@ -332,7 +339,7 @@ export class DownloadHttpClient {
} else {
response.message
.on('error', error => {
core.error(
core.info(
`An error occurred while attempting to read the response stream`
)
destinationStream.close()
@@ -343,7 +350,7 @@ export class DownloadHttpClient {
resolve()
})
.on('error', error => {
core.error(
core.info(
`An error occurred while writing a downloaded file to ${destinationStream.path}`
)
reject(error)
+22 -7
View File
@@ -9,12 +9,27 @@ const stat = promisify(fs.stat)
* If any of these types of files are encountered then on-disk gzip creation will be skipped and the original file will be uploaded as-is
*/
const gzipExemptFileExtensions = [
'.gzip',
'.zip',
'.tar.lz',
'.tar.gz',
'.tar.bz2',
'.7z'
'.gz', // GZIP
'.gzip', // GZIP
'.tgz', // GZIP
'.taz', // GZIP
'.Z', // COMPRESS
'.taZ', // COMPRESS
'.bz2', // BZIP2
'.tbz', // BZIP2
'.tbz2', // BZIP2
'.tz2', // BZIP2
'.lz', // LZIP
'.lzma', // LZMA
'.tlz', // LZMA
'.lzo', // LZOP
'.xz', // XZ
'.txz', // XZ
'.zst', // ZSTD
'.zstd', // ZSTD
'.tzst', // ZSTD
'.zip', // ZIP
'.7z' // 7ZIP
]
/**
@@ -47,7 +62,7 @@ export async function createGZipFileOnDisk(
outputStream.on('error', error => {
// eslint-disable-next-line no-console
console.log(error)
reject
reject(error)
})
})
}
@@ -25,7 +25,7 @@ export function getUploadSpecification(
if (!fs.existsSync(rootDirectory)) {
throw new Error(`Provided rootDirectory ${rootDirectory} does not exist`)
}
if (!fs.lstatSync(rootDirectory).isDirectory()) {
if (!fs.statSync(rootDirectory).isDirectory()) {
throw new Error(
`Provided rootDirectory ${rootDirectory} is not a valid directory`
)
@@ -57,7 +57,7 @@ export function getUploadSpecification(
if (!fs.existsSync(file)) {
throw new Error(`File ${file} does not exist`)
}
if (!fs.lstatSync(file).isDirectory()) {
if (!fs.statSync(file).isDirectory()) {
// Normalize and resolve, this allows for either absolute or relative paths to be used
file = normalize(file)
file = resolve(file)
+4 -2
View File
@@ -44,6 +44,8 @@ const cacheKey = await cache.restoreCache(paths, key, restoreKeys)
##### Cache segment restore timeout
A cache gets downloaded in multiple segments of fixed sizes (`1GB` for a `32-bit` runner and `2GB` for a `64-bit` runner). Sometimes, a segment download gets stuck which causes the workflow job to be stuck forever and fail. Version `v3.0.4` of cache package introduces a segment download timeout. The segment download timeout will allow the segment download to get aborted and hence allow the job to proceed with a cache miss.
A cache gets downloaded in multiple segments of fixed sizes (now `128MB` to fail-fast, previously `1GB` for a `32-bit` runner and `2GB` for a `64-bit` runner were used). Sometimes, a segment download gets stuck which causes the workflow job to be stuck forever and fail. Version `v3.0.4` of cache package introduces a segment download timeout. The segment download timeout will allow the segment download to get aborted and hence allow the job to proceed with a cache miss.
Default value of this timeout is 10 minutes (starting `v3.2.1` and higher, previously 60 minutes in versions between `v.3.0.4` and `v3.2.0`, both included) and can be customized by specifying an [environment variable](https://docs.github.com/en/actions/learn-github-actions/environment-variables) named `SEGMENT_DOWNLOAD_TIMEOUT_MINS` with timeout value in minutes.
Default value of this timeout is 60 minutes and can be customized by specifying an [environment variable](https://docs.github.com/en/actions/learn-github-actions/environment-variables) named `SEGMENT_DOWNLOAD_TIMEOUT_MINS` with timeout value in minutes.
+71 -2
View File
@@ -5,89 +5,158 @@
- Initial release
### 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.2.1
- Fix to await async function getCompressionMethod
### 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`
### 1.0.1
- Fix bug in downloading large files (> 2 GBs) with the Azure SDK
### 1.0.2
- Use posix archive format to add support for some tools
### 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.4
- Use @actions/core v1.2.6
- Fixes uploadChunk to throw an error if any unsuccessful response code is received
### 1.0.5
- Fix to ensure Windows cache paths get resolved correctly
### 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.7
- Fixes permissions issue extracting archives with GNU tar on macOS ([issue](https://github.com/actions/cache/issues/527))
### 1.0.8
- Increase the allowed artifact cache size from 5GB to 10GB ([issue](https://github.com/actions/cache/discussions/497))
### 1.0.9
- Use @azure/ms-rest-js v2.6.0
- Use @azure/storage-blob v12.8.0
- Use @azure/ms-rest-js v2.6.0
- Use @azure/storage-blob v12.8.0
### 1.0.10
- Update `lockfileVersion` to `v2` in `package-lock.json [#1022](https://github.com/actions/toolkit/pull/1022)
### 1.0.11
- Fix file downloads > 2GB([issue](https://github.com/actions/cache/issues/773))
### 2.0.0
- Added support to check if Actions cache service feature is available or not [#1028](https://github.com/actions/toolkit/pull/1028)
### 2.0.3
- Update to v2.0.0 of `@actions/http-client`
### 2.0.4
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
### 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.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))
### 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)
### 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.2
- Added 1 hour timeout for the download stuck issue [#810](https://github.com/actions/cache/issues/810).
### 3.0.3
- Bug fixes for download stuck issue [#810](https://github.com/actions/cache/issues/810).
### 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.5
- Update `@actions/cache` to use `@actions/core@^1.10.0`
### 3.0.6
- Added `@azure/abort-controller` to dependencies to fix compatibility issue with ESM [#1208](https://github.com/actions/toolkit/issues/1208)
### 3.1.0-beta.1
- Update actions/cache on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. ([issue](https://github.com/actions/cache/issues/984))
### 3.1.0-beta.2
- Added support for fallback to gzip to restore old caches on windows.
### 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
- 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.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.2
- Fix issue with symlink restoration on windows.
### 3.1.3
- Fix to prevent from setting MYSYS environement variable globally [#1329](https://github.com/actions/toolkit/pull/1329).
### 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.2.0
- Add `lookupOnly` to cache restore `DownloadOptions`.
### 3.2.1
- Updated @azure/storage-blob to `v12.13.0`
+17 -6
View File
@@ -7,7 +7,7 @@ jest.mock('../src/internal/downloadUtils')
test('getCacheVersion with one path returns version', async () => {
const paths = ['node_modules']
const result = getCacheVersion(paths)
const result = getCacheVersion(paths, undefined, true)
expect(result).toEqual(
'b3e0c6cb5ecf32614eeb2997d905b9c297046d7cbf69062698f25b14b4cb0985'
)
@@ -15,7 +15,7 @@ test('getCacheVersion with one path returns version', async () => {
test('getCacheVersion with multiple paths returns version', async () => {
const paths = ['node_modules', 'dist']
const result = getCacheVersion(paths)
const result = getCacheVersion(paths, undefined, true)
expect(result).toEqual(
'165c3053bc646bf0d4fac17b1f5731caca6fe38e0e464715c0c3c6b6318bf436'
)
@@ -23,22 +23,33 @@ test('getCacheVersion with multiple paths returns version', async () => {
test('getCacheVersion with zstd compression returns version', async () => {
const paths = ['node_modules']
const result = getCacheVersion(paths, CompressionMethod.Zstd)
const result = getCacheVersion(paths, CompressionMethod.Zstd, true)
expect(result).toEqual(
'273877e14fd65d270b87a198edbfa2db5a43de567c9a548d2a2505b408befe24'
)
})
test('getCacheVersion with gzip compression does not change vesion', async () => {
test('getCacheVersion with gzip compression returns version', async () => {
const paths = ['node_modules']
const result = getCacheVersion(paths, CompressionMethod.Gzip)
const result = getCacheVersion(paths, CompressionMethod.Gzip, true)
expect(result).toEqual(
'b3e0c6cb5ecf32614eeb2997d905b9c297046d7cbf69062698f25b14b4cb0985'
'470e252814dbffc9524891b17cf4e5749b26c1b5026e63dd3f00972db2393117'
)
})
test('getCacheVersion with enableCrossOsArchive as false returns version on windows', async () => {
if (process.platform === 'win32') {
const paths = ['node_modules']
const result = getCacheVersion(paths)
expect(result).toEqual(
'2db19d6596dc34f51f0043120148827a264863f5c6ac857569c2af7119bad14e'
)
}
})
test('downloadCache uses http-client for non-Azure URLs', async () => {
const downloadCacheHttpClientMock = jest.spyOn(
downloadUtils,
+9 -4
View File
@@ -8,7 +8,8 @@ import {
const useAzureSdk = true
const downloadConcurrency = 8
const timeoutInMs = 30000
const segmentTimeoutInMs = 3600000
const segmentTimeoutInMs = 600000
const lookupOnly = false
const uploadConcurrency = 4
const uploadChunkSize = 32 * 1024 * 1024
@@ -19,7 +20,8 @@ test('getDownloadOptions sets defaults', async () => {
useAzureSdk,
downloadConcurrency,
timeoutInMs,
segmentTimeoutInMs
segmentTimeoutInMs,
lookupOnly
})
})
@@ -28,7 +30,8 @@ test('getDownloadOptions overrides all settings', async () => {
useAzureSdk: false,
downloadConcurrency: 14,
timeoutInMs: 20000,
segmentTimeoutInMs: 3600000
segmentTimeoutInMs: 3600000,
lookupOnly: true
}
const actualOptions = getDownloadOptions(expectedOptions)
@@ -61,7 +64,8 @@ test('getDownloadOptions overrides download timeout minutes', async () => {
useAzureSdk: false,
downloadConcurrency: 14,
timeoutInMs: 20000,
segmentTimeoutInMs: 3600000
segmentTimeoutInMs: 3600000,
lookupOnly: true
}
process.env.SEGMENT_DOWNLOAD_TIMEOUT_MINS = '10'
const actualOptions = getDownloadOptions(expectedOptions)
@@ -72,4 +76,5 @@ test('getDownloadOptions overrides download timeout minutes', async () => {
)
expect(actualOptions.timeoutInMs).toEqual(expectedOptions.timeoutInMs)
expect(actualOptions.segmentTimeoutInMs).toEqual(600000)
expect(actualOptions.lookupOnly).toEqual(expectedOptions.lookupOnly)
})
+42 -3
View File
@@ -142,7 +142,8 @@ test('restore with gzip compressed cache found', async () => {
expect(cacheKey).toBe(key)
expect(getCacheMock).toHaveBeenCalledWith([key], paths, {
compressionMethod: compression
compressionMethod: compression,
enableCrossOsArchive: false
})
expect(createTempDirectoryMock).toHaveBeenCalledTimes(1)
expect(downloadCacheMock).toHaveBeenCalledWith(
@@ -201,7 +202,8 @@ test('restore with zstd compressed cache found', async () => {
expect(cacheKey).toBe(key)
expect(getCacheMock).toHaveBeenCalledWith([key], paths, {
compressionMethod: compression
compressionMethod: compression,
enableCrossOsArchive: false
})
expect(createTempDirectoryMock).toHaveBeenCalledTimes(1)
expect(downloadCacheMock).toHaveBeenCalledWith(
@@ -258,7 +260,8 @@ test('restore with cache found for restore key', async () => {
expect(cacheKey).toBe(restoreKey)
expect(getCacheMock).toHaveBeenCalledWith([key, restoreKey], paths, {
compressionMethod: compression
compressionMethod: compression,
enableCrossOsArchive: false
})
expect(createTempDirectoryMock).toHaveBeenCalledTimes(1)
expect(downloadCacheMock).toHaveBeenCalledWith(
@@ -273,3 +276,39 @@ test('restore with cache found for restore key', async () => {
expect(extractTarMock).toHaveBeenCalledWith(archivePath, compression)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
})
test('restore with dry run', async () => {
const paths = ['node_modules']
const key = 'node-test'
const options = {lookupOnly: true}
const cacheEntry: ArtifactCacheEntry = {
cacheKey: key,
scope: 'refs/heads/main',
archiveLocation: 'www.actionscache.test/download'
}
const getCacheMock = jest.spyOn(cacheHttpClient, 'getCacheEntry')
getCacheMock.mockImplementation(async () => {
return Promise.resolve(cacheEntry)
})
const createTempDirectoryMock = jest.spyOn(cacheUtils, 'createTempDirectory')
const downloadCacheMock = jest.spyOn(cacheHttpClient, 'downloadCache')
const compression = CompressionMethod.Gzip
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValue(Promise.resolve(compression))
const cacheKey = await restoreCache(paths, key, undefined, options)
expect(cacheKey).toBe(key)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
expect(getCacheMock).toHaveBeenCalledWith([key], paths, {
compressionMethod: compression,
enableCrossOsArchive: false
})
// creating a tempDir and downloading the cache are skipped
expect(createTempDirectoryMock).toHaveBeenCalledTimes(0)
expect(downloadCacheMock).toHaveBeenCalledTimes(0)
})
+9 -3
View File
@@ -209,7 +209,9 @@ test('save with reserve cache failure should fail', async () => {
expect(reserveCacheMock).toHaveBeenCalledTimes(1)
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, paths, {
compressionMethod: compression
cacheSize: undefined,
compressionMethod: compression,
enableCrossOsArchive: false
})
expect(createTarMock).toHaveBeenCalledTimes(1)
expect(saveCacheMock).toHaveBeenCalledTimes(0)
@@ -253,7 +255,9 @@ test('save with server error should fail', async () => {
expect(reserveCacheMock).toHaveBeenCalledTimes(1)
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], {
compressionMethod: compression
cacheSize: undefined,
compressionMethod: compression,
enableCrossOsArchive: false
})
const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
@@ -296,7 +300,9 @@ test('save with valid inputs uploads a cache', async () => {
expect(reserveCacheMock).toHaveBeenCalledTimes(1)
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], {
compressionMethod: compression
cacheSize: undefined,
compressionMethod: compression,
enableCrossOsArchive: false
})
const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
+268 -57
View File
@@ -1,7 +1,14 @@
import * as exec from '@actions/exec'
import * as io from '@actions/io'
import * as path from 'path'
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
import {
CacheFilename,
CompressionMethod,
GnuTarPathOnWindows,
ManifestFilename,
SystemTarPathOnWindows,
TarFilename
} from '../src/internal/constants'
import * as tar from '../src/internal/tar'
import * as utils from '../src/internal/cacheUtils'
// eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -13,7 +20,9 @@ jest.mock('@actions/io')
const IS_WINDOWS = process.platform === 'win32'
const IS_MAC = process.platform === 'darwin'
const defaultTarPath = process.platform === 'darwin' ? 'gtar' : 'tar'
const defaultTarPath = IS_MAC ? 'gtar' : 'tar'
const defaultEnv = {MSYS: 'winsymlinks:nativestrict'}
function getTempDir(): string {
return path.join(__dirname, '_temp', 'tar')
@@ -28,6 +37,10 @@ beforeAll(async () => {
await jest.requireActual('@actions/io').rmRF(getTempDir())
})
beforeEach(async () => {
jest.restoreAllMocks()
})
afterAll(async () => {
delete process.env['GITHUB_WORKSPACE']
await jest.requireActual('@actions/io').rmRF(getTempDir())
@@ -41,16 +54,15 @@ test('zstd extract tar', async () => {
? `${process.env['windir']}\\fakepath\\cache.tar`
: 'cache.tar'
const workspace = process.env['GITHUB_WORKSPACE']
const tarPath = IS_WINDOWS ? GnuTarPathOnWindows : defaultTarPath
await tar.extractTar(archivePath, CompressionMethod.Zstd)
expect(mkdirMock).toHaveBeenCalledWith(workspace)
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${defaultTarPath}"`,
[
'--use-compress-program',
IS_WINDOWS ? 'zstd -d --long=30' : 'unzstd --long=30',
`"${tarPath}"`,
'-xf',
IS_WINDOWS ? archivePath.replace(/\\/g, '/') : archivePath,
'-P',
@@ -58,11 +70,70 @@ test('zstd extract tar', async () => {
IS_WINDOWS ? workspace?.replace(/\\/g, '/') : workspace
]
.concat(IS_WINDOWS ? ['--force-local'] : [])
.concat(IS_MAC ? ['--delay-directory-restore'] : []),
{cwd: undefined}
.concat(IS_MAC ? ['--delay-directory-restore'] : [])
.concat([
'--use-compress-program',
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
])
.join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
})
test('zstd extract tar with windows BSDtar', async () => {
if (IS_WINDOWS) {
const mkdirMock = jest.spyOn(io, 'mkdirP')
const execMock = jest.spyOn(exec, 'exec')
jest
.spyOn(utils, 'getGnuTarPathOnWindows')
.mockReturnValue(Promise.resolve(''))
const archivePath = `${process.env['windir']}\\fakepath\\cache.tar`
const workspace = process.env['GITHUB_WORKSPACE']
const tarPath = SystemTarPathOnWindows
await tar.extractTar(archivePath, CompressionMethod.Zstd)
expect(mkdirMock).toHaveBeenCalledWith(workspace)
expect(execMock).toHaveBeenCalledTimes(2)
expect(execMock).toHaveBeenNthCalledWith(
1,
[
'zstd -d --long=30 --force -o',
TarFilename.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
].join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
expect(execMock).toHaveBeenNthCalledWith(
2,
[
`"${tarPath}"`,
'-xf',
TarFilename.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P',
'-C',
workspace?.replace(/\\/g, '/')
].join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
}
})
test('gzip extract tar', async () => {
const mkdirMock = jest.spyOn(io, 'mkdirP')
const execMock = jest.spyOn(exec, 'exec')
@@ -74,51 +145,58 @@ test('gzip extract tar', async () => {
await tar.extractTar(archivePath, CompressionMethod.Gzip)
expect(mkdirMock).toHaveBeenCalledWith(workspace)
const tarPath = IS_WINDOWS
? `${process.env['windir']}\\System32\\tar.exe`
: defaultTarPath
const tarPath = IS_WINDOWS ? GnuTarPathOnWindows : defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
[
'-z',
`"${tarPath}"`,
'-xf',
IS_WINDOWS ? archivePath.replace(/\\/g, '/') : archivePath,
'-P',
'-C',
IS_WINDOWS ? workspace?.replace(/\\/g, '/') : workspace
].concat(IS_MAC ? ['--delay-directory-restore'] : []),
{cwd: undefined}
]
.concat(IS_WINDOWS ? ['--force-local'] : [])
.concat(IS_MAC ? ['--delay-directory-restore'] : [])
.concat(['-z'])
.join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
})
test('gzip extract GNU tar on windows', async () => {
test('gzip extract GNU tar on windows with GNUtar in path', async () => {
if (IS_WINDOWS) {
jest.spyOn(fs, 'existsSync').mockReturnValueOnce(false)
const isGnuMock = jest
.spyOn(utils, 'isGnuTarInstalled')
.mockReturnValue(Promise.resolve(true))
// GNU tar present in path but not at default location
jest
.spyOn(utils, 'getGnuTarPathOnWindows')
.mockReturnValue(Promise.resolve('tar'))
const execMock = jest.spyOn(exec, 'exec')
const archivePath = `${process.env['windir']}\\fakepath\\cache.tar`
const workspace = process.env['GITHUB_WORKSPACE']
await tar.extractTar(archivePath, CompressionMethod.Gzip)
expect(isGnuMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"tar"`,
[
'-z',
`"tar"`,
'-xf',
archivePath.replace(/\\/g, '/'),
'-P',
'-C',
workspace?.replace(/\\/g, '/'),
'--force-local'
],
{cwd: undefined}
'--force-local',
'-z'
].join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
}
})
@@ -134,13 +212,13 @@ test('zstd create tar', async () => {
await tar.createTar(archiveFolder, sourceDirectories, CompressionMethod.Zstd)
const tarPath = IS_WINDOWS ? GnuTarPathOnWindows : defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${defaultTarPath}"`,
[
`"${tarPath}"`,
'--posix',
'--use-compress-program',
IS_WINDOWS ? 'zstd -T0 --long=30' : 'zstdmt --long=30',
'-cf',
IS_WINDOWS ? CacheFilename.Zstd.replace(/\\/g, '/') : CacheFilename.Zstd,
'--exclude',
@@ -149,16 +227,84 @@ test('zstd create tar', async () => {
'-C',
IS_WINDOWS ? workspace?.replace(/\\/g, '/') : workspace,
'--files-from',
'manifest.txt'
ManifestFilename
]
.concat(IS_WINDOWS ? ['--force-local'] : [])
.concat(IS_MAC ? ['--delay-directory-restore'] : []),
.concat(IS_MAC ? ['--delay-directory-restore'] : [])
.concat([
'--use-compress-program',
IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30'
])
.join(' '),
undefined, // args
{
cwd: archiveFolder
cwd: archiveFolder,
env: expect.objectContaining(defaultEnv)
}
)
})
test('zstd create tar with windows BSDtar', async () => {
if (IS_WINDOWS) {
const execMock = jest.spyOn(exec, 'exec')
jest
.spyOn(utils, 'getGnuTarPathOnWindows')
.mockReturnValue(Promise.resolve(''))
const archiveFolder = getTempDir()
const workspace = process.env['GITHUB_WORKSPACE']
const sourceDirectories = ['~/.npm/cache', `${workspace}/dist`]
await fs.promises.mkdir(archiveFolder, {recursive: true})
await tar.createTar(
archiveFolder,
sourceDirectories,
CompressionMethod.Zstd
)
const tarPath = SystemTarPathOnWindows
expect(execMock).toHaveBeenCalledTimes(2)
expect(execMock).toHaveBeenNthCalledWith(
1,
[
`"${tarPath}"`,
'--posix',
'-cf',
TarFilename.replace(/\\/g, '/'),
'--exclude',
TarFilename.replace(/\\/g, '/'),
'-P',
'-C',
workspace?.replace(/\\/g, '/'),
'--files-from',
ManifestFilename
].join(' '),
undefined, // args
{
cwd: archiveFolder,
env: expect.objectContaining(defaultEnv)
}
)
expect(execMock).toHaveBeenNthCalledWith(
2,
[
'zstd -T0 --long=30 --force -o',
CacheFilename.Zstd.replace(/\\/g, '/'),
TarFilename.replace(/\\/g, '/')
].join(' '),
undefined, // args
{
cwd: archiveFolder,
env: expect.objectContaining(defaultEnv)
}
)
}
})
test('gzip create tar', async () => {
const execMock = jest.spyOn(exec, 'exec')
@@ -170,16 +316,13 @@ test('gzip create tar', async () => {
await tar.createTar(archiveFolder, sourceDirectories, CompressionMethod.Gzip)
const tarPath = IS_WINDOWS
? `${process.env['windir']}\\System32\\tar.exe`
: defaultTarPath
const tarPath = IS_WINDOWS ? GnuTarPathOnWindows : defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
[
`"${tarPath}"`,
'--posix',
'-z',
'-cf',
IS_WINDOWS ? CacheFilename.Gzip.replace(/\\/g, '/') : CacheFilename.Gzip,
'--exclude',
@@ -188,10 +331,16 @@ test('gzip create tar', async () => {
'-C',
IS_WINDOWS ? workspace?.replace(/\\/g, '/') : workspace,
'--files-from',
'manifest.txt'
].concat(IS_MAC ? ['--delay-directory-restore'] : []),
ManifestFilename
]
.concat(IS_WINDOWS ? ['--force-local'] : [])
.concat(IS_MAC ? ['--delay-directory-restore'] : [])
.concat(['-z'])
.join(' '),
undefined, // args
{
cwd: archiveFolder
cwd: archiveFolder,
env: expect.objectContaining(defaultEnv)
}
)
})
@@ -205,22 +354,74 @@ test('zstd list tar', async () => {
await tar.listTar(archivePath, CompressionMethod.Zstd)
const tarPath = IS_WINDOWS ? GnuTarPathOnWindows : defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${defaultTarPath}"`,
[
'--use-compress-program',
IS_WINDOWS ? 'zstd -d --long=30' : 'unzstd --long=30',
`"${tarPath}"`,
'-tf',
IS_WINDOWS ? archivePath.replace(/\\/g, '/') : archivePath,
'-P'
]
.concat(IS_WINDOWS ? ['--force-local'] : [])
.concat(IS_MAC ? ['--delay-directory-restore'] : []),
{cwd: undefined}
.concat(IS_MAC ? ['--delay-directory-restore'] : [])
.concat([
'--use-compress-program',
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
])
.join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
})
test('zstd list tar with windows BSDtar', async () => {
if (IS_WINDOWS) {
const execMock = jest.spyOn(exec, 'exec')
jest
.spyOn(utils, 'getGnuTarPathOnWindows')
.mockReturnValue(Promise.resolve(''))
const archivePath = `${process.env['windir']}\\fakepath\\cache.tar`
await tar.listTar(archivePath, CompressionMethod.Zstd)
const tarPath = SystemTarPathOnWindows
expect(execMock).toHaveBeenCalledTimes(2)
expect(execMock).toHaveBeenNthCalledWith(
1,
[
'zstd -d --long=30 --force -o',
TarFilename.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
].join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
expect(execMock).toHaveBeenNthCalledWith(
2,
[
`"${tarPath}"`,
'-tf',
TarFilename.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P'
].join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
}
})
test('zstdWithoutLong list tar', async () => {
const execMock = jest.spyOn(exec, 'exec')
@@ -230,19 +431,24 @@ test('zstdWithoutLong list tar', async () => {
await tar.listTar(archivePath, CompressionMethod.ZstdWithoutLong)
const tarPath = IS_WINDOWS ? GnuTarPathOnWindows : defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${defaultTarPath}"`,
[
'--use-compress-program',
IS_WINDOWS ? 'zstd -d' : 'unzstd',
`"${tarPath}"`,
'-tf',
IS_WINDOWS ? archivePath.replace(/\\/g, '/') : archivePath,
'-P'
]
.concat(IS_WINDOWS ? ['--force-local'] : [])
.concat(IS_MAC ? ['--delay-directory-restore'] : []),
{cwd: undefined}
.concat(IS_MAC ? ['--delay-directory-restore'] : [])
.concat(['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd'])
.join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
})
@@ -254,18 +460,23 @@ test('gzip list tar', async () => {
await tar.listTar(archivePath, CompressionMethod.Gzip)
const tarPath = IS_WINDOWS
? `${process.env['windir']}\\System32\\tar.exe`
: defaultTarPath
const tarPath = IS_WINDOWS ? GnuTarPathOnWindows : defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
[
'-z',
`"${tarPath}"`,
'-tf',
IS_WINDOWS ? archivePath.replace(/\\/g, '/') : archivePath,
'-P'
].concat(IS_MAC ? ['--delay-directory-restore'] : []),
{cwd: undefined}
]
.concat(IS_WINDOWS ? ['--force-local'] : [])
.concat(IS_MAC ? ['--delay-directory-restore'] : [])
.concat(['-z'])
.join(' '),
undefined,
{
cwd: undefined,
env: expect.objectContaining(defaultEnv)
}
)
})
+95 -100
View File
@@ -1,12 +1,12 @@
{
"name": "@actions/cache",
"version": "3.0.6",
"version": "3.2.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@actions/cache",
"version": "3.0.6",
"version": "3.2.1",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
@@ -16,14 +16,14 @@
"@actions/io": "^1.0.1",
"@azure/abort-controller": "^1.1.0",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0",
"@azure/storage-blob": "^12.13.0",
"semver": "^6.1.0",
"uuid": "^3.3.3"
},
"devDependencies": {
"@types/semver": "^6.0.0",
"@types/uuid": "^3.4.5",
"typescript": "^3.8.3"
"typescript": "^4.8.0"
}
},
"node_modules/@actions/core": {
@@ -69,9 +69,9 @@
}
},
"node_modules/@actions/io": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
},
"node_modules/@azure/abort-controller": {
"version": "1.1.0",
@@ -112,28 +112,27 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@azure/core-http": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.3.tgz",
"integrity": "sha512-xr8AeszxP418rI//W38NfJDDr0kbVAPZkURZnZ+Fle+lLWeURjDE5zNIuocA1wUPoKSP8iXc0ApW6nPtbLGswA==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.0.tgz",
"integrity": "sha512-BxI2SlGFPPz6J1XyZNIVUf0QZLBKFX+ViFjKOkzqD18J1zOINIQ8JSBKKr+i+v8+MB6LacL6Nn/sP/TE13+s2Q==",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-asynciterator-polyfill": "^1.0.0",
"@azure/core-auth": "^1.3.0",
"@azure/core-tracing": "1.0.0-preview.13",
"@azure/core-util": "^1.1.1",
"@azure/logger": "^1.0.0",
"@types/node-fetch": "^2.5.0",
"@types/tunnel": "^0.0.3",
"form-data": "^4.0.0",
"node-fetch": "^2.6.6",
"node-fetch": "^2.6.7",
"process": "^0.11.10",
"tough-cookie": "^4.0.0",
"tslib": "^2.2.0",
"tunnel": "^0.0.6",
"uuid": "^8.3.0",
"xml2js": "^0.4.19"
},
"engines": {
"node": ">=12.0.0"
"node": ">=14.0.0"
}
},
"node_modules/@azure/core-http/node_modules/form-data": {
@@ -149,23 +148,10 @@
"node": ">= 6"
}
},
"node_modules/@azure/core-http/node_modules/tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
"dependencies": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
"universalify": "^0.1.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@azure/core-http/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"node_modules/@azure/core-http/node_modules/uuid": {
"version": "8.3.2",
@@ -228,6 +214,23 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@azure/core-util": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.2.0.tgz",
"integrity": "sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"tslib": "^2.2.0"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@azure/core-util/node_modules/tslib": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"node_modules/@azure/logger": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz",
@@ -269,12 +272,12 @@
}
},
"node_modules/@azure/storage-blob": {
"version": "12.8.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.8.0.tgz",
"integrity": "sha512-c8+Wz19xauW0bGkTCoqZH4dYfbtBniPiGiRQOn1ca6G5jsjr4azwaTk9gwjVY8r3vY2Taf95eivLzipfIfiS4A==",
"version": "12.13.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.13.0.tgz",
"integrity": "sha512-t3Q2lvBMJucgTjQcP5+hvEJMAsJSk0qmAnjDLie2td017IiduZbbC9BOcFfmwzR6y6cJdZOuewLCNFmEx9IrXA==",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-http": "^2.0.0",
"@azure/core-http": "^3.0.0",
"@azure/core-lro": "^2.2.0",
"@azure/core-paging": "^1.1.1",
"@azure/core-tracing": "1.0.0-preview.13",
@@ -283,7 +286,7 @@
"tslib": "^2.2.0"
},
"engines": {
"node": ">=12.0.0"
"node": ">=14.0.0"
}
},
"node_modules/@azure/storage-blob/node_modules/tslib": {
@@ -300,14 +303,14 @@
}
},
"node_modules/@types/node": {
"version": "17.0.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.14.tgz",
"integrity": "sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng=="
"version": "18.14.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.6.tgz",
"integrity": "sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA=="
},
"node_modules/@types/node-fetch": {
"version": "2.5.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
"integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz",
"integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==",
"dependencies": {
"@types/node": "*",
"form-data": "^3.0.0"
@@ -457,9 +460,9 @@
}
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -489,7 +492,7 @@
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"engines": {
"node": ">= 0.6.0"
}
@@ -552,9 +555,9 @@
}
},
"node_modules/typescript": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@@ -564,14 +567,6 @@
"node": ">=4.2.0"
}
},
"node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@@ -659,9 +654,9 @@
}
},
"@actions/io": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
},
"@azure/abort-controller": {
"version": "1.1.0",
@@ -700,21 +695,20 @@
}
},
"@azure/core-http": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.3.tgz",
"integrity": "sha512-xr8AeszxP418rI//W38NfJDDr0kbVAPZkURZnZ+Fle+lLWeURjDE5zNIuocA1wUPoKSP8iXc0ApW6nPtbLGswA==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.0.tgz",
"integrity": "sha512-BxI2SlGFPPz6J1XyZNIVUf0QZLBKFX+ViFjKOkzqD18J1zOINIQ8JSBKKr+i+v8+MB6LacL6Nn/sP/TE13+s2Q==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-asynciterator-polyfill": "^1.0.0",
"@azure/core-auth": "^1.3.0",
"@azure/core-tracing": "1.0.0-preview.13",
"@azure/core-util": "^1.1.1",
"@azure/logger": "^1.0.0",
"@types/node-fetch": "^2.5.0",
"@types/tunnel": "^0.0.3",
"form-data": "^4.0.0",
"node-fetch": "^2.6.6",
"node-fetch": "^2.6.7",
"process": "^0.11.10",
"tough-cookie": "^4.0.0",
"tslib": "^2.2.0",
"tunnel": "^0.0.6",
"uuid": "^8.3.0",
@@ -731,20 +725,10 @@
"mime-types": "^2.1.12"
}
},
"tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
"requires": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
"universalify": "^0.1.2"
}
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"uuid": {
"version": "8.3.2",
@@ -803,6 +787,22 @@
}
}
},
"@azure/core-util": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.2.0.tgz",
"integrity": "sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"tslib": "^2.2.0"
},
"dependencies": {
"tslib": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
}
}
},
"@azure/logger": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz",
@@ -842,12 +842,12 @@
}
},
"@azure/storage-blob": {
"version": "12.8.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.8.0.tgz",
"integrity": "sha512-c8+Wz19xauW0bGkTCoqZH4dYfbtBniPiGiRQOn1ca6G5jsjr4azwaTk9gwjVY8r3vY2Taf95eivLzipfIfiS4A==",
"version": "12.13.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.13.0.tgz",
"integrity": "sha512-t3Q2lvBMJucgTjQcP5+hvEJMAsJSk0qmAnjDLie2td017IiduZbbC9BOcFfmwzR6y6cJdZOuewLCNFmEx9IrXA==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-http": "^2.0.0",
"@azure/core-http": "^3.0.0",
"@azure/core-lro": "^2.2.0",
"@azure/core-paging": "^1.1.1",
"@azure/core-tracing": "1.0.0-preview.13",
@@ -869,14 +869,14 @@
"integrity": "sha512-BuJuXRSJNQ3QoKA6GWWDyuLpOUck+9hAXNMCnrloc1aWVoy6Xq6t9PUV08aBZ4Lutqq2LEHM486bpZqoViScog=="
},
"@types/node": {
"version": "17.0.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.14.tgz",
"integrity": "sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng=="
"version": "18.14.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.6.tgz",
"integrity": "sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA=="
},
"@types/node-fetch": {
"version": "2.5.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
"integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz",
"integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==",
"requires": {
"@types/node": "*",
"form-data": "^3.0.0"
@@ -998,9 +998,9 @@
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -1016,7 +1016,7 @@
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
},
"psl": {
"version": "1.8.0",
@@ -1064,16 +1064,11 @@
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"typescript": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/cache",
"version": "3.0.6",
"version": "3.2.1",
"preview": true,
"description": "Actions cache lib",
"keywords": [
@@ -44,13 +44,13 @@
"@actions/io": "^1.0.1",
"@azure/abort-controller": "^1.1.0",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0",
"@azure/storage-blob": "^12.13.0",
"semver": "^6.1.0",
"uuid": "^3.3.3"
},
"devDependencies": {
"@types/semver": "^6.0.0",
"@types/uuid": "^3.4.5",
"typescript": "^3.8.3"
"typescript": "^4.8.0"
}
}
+14 -4
View File
@@ -60,13 +60,15 @@ export function isFeatureAvailable(): boolean {
* @param primaryKey an explicit key for restoring the cache
* @param restoreKeys an optional ordered list of keys to use for restoring the cache if no cache hit occurred for key
* @param downloadOptions cache download options
* @param enableCrossOsArchive an optional boolean enabled to restore on windows any cache created on any platform
* @returns string returns the key for the cache hit, otherwise returns undefined
*/
export async function restoreCache(
paths: string[],
primaryKey: string,
restoreKeys?: string[],
options?: DownloadOptions
options?: DownloadOptions,
enableCrossOsArchive = false
): Promise<string | undefined> {
checkPaths(paths)
@@ -90,14 +92,19 @@ export async function restoreCache(
try {
// path are needed to compute version
const cacheEntry = await cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
compressionMethod,
enableCrossOsArchive
})
if (!cacheEntry?.archiveLocation) {
// Cache not found
return undefined
}
if (options?.lookupOnly) {
core.info('Lookup only - skipping download')
return cacheEntry.cacheKey
}
archivePath = path.join(
await utils.createTempDirectory(),
utils.getCacheFileName(compressionMethod)
@@ -151,13 +158,15 @@ export async function restoreCache(
*
* @param paths a list of file paths to be cached
* @param key an explicit key for restoring the cache
* @param enableCrossOsArchive an optional boolean enabled to save cache on windows which could be restored on any platform
* @param options cache upload options
* @returns number returns cacheId if the cache was saved successfully and throws an error if save fails
*/
export async function saveCache(
paths: string[],
key: string,
options?: UploadOptions
options?: UploadOptions,
enableCrossOsArchive = false
): Promise<number> {
checkPaths(paths)
checkKey(key)
@@ -207,6 +216,7 @@ export async function saveCache(
paths,
{
compressionMethod,
enableCrossOsArchive,
cacheSize: archiveFileSize
}
)
+57 -9
View File
@@ -17,7 +17,8 @@ import {
CommitCacheRequest,
ReserveCacheRequest,
ReserveCacheResponse,
ITypedResponseWithError
ITypedResponseWithError,
ArtifactCacheList
} from './contracts'
import {downloadCacheHttpClient, downloadCacheStorageSDK} from './downloadUtils'
import {
@@ -72,13 +73,21 @@ function createHttpClient(): HttpClient {
export function getCacheVersion(
paths: string[],
compressionMethod?: CompressionMethod
compressionMethod?: CompressionMethod,
enableCrossOsArchive = false
): string {
const components = paths.concat(
!compressionMethod || compressionMethod === CompressionMethod.Gzip
? []
: [compressionMethod]
)
const components = paths
// Add compression method to cache version to restore
// compressed cache as per compression method
if (compressionMethod) {
components.push(compressionMethod)
}
// Only check for windows platforms if enableCrossOsArchive is false
if (process.platform === 'win32' && !enableCrossOsArchive) {
components.push('windows-only')
}
// Add salt to cache version to support breaking changes in cache entry
components.push(versionSalt)
@@ -95,7 +104,11 @@ export async function getCacheEntry(
options?: InternalCacheOptions
): Promise<ArtifactCacheEntry | null> {
const httpClient = createHttpClient()
const version = getCacheVersion(paths, options?.compressionMethod)
const version = getCacheVersion(
paths,
options?.compressionMethod,
options?.enableCrossOsArchive
)
const resource = `cache?keys=${encodeURIComponent(
keys.join(',')
)}&version=${version}`
@@ -103,7 +116,12 @@ export async function getCacheEntry(
const response = await retryTypedResponse('getCacheEntry', async () =>
httpClient.getJson<ArtifactCacheEntry>(getCacheApiUrl(resource))
)
// Cache not found
if (response.statusCode === 204) {
// List cache for primary key only if cache miss occurs
if (core.isDebug()) {
await printCachesListForDiagnostics(keys[0], httpClient, version)
}
return null
}
if (!isSuccessStatusCode(response.statusCode)) {
@@ -113,6 +131,7 @@ export async function getCacheEntry(
const cacheResult = response.result
const cacheDownloadUrl = cacheResult?.archiveLocation
if (!cacheDownloadUrl) {
// Cache achiveLocation not found. This should never happen, and hence bail out.
throw new Error('Cache not found.')
}
core.setSecret(cacheDownloadUrl)
@@ -122,6 +141,31 @@ export async function getCacheEntry(
return cacheResult
}
async function printCachesListForDiagnostics(
key: string,
httpClient: HttpClient,
version: string
): Promise<void> {
const resource = `caches?key=${encodeURIComponent(key)}`
const response = await retryTypedResponse('listCache', async () =>
httpClient.getJson<ArtifactCacheList>(getCacheApiUrl(resource))
)
if (response.statusCode === 200) {
const cacheListResult = response.result
const totalCount = cacheListResult?.totalCount
if (totalCount && totalCount > 0) {
core.debug(
`No matching cache found for cache key '${key}', version '${version} and scope ${process.env['GITHUB_REF']}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key \nOther caches with similar key:`
)
for (const cacheEntry of cacheListResult?.artifactCaches || []) {
core.debug(
`Cache Key: ${cacheEntry?.cacheKey}, Cache Version: ${cacheEntry?.cacheVersion}, Cache Scope: ${cacheEntry?.scope}, Cache Created: ${cacheEntry?.creationTime}`
)
}
}
}
}
export async function downloadCache(
archiveLocation: string,
archivePath: string,
@@ -149,7 +193,11 @@ export async function reserveCache(
options?: InternalCacheOptions
): Promise<ITypedResponseWithError<ReserveCacheResponse>> {
const httpClient = createHttpClient()
const version = getCacheVersion(paths, options?.compressionMethod)
const version = getCacheVersion(
paths,
options?.compressionMethod,
options?.enableCrossOsArchive
)
const reserveCacheRequest: ReserveCacheRequest = {
key,
+21 -19
View File
@@ -7,7 +7,11 @@ import * as path from 'path'
import * as semver from 'semver'
import * as util from 'util'
import {v4 as uuidV4} from 'uuid'
import {CacheFilename, CompressionMethod} from './constants'
import {
CacheFilename,
CompressionMethod,
GnuTarPathOnWindows
} from './constants'
// From https://github.com/actions/toolkit/blob/main/packages/tool-cache/src/tool-cache.ts#L23
export async function createTempDirectory(): Promise<string> {
@@ -67,11 +71,15 @@ export async function unlinkFile(filePath: fs.PathLike): Promise<void> {
return util.promisify(fs.unlink)(filePath)
}
async function getVersion(app: string): Promise<string> {
core.debug(`Checking ${app} --version`)
async function getVersion(
app: string,
additionalArgs: string[] = []
): Promise<string> {
let versionOutput = ''
additionalArgs.push('--version')
core.debug(`Checking ${app} ${additionalArgs.join(' ')}`)
try {
await exec.exec(`${app} --version`, [], {
await exec.exec(`${app}`, additionalArgs, {
ignoreReturnCode: true,
silent: true,
listeners: {
@@ -90,23 +98,14 @@ async function getVersion(app: string): Promise<string> {
// Use zstandard if possible to maximize cache performance
export async function getCompressionMethod(): Promise<CompressionMethod> {
if (process.platform === 'win32' && !(await isGnuTarInstalled())) {
// Disable zstd due to bug https://github.com/actions/cache/issues/301
return CompressionMethod.Gzip
}
const versionOutput = await getVersion('zstd')
const versionOutput = await getVersion('zstd', ['--quiet'])
const version = semver.clean(versionOutput)
core.debug(`zstd version: ${version}`)
if (!versionOutput.toLowerCase().includes('zstd command line interface')) {
// zstd is not installed
if (versionOutput === '') {
return CompressionMethod.Gzip
} else if (!version || semver.lt(version, 'v1.3.2')) {
// zstd is installed but using a version earlier than v1.3.2
// v1.3.2 is required to use the `--long` options in zstd
return CompressionMethod.ZstdWithoutLong
} else {
return CompressionMethod.Zstd
return CompressionMethod.ZstdWithoutLong
}
}
@@ -116,9 +115,12 @@ export function getCacheFileName(compressionMethod: CompressionMethod): string {
: CacheFilename.Zstd
}
export async function isGnuTarInstalled(): Promise<boolean> {
export async function getGnuTarPathOnWindows(): Promise<string> {
if (fs.existsSync(GnuTarPathOnWindows)) {
return GnuTarPathOnWindows
}
const versionOutput = await getVersion('tar')
return versionOutput.toLowerCase().includes('gnu tar')
return versionOutput.toLowerCase().includes('gnu tar') ? io.which('tar') : ''
}
export function assertDefined<T>(name: string, value?: T): T {
+15
View File
@@ -11,6 +11,11 @@ export enum CompressionMethod {
Zstd = 'zstd'
}
export enum ArchiveToolType {
GNU = 'gnu',
BSD = 'bsd'
}
// The default number of retry attempts.
export const DefaultRetryAttempts = 2
@@ -21,3 +26,13 @@ export const DefaultRetryDelay = 5000
// over the socket during this period, the socket is destroyed and the download
// is aborted.
export const SocketTimeout = 5000
// The default path of GNUtar on hosted Windows runners
export const GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`
// The default path of BSDtar on hosted Windows runners
export const SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`
export const TarFilename = 'cache.tar'
export const ManifestFilename = 'manifest.txt'
+12
View File
@@ -9,10 +9,16 @@ export interface ITypedResponseWithError<T> extends TypedResponse<T> {
export interface ArtifactCacheEntry {
cacheKey?: string
scope?: string
cacheVersion?: string
creationTime?: string
archiveLocation?: string
}
export interface ArtifactCacheList {
totalCount: number
artifactCaches?: ArtifactCacheEntry[]
}
export interface CommitCacheRequest {
size: number
}
@@ -29,5 +35,11 @@ export interface ReserveCacheResponse {
export interface InternalCacheOptions {
compressionMethod?: CompressionMethod
enableCrossOsArchive?: boolean
cacheSize?: number
}
export interface ArchiveTool {
path: string
type: string
}
+11 -33
View File
@@ -12,8 +12,6 @@ import {SocketTimeout} from './constants'
import {DownloadOptions} from '../options'
import {retryHttpClientResponse} from './requestUtils'
import {AbortController} from '@azure/abort-controller'
/**
* Pipes the body of a HTTP response to a stream
*
@@ -242,15 +240,17 @@ export async function downloadCacheStorageSDK(
// If the file exceeds the buffer maximum length (~1 GB on 32-bit systems and ~2 GB
// on 64-bit systems), split the download into multiple segments
// ~2 GB = 2147483647, beyond this, we start getting out of range error. So, capping it accordingly.
const maxSegmentSize = Math.min(2147483647, buffer.constants.MAX_LENGTH)
// Updated segment size to 128MB = 134217728 bytes, to complete a segment faster and fail fast
const maxSegmentSize = Math.min(134217728, buffer.constants.MAX_LENGTH)
const downloadProgress = new DownloadProgress(contentLength)
const fd = fs.openSync(archivePath, 'w')
try {
downloadProgress.startDisplayTimer()
const controller = new AbortController()
const abortSignal = controller.signal
// const controller = new AbortController()
// const abortSignal = controller.signal
while (!downloadProgress.isDone()) {
const segmentStart =
downloadProgress.segmentOffset + downloadProgress.segmentSize
@@ -261,22 +261,15 @@ export async function downloadCacheStorageSDK(
)
downloadProgress.nextSegment(segmentSize)
const result = await promiseWithTimeout(
options.segmentTimeoutInMs || 3600000,
client.downloadToBuffer(segmentStart, segmentSize, {
abortSignal,
const result = await client.downloadToBuffer(
segmentStart,
segmentSize,
{
concurrency: options.downloadConcurrency,
onProgress: downloadProgress.onProgress()
})
}
)
if (result === 'timeout') {
controller.abort()
throw new Error(
'Aborting cache download as the download time exceeded the timeout.'
)
} else if (Buffer.isBuffer(result)) {
fs.writeFileSync(fd, result)
}
fs.writeFileSync(fd, result)
}
} finally {
downloadProgress.stopDisplayTimer()
@@ -284,18 +277,3 @@ export async function downloadCacheStorageSDK(
}
}
}
const promiseWithTimeout = async (
timeoutMs: number,
promise: Promise<Buffer>
): Promise<unknown> => {
let timeoutHandle: NodeJS.Timeout
const timeoutPromise = new Promise(resolve => {
timeoutHandle = setTimeout(() => resolve('timeout'), timeoutMs)
})
return Promise.race([promise, timeoutPromise]).then(result => {
clearTimeout(timeoutHandle)
return result
})
}
+226 -84
View File
@@ -3,25 +3,28 @@ import * as io from '@actions/io'
import {existsSync, writeFileSync} from 'fs'
import * as path from 'path'
import * as utils from './cacheUtils'
import {CompressionMethod} from './constants'
import {ArchiveTool} from './contracts'
import {
CompressionMethod,
SystemTarPathOnWindows,
ArchiveToolType,
TarFilename,
ManifestFilename
} from './constants'
const IS_WINDOWS = process.platform === 'win32'
async function getTarPath(
args: string[],
compressionMethod: CompressionMethod
): Promise<string> {
// Returns tar path and type: BSD or GNU
async function getTarPath(): Promise<ArchiveTool> {
switch (process.platform) {
case 'win32': {
const systemTar = `${process.env['windir']}\\System32\\tar.exe`
if (compressionMethod !== CompressionMethod.Gzip) {
// We only use zstandard compression on windows when gnu tar is installed due to
// a bug with compressing large files with bsdtar + zstd
args.push('--force-local')
const gnuTar = await utils.getGnuTarPathOnWindows()
const systemTar = SystemTarPathOnWindows
if (gnuTar) {
// Use GNUtar as default on windows
return <ArchiveTool>{path: gnuTar, type: ArchiveToolType.GNU}
} else if (existsSync(systemTar)) {
return systemTar
} else if (await utils.isGnuTarInstalled()) {
args.push('--force-local')
return <ArchiveTool>{path: systemTar, type: ArchiveToolType.BSD}
}
break
}
@@ -29,27 +32,133 @@ async function getTarPath(
const gnuTar = await io.which('gtar', false)
if (gnuTar) {
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
args.push('--delay-directory-restore')
return gnuTar
return <ArchiveTool>{path: gnuTar, type: ArchiveToolType.GNU}
} else {
return <ArchiveTool>{
path: await io.which('tar', true),
type: ArchiveToolType.BSD
}
}
break
}
default:
break
}
return await io.which('tar', true)
// Default assumption is GNU tar is present in path
return <ArchiveTool>{
path: await io.which('tar', true),
type: ArchiveToolType.GNU
}
}
async function execTar(
args: string[],
// Return arguments for tar as per tarPath, compressionMethod, method type and os
async function getTarArgs(
tarPath: ArchiveTool,
compressionMethod: CompressionMethod,
cwd?: string
): Promise<void> {
try {
await exec(`"${await getTarPath(args, compressionMethod)}"`, args, {cwd})
} catch (error) {
throw new Error(`Tar failed with error: ${error?.message}`)
type: string,
archivePath = ''
): Promise<string[]> {
const args = [`"${tarPath.path}"`]
const cacheFileName = utils.getCacheFileName(compressionMethod)
const tarFile = 'cache.tar'
const workingDirectory = getWorkingDirectory()
// Speficic args for BSD tar on windows for workaround
const BSD_TAR_ZSTD =
tarPath.type === ArchiveToolType.BSD &&
compressionMethod !== CompressionMethod.Gzip &&
IS_WINDOWS
// Method specific args
switch (type) {
case 'create':
args.push(
'--posix',
'-cf',
BSD_TAR_ZSTD
? tarFile
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--exclude',
BSD_TAR_ZSTD
? tarFile
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P',
'-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--files-from',
ManifestFilename
)
break
case 'extract':
args.push(
'-xf',
BSD_TAR_ZSTD
? tarFile
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P',
'-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
)
break
case 'list':
args.push(
'-tf',
BSD_TAR_ZSTD
? tarFile
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P'
)
break
}
// Platform specific args
if (tarPath.type === ArchiveToolType.GNU) {
switch (process.platform) {
case 'win32':
args.push('--force-local')
break
case 'darwin':
args.push('--delay-directory-restore')
break
}
}
return args
}
// Returns commands to run tar and compression program
async function getCommands(
compressionMethod: CompressionMethod,
type: string,
archivePath = ''
): Promise<string[]> {
let args
const tarPath = await getTarPath()
const tarArgs = await getTarArgs(
tarPath,
compressionMethod,
type,
archivePath
)
const compressionArgs =
type !== 'create'
? await getDecompressionProgram(tarPath, compressionMethod, archivePath)
: await getCompressionProgram(tarPath, compressionMethod)
const BSD_TAR_ZSTD =
tarPath.type === ArchiveToolType.BSD &&
compressionMethod !== CompressionMethod.Gzip &&
IS_WINDOWS
if (BSD_TAR_ZSTD && type !== 'create') {
args = [[...compressionArgs].join(' '), [...tarArgs].join(' ')]
} else {
args = [[...tarArgs].join(' '), [...compressionArgs].join(' ')]
}
if (BSD_TAR_ZSTD) {
return args
}
return [args.join(' ')]
}
function getWorkingDirectory(): string {
@@ -57,37 +166,110 @@ function getWorkingDirectory(): string {
}
// Common function for extractTar and listTar to get the compression method
function getCompressionProgram(compressionMethod: CompressionMethod): string[] {
async function getDecompressionProgram(
tarPath: ArchiveTool,
compressionMethod: CompressionMethod,
archivePath: string
): Promise<string[]> {
// -d: Decompress.
// unzstd is equivalent to 'zstd -d'
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
// Using 30 here because we also support 32-bit self-hosted runners.
const BSD_TAR_ZSTD =
tarPath.type === ArchiveToolType.BSD &&
compressionMethod !== CompressionMethod.Gzip &&
IS_WINDOWS
switch (compressionMethod) {
case CompressionMethod.Zstd:
return [
'--use-compress-program',
IS_WINDOWS ? 'zstd -d --long=30' : 'unzstd --long=30'
]
return BSD_TAR_ZSTD
? [
'zstd -d --long=30 --force -o',
TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
: [
'--use-compress-program',
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
]
case CompressionMethod.ZstdWithoutLong:
return ['--use-compress-program', IS_WINDOWS ? 'zstd -d' : 'unzstd']
return BSD_TAR_ZSTD
? [
'zstd -d --force -o',
TarFilename,
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
: ['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd']
default:
return ['-z']
}
}
// Used for creating the archive
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
// zstdmt is equivalent to 'zstd -T0'
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
// Using 30 here because we also support 32-bit self-hosted runners.
// Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
async function getCompressionProgram(
tarPath: ArchiveTool,
compressionMethod: CompressionMethod
): Promise<string[]> {
const cacheFileName = utils.getCacheFileName(compressionMethod)
const BSD_TAR_ZSTD =
tarPath.type === ArchiveToolType.BSD &&
compressionMethod !== CompressionMethod.Gzip &&
IS_WINDOWS
switch (compressionMethod) {
case CompressionMethod.Zstd:
return BSD_TAR_ZSTD
? [
'zstd -T0 --long=30 --force -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
TarFilename
]
: [
'--use-compress-program',
IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30'
]
case CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD
? [
'zstd -T0 --force -o',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
TarFilename
]
: ['--use-compress-program', IS_WINDOWS ? '"zstd -T0"' : 'zstdmt']
default:
return ['-z']
}
}
// Executes all commands as separate processes
async function execCommands(commands: string[], cwd?: string): Promise<void> {
for (const command of commands) {
try {
await exec(command, undefined, {
cwd,
env: {...(process.env as object), MSYS: 'winsymlinks:nativestrict'}
})
} catch (error) {
throw new Error(
`${command.split(' ')[0]} failed with error: ${error?.message}`
)
}
}
}
// List the contents of a tar
export async function listTar(
archivePath: string,
compressionMethod: CompressionMethod
): Promise<void> {
const args = [
...getCompressionProgram(compressionMethod),
'-tf',
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P'
]
await execTar(args, compressionMethod)
const commands = await getCommands(compressionMethod, 'list', archivePath)
await execCommands(commands)
}
// Extract a tar
export async function extractTar(
archivePath: string,
compressionMethod: CompressionMethod
@@ -95,61 +277,21 @@ export async function extractTar(
// Create directory to extract tar into
const workingDirectory = getWorkingDirectory()
await io.mkdirP(workingDirectory)
const args = [
...getCompressionProgram(compressionMethod),
'-xf',
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P',
'-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
]
await execTar(args, compressionMethod)
const commands = await getCommands(compressionMethod, 'extract', archivePath)
await execCommands(commands)
}
// Create a tar
export async function createTar(
archiveFolder: string,
sourceDirectories: string[],
compressionMethod: CompressionMethod
): Promise<void> {
// Write source directories to manifest.txt to avoid command length limits
const manifestFilename = 'manifest.txt'
const cacheFileName = utils.getCacheFileName(compressionMethod)
writeFileSync(
path.join(archiveFolder, manifestFilename),
path.join(archiveFolder, ManifestFilename),
sourceDirectories.join('\n')
)
const workingDirectory = getWorkingDirectory()
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
// zstdmt is equivalent to 'zstd -T0'
// --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
// Using 30 here because we also support 32-bit self-hosted runners.
// Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
function getCompressionProgram(): string[] {
switch (compressionMethod) {
case CompressionMethod.Zstd:
return [
'--use-compress-program',
IS_WINDOWS ? 'zstd -T0 --long=30' : 'zstdmt --long=30'
]
case CompressionMethod.ZstdWithoutLong:
return ['--use-compress-program', IS_WINDOWS ? 'zstd -T0' : 'zstdmt']
default:
return ['-z']
}
}
const args = [
'--posix',
...getCompressionProgram(),
'-cf',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--exclude',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P',
'-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--files-from',
manifestFilename
]
await execTar(args, compressionMethod, archiveFolder)
const commands = await getCommands(compressionMethod, 'create')
await execCommands(commands, archiveFolder)
}
+16 -1
View File
@@ -53,6 +53,15 @@ export interface DownloadOptions {
* @default 3600000
*/
segmentTimeoutInMs?: number
/**
* Weather to skip downloading the cache entry.
* If lookupOnly is set to true, the restore function will only check if
* a matching cache entry exists and return the cache key if it does.
*
* @default false
*/
lookupOnly?: boolean
}
/**
@@ -92,7 +101,8 @@ export function getDownloadOptions(copy?: DownloadOptions): DownloadOptions {
useAzureSdk: true,
downloadConcurrency: 8,
timeoutInMs: 30000,
segmentTimeoutInMs: 3600000
segmentTimeoutInMs: 600000,
lookupOnly: false
}
if (copy) {
@@ -111,6 +121,10 @@ export function getDownloadOptions(copy?: DownloadOptions): DownloadOptions {
if (typeof copy.segmentTimeoutInMs === 'number') {
result.segmentTimeoutInMs = copy.segmentTimeoutInMs
}
if (typeof copy.lookupOnly === 'boolean') {
result.lookupOnly = copy.lookupOnly
}
}
const segmentDownloadTimeoutMins =
process.env['SEGMENT_DOWNLOAD_TIMEOUT_MINS']
@@ -129,6 +143,7 @@ export function getDownloadOptions(copy?: DownloadOptions): DownloadOptions {
`Cache segment download timeout mins env var: ${process.env['SEGMENT_DOWNLOAD_TIMEOUT_MINS']}`
)
core.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`)
core.debug(`Lookup only: ${result.lookupOnly}`)
return result
}
+2 -1
View File
@@ -4,7 +4,8 @@
"baseUrl": "./",
"outDir": "./lib",
"rootDir": "./src",
"lib": ["es6", "dom"]
"lib": ["es6", "dom"],
"useUnknownInCatchVariables": false
},
"include": [
"./src"
+1 -1
View File
@@ -121,7 +121,7 @@ const result = await core.group('Do something async', async () => {
This library has 3 methods that will produce [annotations](https://docs.github.com/en/rest/reference/checks#create-a-check-run).
```js
core.error('This is a bad error. This will also fail the build.')
core.error('This is a bad error, action may still succeed though.')
core.warning('Something went wrong, but it\'s not bad enough to fail the build.')
+1 -1
View File
@@ -34,7 +34,7 @@ export enum ExitCode {
}
/**
* Optional properties that can be sent with annotatation commands (notice, error, and warning)
* Optional properties that can be sent with annotation commands (notice, error, and warning)
* See: https://docs.github.com/en/rest/reference/checks#create-a-check-run for more information about annotations.
*/
export interface AnnotationProperties {
@@ -22,7 +22,7 @@ describe('@actions/github', () => {
proxyServer.listen(port, () => resolve())
})
proxyServer.on('connect', req => {
proxyConnects.push(req.url)
proxyConnects.push(req.url ?? '')
})
})
+1 -1
View File
@@ -18,7 +18,7 @@ describe('@actions/github', () => {
proxyServer.listen(port, () => resolve(null))
})
proxyServer.on('connect', req => {
proxyConnects.push(req.url)
proxyConnects.push(req.url ?? '')
})
})
+3
View File
@@ -1,5 +1,8 @@
# @actions/glob Releases
### 0.4.0
- Pass in the current workspace as a parameter to HashFiles [#1318](https://github.com/actions/toolkit/pull/1318)
### 0.3.0
- Added a `verbose` option to HashFiles [#1052](https://github.com/actions/toolkit/pull/1052/files)
+7 -2
View File
@@ -51,6 +51,7 @@ describe('globber', () => {
)
})
const emptyDirectory = ''
it('followSymbolicLinks set to true', async () => {
const root = path.join(getTestTemp(), 'set-to-true')
await fs.mkdir(path.join(root, 'realdir'), {recursive: true})
@@ -60,7 +61,9 @@ describe('globber', () => {
path.join(root, 'symDir')
)
const testPath = path.join(root, `symDir`)
const hash = await hashFiles(testPath, {followSymbolicLinks: true})
const hash = await hashFiles(testPath, emptyDirectory, {
followSymbolicLinks: true
})
expect(hash).toEqual(
'd8a411e8f8643821bed189e627ff57151918aa554c00c10b31c693ab2dded273'
)
@@ -80,7 +83,9 @@ describe('globber', () => {
path.join(root, 'symDir')
)
const testPath = path.join(root, 'symdir')
const hash = await hashFiles(testPath, {followSymbolicLinks: false})
const hash = await hashFiles(testPath, emptyDirectory, {
followSymbolicLinks: false
})
expect(hash).toEqual('')
})
+46 -92
View File
@@ -1,12 +1,27 @@
{
"name": "@actions/glob",
"version": "0.3.0",
"lockfileVersion": 2,
"version": "0.4.0",
"lockfileVersion": 3,
"requires": true,
"description": "Actions glob lib",
"files": [
"lib",
"!.DS_Store"
],
"homepage": "https://github.com/actions/toolkit/tree/main/packages/glob",
"keywords": [
"github",
"actions",
"glob"
],
"license": "MIT",
"main": "lib/glob.js",
"preview": true,
"types": "lib/glob.d.ts",
"packages": {
"": {
"name": "@actions/glob",
"version": "0.3.0",
"version": "0.4.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.9.1",
@@ -14,26 +29,17 @@
}
},
"node_modules/@actions/core": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"version": "1.10.0",
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"dependencies": {
"tunnel": "^0.0.6"
}
},
"node_modules/balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/brace-expansion": {
"version": "1.1.11",
@@ -47,90 +53,38 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
}
},
"dependencies": {
"@actions/core": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"requires": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"requires": {
"tunnel": "^0.0.6"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"directories": {
"lib": "lib",
"test": "__tests__"
},
"publishConfig": {
"access": "public"
},
"repository": {
"directory": "packages/glob",
"type": "git",
"url": "git+https://github.com/actions/toolkit.git"
},
"scripts": {
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
"test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/glob",
"version": "0.3.0",
"version": "0.4.0",
"preview": true,
"description": "Actions glob lib",
"keywords": [
+4 -1
View File
@@ -22,10 +22,13 @@ export async function create(
* Computes the sha256 hash of a glob
*
* @param patterns Patterns separated by newlines
* @param currentWorkspace Workspace used when matching files
* @param options Glob options
* @param verbose Enables verbose logging
*/
export async function hashFiles(
patterns: string,
currentWorkspace = '',
options?: HashFileOptions,
verbose: Boolean = false
): Promise<string> {
@@ -34,5 +37,5 @@ export async function hashFiles(
followSymbolicLinks = options.followSymbolicLinks
}
const globber = await create(patterns, {followSymbolicLinks})
return _hashFiles(globber, verbose)
return _hashFiles(globber, currentWorkspace, verbose)
}
+4 -1
View File
@@ -8,11 +8,14 @@ import {Globber} from './glob'
export async function hashFiles(
globber: Globber,
currentWorkspace: string,
verbose: Boolean = false
): Promise<string> {
const writeDelegate = verbose ? core.info : core.debug
let hasMatch = false
const githubWorkspace = process.env['GITHUB_WORKSPACE'] ?? process.cwd()
const githubWorkspace = currentWorkspace
? currentWorkspace
: process.env['GITHUB_WORKSPACE'] ?? process.cwd()
const result = crypto.createHash('sha256')
let count = 0
for await (const file of globber.globGenerator()) {
+4
View File
@@ -1,5 +1,9 @@
## Releases
## 2.1.0
- Add support for `*` and subdomains in `no_proxy` [#1355](https://github.com/actions/toolkit/pull/1355) [#1223](https://github.com/actions/toolkit/pull/1223)
- Bypass proxy for loopback IP adresses [#1360](https://github.com/actions/toolkit/pull/1360))
## 2.0.1
- Fix an issue with missing `tunnel` dependency [#1085](https://github.com/actions/toolkit/pull/1085)
+69 -1
View File
@@ -19,7 +19,7 @@ describe('proxy', () => {
_proxyServer.listen(port, () => resolve())
})
_proxyServer.on('connect', req => {
_proxyConnects.push(req.url)
_proxyConnects.push(req.url ?? '')
})
})
@@ -145,6 +145,49 @@ describe('proxy', () => {
expect(bypass).toBeFalsy()
})
it('checkBypass returns true if host with subdomain in no_proxy', () => {
process.env['no_proxy'] = 'myserver.com'
const bypass = pm.checkBypass(new URL('https://sub.myserver.com'))
expect(bypass).toBeTruthy()
})
it('checkBypass returns false if no_proxy is subdomain', () => {
process.env['no_proxy'] = 'myserver.com'
const bypass = pm.checkBypass(new URL('https://myserver.com.evil.org'))
expect(bypass).toBeFalsy()
})
it('checkBypass returns false if no_proxy is part of domain', () => {
process.env['no_proxy'] = 'myserver.com'
const bypass = pm.checkBypass(new URL('https://evilmyserver.com'))
expect(bypass).toBeFalsy()
})
// Do not strip leading dots as per https://github.com/actions/runner/blob/97195bad5870e2ad0915ebfef1616083aacf5818/docs/adrs/0263-proxy-support.md
it('checkBypass returns false if host with leading dot in no_proxy', () => {
process.env['no_proxy'] = '.myserver.com'
const bypass = pm.checkBypass(new URL('https://myserver.com'))
expect(bypass).toBeFalsy()
})
it('checkBypass returns true if host with subdomain in no_proxy defined with leading "."', () => {
process.env['no_proxy'] = '.myserver.com'
const bypass = pm.checkBypass(new URL('https://sub.myserver.com'))
expect(bypass).toBeTruthy()
})
it('checkBypass returns true if no_proxy is "*"', () => {
process.env['no_proxy'] = '*'
const bypass = pm.checkBypass(new URL('https://anything.whatsoever.com'))
expect(bypass).toBeTruthy()
})
it('checkBypass returns true if no_proxy contains comma separated "*"', () => {
process.env['no_proxy'] = 'domain.com,* , example.com'
const bypass = pm.checkBypass(new URL('https://anything.whatsoever.com'))
expect(bypass).toBeTruthy()
})
it('HttpClient does basic http get request through proxy', async () => {
process.env['http_proxy'] = _proxyUrl
const httpClient = new httpm.HttpClient()
@@ -199,6 +242,31 @@ describe('proxy', () => {
expect(_proxyConnects).toHaveLength(0)
})
it('HttpClient bypasses proxy for loopback addresses (localhost, ::1, 127.*)', async () => {
// setup a server listening on localhost:8091
const server = http.createServer((request, response) => {
response.writeHead(200)
request.pipe(response)
})
server.listen(8091)
try {
process.env['http_proxy'] = _proxyUrl
const httpClient = new httpm.HttpClient()
let res = await httpClient.get('http://localhost:8091')
expect(res.message.statusCode).toBe(200)
res = await httpClient.get('http://127.0.0.1:8091')
expect(res.message.statusCode).toBe(200)
// no support for ipv6 for now
expect(httpClient.get('http://[::1]:8091')).rejects.toThrow()
// proxy at _proxyUrl was ignored
expect(_proxyConnects).toEqual([])
} finally {
server.close()
}
})
it('proxyAuth not set in tunnel agent when authentication is not provided', async () => {
process.env['https_proxy'] = 'http://127.0.0.1:8080'
const httpClient = new httpm.HttpClient()
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/http-client",
"version": "2.0.1",
"version": "2.1.0",
"description": "Actions Http Client",
"keywords": [
"github",
+25 -1
View File
@@ -25,6 +25,11 @@ export function checkBypass(reqUrl: URL): boolean {
return false
}
const reqHost = reqUrl.hostname
if (isLoopbackAddress(reqHost)) {
return true
}
const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''
if (!noProxy) {
return false
@@ -51,10 +56,29 @@ export function checkBypass(reqUrl: URL): boolean {
.split(',')
.map(x => x.trim().toUpperCase())
.filter(x => x)) {
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
if (
upperNoProxyItem === '*' ||
upperReqHosts.some(
x =>
x === upperNoProxyItem ||
x.endsWith(`.${upperNoProxyItem}`) ||
(upperNoProxyItem.startsWith('.') &&
x.endsWith(`${upperNoProxyItem}`))
)
) {
return true
}
}
return false
}
function isLoopbackAddress(host: string): boolean {
const hostLower = host.toLowerCase()
return (
hostLower === 'localhost' ||
hostLower.startsWith('127.') ||
hostLower.startsWith('[::1]') ||
hostLower.startsWith('[0:0:0:0:0:0:0:1]')
)
}
+3
View File
@@ -1,5 +1,8 @@
# @actions/io Releases
### 1.1.3
- Replace `child_process.exec` with `fs.rm` in `rmRF` for all OS implementations [#1373](https://github.com/actions/toolkit/pull/1373)
### 1.1.2
- Update `lockfileVersion` to `v2` in `package-lock.json [#1020](https://github.com/actions/toolkit/pull/1020)
+16 -24
View File
@@ -3,6 +3,7 @@ import {promises as fs} from 'fs'
import * as os from 'os'
import * as path from 'path'
import * as io from '../src/io'
import * as ioUtil from '../src/io-util'
describe('cp', () => {
beforeAll(async () => {
@@ -331,11 +332,22 @@ describe('rmRF', () => {
await fs.appendFile(filePath, 'some data')
await assertExists(filePath)
const fd = await fs.open(filePath, 'r')
await io.rmRF(testPath)
await assertNotExists(testPath)
// For windows we need to explicitly set an exclusive lock flag, because by default Node will open the file with the 'Delete' FileShare flag.
// See the exclusive lock windows flag definition:
// https://github.com/nodejs/node/blob/c2e4b1fa9ad0b744616c4e4c13a5017772a630c4/deps/uv/src/win/fs.c#L499-L513
const fd = await fs.open(
filePath,
fs.constants.O_RDONLY | ioUtil.UV_FS_O_EXLOCK
)
if (ioUtil.IS_WINDOWS) {
// On Windows, we expect an error due to an lstat call implementation in the underlying libuv code.
// See https://github.com/libuv/libuv/issues/3267 is resolved
await expect(async () => io.rmRF(testPath)).rejects.toThrow('EBUSY')
} else {
await io.rmRF(testPath)
await assertNotExists(testPath)
}
await fd.close()
await io.rmRF(testPath)
await assertNotExists(testPath)
@@ -373,26 +385,6 @@ describe('rmRF', () => {
await assertNotExists(file)
})
it('removes symlink folder with rmRF', async () => {
// create the following layout:
// real_directory
// real_directory/real_file
// symlink_directory -> real_directory
const root: string = path.join(getTestTemp(), 'rmRF_sym_dir_test')
const realDirectory: string = path.join(root, 'real_directory')
const realFile: string = path.join(root, 'real_directory', 'real_file')
const symlinkDirectory: string = path.join(root, 'symlink_directory')
await io.mkdirP(realDirectory)
await fs.writeFile(realFile, 'test file content')
await createSymlinkDir(realDirectory, symlinkDirectory)
await assertExists(path.join(symlinkDirectory, 'real_file'))
await io.rmRF(symlinkDirectory)
await assertExists(realDirectory)
await assertExists(realFile)
await assertNotExists(symlinkDirectory)
})
// creating a symlink to a file on Windows requires elevated
if (os.platform() !== 'win32') {
it('removes symlink file with rmRF', async () => {
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@actions/io",
"version": "1.1.2",
"version": "1.1.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@actions/io",
"version": "1.1.2",
"version": "1.1.3",
"license": "MIT"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/io",
"version": "1.1.2",
"version": "1.1.3",
"description": "Actions io lib",
"keywords": [
"github",
+6 -1
View File
@@ -6,16 +6,21 @@ export const {
copyFile,
lstat,
mkdir,
open,
readdir,
readlink,
rename,
rm,
rmdir,
stat,
symlink,
unlink
} = fs.promises
// export const {open} = 'fs'
export const IS_WINDOWS = process.platform === 'win32'
// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
export const UV_FS_O_EXLOCK = 0x10000000
export const READONLY = fs.constants.O_RDONLY
export async function exists(fsPath: string): Promise<boolean> {
try {
+11 -49
View File
@@ -1,12 +1,7 @@
import {ok} from 'assert'
import * as childProcess from 'child_process'
import * as path from 'path'
import {promisify} from 'util'
import * as ioUtil from './io-util'
const exec = promisify(childProcess.exec)
const execFile = promisify(childProcess.execFile)
/**
* Interface for cp/mv options
*/
@@ -116,9 +111,6 @@ export async function mv(
*/
export async function rmRF(inputPath: string): Promise<void> {
if (ioUtil.IS_WINDOWS) {
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
// Check for invalid characters
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
if (/[*"<>|]/.test(inputPath)) {
@@ -126,47 +118,17 @@ export async function rmRF(inputPath: string): Promise<void> {
'File path must not contain `*`, `"`, `<`, `>` or `|` on Windows'
)
}
try {
const cmdPath = ioUtil.getCmdPath()
if (await ioUtil.isDirectory(inputPath, true)) {
await exec(`${cmdPath} /s /c "rd /s /q "%inputPath%""`, {
env: {inputPath}
})
} else {
await exec(`${cmdPath} /s /c "del /f /a "%inputPath%""`, {
env: {inputPath}
})
}
} catch (err) {
// if you try to delete a file that doesn't exist, desired result is achieved
// other errors are valid
if (err.code !== 'ENOENT') throw err
}
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
try {
await ioUtil.unlink(inputPath)
} catch (err) {
// if you try to delete a file that doesn't exist, desired result is achieved
// other errors are valid
if (err.code !== 'ENOENT') throw err
}
} else {
let isDir = false
try {
isDir = await ioUtil.isDirectory(inputPath)
} catch (err) {
// if you try to delete a file that doesn't exist, desired result is achieved
// other errors are valid
if (err.code !== 'ENOENT') throw err
return
}
if (isDir) {
await execFile(`rm`, [`-rf`, `${inputPath}`])
} else {
await ioUtil.unlink(inputPath)
}
}
try {
// note if path does not exist, error is silent
await ioUtil.rm(inputPath, {
force: true,
maxRetries: 3,
recursive: true,
retryDelay: 300
})
} catch (err) {
throw new Error(`File was unable to be removed ${err}`)
}
}
+29 -242
View File
@@ -17,10 +17,10 @@
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/nock": "^10.0.3",
"@types/nock": "^11.1.0",
"@types/semver": "^6.0.0",
"@types/uuid": "^3.4.4",
"nock": "^10.0.6"
"nock": "^13.2.9"
}
},
"node_modules/@actions/core": {
@@ -62,12 +62,13 @@
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
},
"node_modules/@types/nock": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@types/nock/-/nock-10.0.3.tgz",
"integrity": "sha512-OthuN+2FuzfZO3yONJ/QVjKmLEuRagS9TV9lEId+WHL9KhftYG+/2z+pxlr0UgVVXSpVD8woie/3fzQn8ft/Ow==",
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@types/nock/-/nock-11.1.0.tgz",
"integrity": "sha512-jI/ewavBQ7X5178262JQR0ewicPAcJhXS/iFaNJl0VHLfyosZ/kwSrsa6VNQNSO8i9d8SqdRgOtZSOKJ/+iNMw==",
"deprecated": "This is a stub types definition. nock provides its own type definitions, so you do not need this installed.",
"dev": true,
"dependencies": {
"@types/node": "*"
"nock": "*"
}
},
"node_modules/@types/node": {
@@ -91,41 +92,6 @@
"@types/node": "*"
}
},
"node_modules/assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/chai": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
"integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
"dev": true,
"dependencies": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.2",
"deep-eql": "^3.0.1",
"get-func-name": "^2.0.0",
"pathval": "^1.1.0",
"type-detect": "^4.0.5"
},
"engines": {
"node": ">=4"
}
},
"node_modules/check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@@ -136,33 +102,6 @@
"ms": "^2.1.1"
}
},
"node_modules/deep-eql": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
"integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
"dev": true,
"dependencies": {
"type-detect": "^4.0.0"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
"dev": true
},
"node_modules/get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@@ -175,24 +114,6 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"node_modules/mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5"
},
"bin": {
"mkdirp": "bin/cmd.js"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -200,59 +121,27 @@
"dev": true
},
"node_modules/nock": {
"version": "10.0.6",
"resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz",
"integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==",
"version": "13.2.9",
"resolved": "https://registry.npmjs.org/nock/-/nock-13.2.9.tgz",
"integrity": "sha512-1+XfJNYF1cjGB+TKMWi29eZ0b82QOvQs2YoLNzbpWGqFMtRQHTa57osqdGj4FrFPgkO4D4AZinzUJR9VvW3QUA==",
"dev": true,
"dependencies": {
"chai": "^4.1.2",
"debug": "^4.1.0",
"deep-equal": "^1.0.0",
"json-stringify-safe": "^5.0.1",
"lodash": "^4.17.5",
"mkdirp": "^0.5.0",
"propagate": "^1.0.0",
"qs": "^6.5.1",
"semver": "^5.5.0"
"lodash": "^4.17.21",
"propagate": "^2.0.0"
},
"engines": {
"node": ">= 6.0"
}
},
"node_modules/nock/node_modules/semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/pathval": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
"dev": true,
"engines": {
"node": "*"
"node": ">= 10.13"
}
},
"node_modules/propagate": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz",
"integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=",
"dev": true,
"engines": [
"node >= 0.8.1"
]
},
"node_modules/qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"dev": true,
"engines": {
"node": ">=0.6"
"node": ">= 8"
}
},
"node_modules/semver": {
@@ -271,15 +160,6 @@
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
@@ -329,12 +209,12 @@
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
},
"@types/nock": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@types/nock/-/nock-10.0.3.tgz",
"integrity": "sha512-OthuN+2FuzfZO3yONJ/QVjKmLEuRagS9TV9lEId+WHL9KhftYG+/2z+pxlr0UgVVXSpVD8woie/3fzQn8ft/Ow==",
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@types/nock/-/nock-11.1.0.tgz",
"integrity": "sha512-jI/ewavBQ7X5178262JQR0ewicPAcJhXS/iFaNJl0VHLfyosZ/kwSrsa6VNQNSO8i9d8SqdRgOtZSOKJ/+iNMw==",
"dev": true,
"requires": {
"@types/node": "*"
"nock": "*"
}
},
"@types/node": {
@@ -358,32 +238,6 @@
"@types/node": "*"
}
},
"assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true
},
"chai": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
"integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
"dev": true,
"requires": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.2",
"deep-eql": "^3.0.1",
"get-func-name": "^2.0.0",
"pathval": "^1.1.0",
"type-detect": "^4.0.5"
}
},
"check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
"dev": true
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@@ -393,27 +247,6 @@
"ms": "^2.1.1"
}
},
"deep-eql": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
"integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
"dev": true,
"requires": {
"type-detect": "^4.0.0"
}
},
"deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
"dev": true
},
"get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
"dev": true
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@@ -426,21 +259,6 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -448,46 +266,21 @@
"dev": true
},
"nock": {
"version": "10.0.6",
"resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz",
"integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==",
"version": "13.2.9",
"resolved": "https://registry.npmjs.org/nock/-/nock-13.2.9.tgz",
"integrity": "sha512-1+XfJNYF1cjGB+TKMWi29eZ0b82QOvQs2YoLNzbpWGqFMtRQHTa57osqdGj4FrFPgkO4D4AZinzUJR9VvW3QUA==",
"dev": true,
"requires": {
"chai": "^4.1.2",
"debug": "^4.1.0",
"deep-equal": "^1.0.0",
"json-stringify-safe": "^5.0.1",
"lodash": "^4.17.5",
"mkdirp": "^0.5.0",
"propagate": "^1.0.0",
"qs": "^6.5.1",
"semver": "^5.5.0"
},
"dependencies": {
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true
}
"lodash": "^4.17.21",
"propagate": "^2.0.0"
}
},
"pathval": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
"dev": true
},
"propagate": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz",
"integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=",
"dev": true
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"dev": true
},
"semver": {
@@ -500,12 +293,6 @@
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+2 -2
View File
@@ -44,9 +44,9 @@
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/nock": "^10.0.3",
"@types/nock": "^11.1.0",
"@types/semver": "^6.0.0",
"@types/uuid": "^3.4.4",
"nock": "^10.0.6"
"nock": "^13.2.9"
}
}
+4
View File
@@ -1,5 +1,9 @@
#!/usr/bin/env node
// NEEDS TO BE UPDATED TO WORK ON NODE 16 BECAUSE NPM AUDIT --JSON OUTPUT CHANGED
// THE AUDIT WORKFLOW IS ONLY RUN ON PRS, BUT IT CAN BE IGNORED AND A RELEASE CAN BE CREATED NONETHELESS
// @fhammerl @rentziass
/*
This script takes the output of npm audit --json from stdin
and writes a filtered version to stdout.