Compare commits

...

57 Commits

Author SHA1 Message Date
Ferenc Hammerl 2539b9b685 Fix linting 2023-06-21 14:37:29 +00:00
Ferenc Hammerl 60f4e9859c Formatting 2023-06-20 13:55:00 +00:00
Ferenc Hammerl 17e0aec811 Prepend http:// to http(s)_proxy env if missing 2023-06-20 12:16:21 +00:00
Francesco Renzi a6bf8726aa Merge pull request #1430 from actions/add-mask-docs
Update docs for setSecret
2023-05-25 11:17:42 +01:00
Francesco Renzi ae9272d5cb Update docs/commands.md
Co-authored-by: JoannaaKL <joannaakl@github.com>
2023-05-25 11:07:37 +01:00
Francesco Renzi f481b8c8dc Update docs for setSecret 2023-05-25 11:00:25 +01:00
Francesco Renzi 59851786d4 Add tests to ensure secrets are escaped 2023-05-25 10:59:41 +01:00
Francesco Renzi 37e09c586f Merge pull request #1429 from actions/rentziass/postman
Use postman-echo to replace httpbin
2023-05-23 13:22:40 +01:00
Francesco Renzi 12c01ac203 Merge pull request #1428 from actions/rentziass/audit-fix
Update actions/cache dependencies to fix vulnerabilities
2023-05-23 13:20:12 +01:00
Francesco Renzi bbab4bec57 Update packages/http-client/__tests__/proxy.test.ts
Co-authored-by: Bassem Dghaidi <568794+Link-@users.noreply.github.com>
2023-05-23 13:10:40 +01:00
Francesco Renzi 672c88ec4b Use postman-echo to replace httpbin 2023-05-23 12:37:39 +01:00
Francesco Renzi a103f5eefe Update actions/cache dependencies to fix vulnerabilities 2023-05-22 14:32:33 +01: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
28 changed files with 528 additions and 425 deletions
+12 -1
View File
@@ -50,7 +50,18 @@ function setSecret(secret: string): void {}
Now, future logs containing BAR will be masked. E.g. running `echo "Hello FOO BAR World"` will now print `Hello FOO **** World`.
**WARNING** The add-mask and setSecret commands only support single line secrets. To register a multiline secrets you must register each line individually otherwise it will not be masked.
**WARNING** The add-mask and setSecret commands only support single-line
secrets or multi-line secrets that have been escaped. `@actions/core`
`setSecret` will escape the string you provide by default. When an escaped
multi-line string is provided the whole string and each of its lines
individually will be masked. For example you can mask `first\nsecond\r\nthird`
using:
```sh
echo "::add-mask::first%0Asecond%0D%0Athird"
```
This will mask `first%0Asecond%0D%0Athird`, `first`, `second` and `third`.
**WARNING** Do **not** mask short values if you can avoid it, it could render your output unreadable (and future steps' output as well).
For example, if you mask the letter `l`, running `echo "Hello FOO BAR World"` will now print `He*********o FOO BAR Wor****d`
+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.
+48 -3
View File
@@ -5,113 +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).
- 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`
+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)
})
+36
View File
@@ -276,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)
})
+101 -106
View File
@@ -1,12 +1,12 @@
{
"name": "@actions/cache",
"version": "3.1.3",
"version": "3.2.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@actions/cache",
"version": "3.1.3",
"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": {
@@ -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.1",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.1.tgz",
"integrity": "sha512-A3x+um3cAPgQe42Lu7Iv/x8/fNjhL/nIoEfqFxfn30EyxK6zC13n+OUxzZBRC0IzQqssqIbt4INf5YG7lYYFtw==",
"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"
"xml2js": "^0.5.0"
},
"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",
@@ -245,19 +248,19 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@azure/ms-rest-js": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.0.tgz",
"integrity": "sha512-4C5FCtvEzWudblB+h92/TYYPiq7tuElX8icVYToxOdggnYqeec4Se14mjse5miInKtZahiFHdl8lZA/jziEc5g==",
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.6.tgz",
"integrity": "sha512-WYIda8VvrkZE68xHgOxUXvjThxNf1nnGPPe0rAljqK5HJHIZ12Pi3YhEDOn3Ge7UnwaaM3eFO0VtAy4nGVI27Q==",
"dependencies": {
"@azure/core-auth": "^1.1.4",
"abort-controller": "^3.0.0",
"form-data": "^2.5.0",
"node-fetch": "^2.6.0",
"node-fetch": "^2.6.7",
"tough-cookie": "^3.0.1",
"tslib": "^1.10.0",
"tunnel": "0.0.6",
"uuid": "^8.3.2",
"xml2js": "^0.4.19"
"xml2js": "^0.5.0"
}
},
"node_modules/@azure/ms-rest-js/node_modules/uuid": {
@@ -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"
@@ -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",
@@ -596,9 +591,9 @@
}
},
"node_modules/xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
@@ -700,25 +695,24 @@
}
},
"@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.1",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.1.tgz",
"integrity": "sha512-A3x+um3cAPgQe42Lu7Iv/x8/fNjhL/nIoEfqFxfn30EyxK6zC13n+OUxzZBRC0IzQqssqIbt4INf5YG7lYYFtw==",
"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",
"xml2js": "^0.4.19"
"xml2js": "^0.5.0"
},
"dependencies": {
"form-data": {
@@ -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",
@@ -819,19 +819,19 @@
}
},
"@azure/ms-rest-js": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.0.tgz",
"integrity": "sha512-4C5FCtvEzWudblB+h92/TYYPiq7tuElX8icVYToxOdggnYqeec4Se14mjse5miInKtZahiFHdl8lZA/jziEc5g==",
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.6.tgz",
"integrity": "sha512-WYIda8VvrkZE68xHgOxUXvjThxNf1nnGPPe0rAljqK5HJHIZ12Pi3YhEDOn3Ge7UnwaaM3eFO0VtAy4nGVI27Q==",
"requires": {
"@azure/core-auth": "^1.1.4",
"abort-controller": "^3.0.0",
"form-data": "^2.5.0",
"node-fetch": "^2.6.0",
"node-fetch": "^2.6.7",
"tough-cookie": "^3.0.1",
"tslib": "^1.10.0",
"tunnel": "0.0.6",
"uuid": "^8.3.2",
"xml2js": "^0.4.19"
"xml2js": "^0.5.0"
},
"dependencies": {
"uuid": {
@@ -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"
@@ -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",
@@ -1094,9 +1089,9 @@
}
},
"xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/cache",
"version": "3.1.3",
"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"
}
}
+5
View File
@@ -100,6 +100,11 @@ export async function restoreCache(
return undefined
}
if (options?.lookupOnly) {
core.info('Lookup only - skipping download')
return cacheEntry.cacheKey
}
archivePath = path.join(
await utils.createTempDirectory(),
utils.getCacheFileName(compressionMethod)
+11 -11
View File
@@ -71,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: {
@@ -94,18 +98,14 @@ async function getVersion(app: string): Promise<string> {
// Use zstandard if possible to maximize cache performance
export async function getCompressionMethod(): Promise<CompressionMethod> {
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
}
}
+3 -1
View File
@@ -242,7 +242,9 @@ 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')
+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"
+5 -1
View File
@@ -161,7 +161,11 @@ describe('@actions/core', () => {
it('setSecret produces the correct command', () => {
core.setSecret('secret val')
assertWriteCalls([`::add-mask::secret val${os.EOL}`])
core.setSecret('multi\nline\r\nsecret')
assertWriteCalls([
`::add-mask::secret val${os.EOL}`,
`::add-mask::multi%0Aline%0D%0Asecret${os.EOL}`
])
})
it('prependPath produces the correct commands and sets the env', () => {
+42 -88
View File
@@ -1,12 +1,27 @@
{
"name": "@actions/glob",
"version": "0.4.0",
"lockfileVersion": 2,
"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,7 +53,7 @@
"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.1.2",
@@ -59,78 +65,26 @@
"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.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"
}
},
"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"
}
}
+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)
+9 -9
View File
@@ -15,18 +15,18 @@ describe('auth', () => {
bh
])
const res: httpm.HttpClientResponse = await http.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
const auth: string = obj.headers.Authorization
const auth: string = obj.headers.authorization
const creds: string = Buffer.from(
auth.substring('Basic '.length),
'base64'
).toString()
expect(creds).toBe('johndoe:password')
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.url).toBe('http://postman-echo.com/get')
})
it('does basic http get request with pat token auth', async () => {
@@ -39,18 +39,18 @@ describe('auth', () => {
ph
])
const res: httpm.HttpClientResponse = await http.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
const auth: string = obj.headers.Authorization
const auth: string = obj.headers.authorization
const creds: string = Buffer.from(
auth.substring('Basic '.length),
'base64'
).toString()
expect(creds).toBe(`PAT:${token}`)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.url).toBe('http://postman-echo.com/get')
})
it('does basic http get request with pat token auth', async () => {
@@ -61,13 +61,13 @@ describe('auth', () => {
ph
])
const res: httpm.HttpClientResponse = await http.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
const auth: string = obj.headers.Authorization
const auth: string = obj.headers.authorization
expect(auth).toBe(`Bearer ${token}`)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.url).toBe('http://postman-echo.com/get')
})
})
+69 -67
View File
@@ -33,44 +33,44 @@ describe('basics', () => {
// "args": {},
// "headers": {
// "Connection": "close",
// "Host": "httpbin.org",
// "User-Agent": "typed-test-client-tests"
// "Host": "postman-echo.com",
// "user-agent": "typed-test-client-tests"
// },
// "origin": "173.95.152.44",
// "url": "https://httpbin.org/get"
// "url": "https://postman-echo.com/get"
// }
it('does basic http get request', async () => {
const res: httpm.HttpClientResponse = await _http.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.headers['User-Agent']).toBeTruthy()
expect(obj.url).toBe('http://postman-echo.com/get')
expect(obj.headers['user-agent']).toBeTruthy()
})
it('does basic http get request with no user agent', async () => {
const http: httpm.HttpClient = new httpm.HttpClient()
const res: httpm.HttpClientResponse = await http.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.headers['User-Agent']).toBeFalsy()
expect(obj.url).toBe('http://postman-echo.com/get')
expect(obj.headers['user-agent']).toBeFalsy()
})
it('does basic https get request', async () => {
const res: httpm.HttpClientResponse = await _http.get(
'https://httpbin.org/get'
'https://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(obj.url).toBe('https://postman-echo.com/get')
})
it('does basic http get request with default headers', async () => {
@@ -85,14 +85,14 @@ describe('basics', () => {
}
)
const res: httpm.HttpClientResponse = await http.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.headers.Accept).toBe('application/json')
expect(obj.headers['Content-Type']).toBe('application/json')
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.headers.accept).toBe('application/json')
expect(obj.headers['content-type']).toBe('application/json')
expect(obj.url).toBe('http://postman-echo.com/get')
})
it('does basic http get request with merged headers', async () => {
@@ -107,7 +107,7 @@ describe('basics', () => {
}
)
const res: httpm.HttpClientResponse = await http.get(
'http://httpbin.org/get',
'http://postman-echo.com/get',
{
'content-type': 'application/x-www-form-urlencoded'
}
@@ -115,22 +115,22 @@ describe('basics', () => {
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.headers.Accept).toBe('application/json')
expect(obj.headers['Content-Type']).toBe(
expect(obj.headers.accept).toBe('application/json')
expect(obj.headers['content-type']).toBe(
'application/x-www-form-urlencoded'
)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.url).toBe('http://postman-echo.com/get')
})
it('pipes a get request', async () => {
return new Promise<void>(async resolve => {
const file = fs.createWriteStream(sampleFilePath)
;(await _http.get('https://httpbin.org/get')).message
;(await _http.get('https://postman-echo.com/get')).message
.pipe(file)
.on('close', () => {
const body: string = fs.readFileSync(sampleFilePath).toString()
const obj = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(obj.url).toBe('https://postman-echo.com/get')
resolve()
})
})
@@ -138,32 +138,32 @@ describe('basics', () => {
it('does basic get request with redirects', async () => {
const res: httpm.HttpClientResponse = await _http.get(
`https://httpbin.org/redirect-to?url=${encodeURIComponent(
'https://httpbin.org/get'
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
'https://postman-echo.com/get'
)}`
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(obj.url).toBe('https://postman-echo.com/get')
})
it('does basic get request with redirects (303)', async () => {
const res: httpm.HttpClientResponse = await _http.get(
`https://httpbin.org/redirect-to?url=${encodeURIComponent(
'https://httpbin.org/get'
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
'https://postman-echo.com/get'
)}&status_code=303`
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(obj.url).toBe('https://postman-echo.com/get')
})
it('returns 404 for not found get request on redirect', async () => {
const res: httpm.HttpClientResponse = await _http.get(
`https://httpbin.org/redirect-to?url=${encodeURIComponent(
'https://httpbin.org/status/404'
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
'https://postman-echo.com/status/404'
)}&status_code=303`
)
expect(res.message.statusCode).toBe(404)
@@ -177,8 +177,8 @@ describe('basics', () => {
{allowRedirects: false}
)
const res: httpm.HttpClientResponse = await http.get(
`https://httpbin.org/redirect-to?url=${encodeURIComponent(
'https://httpbin.org/get'
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
'https://postman-echo.com/get'
)}`
)
expect(res.message.statusCode).toBe(302)
@@ -191,8 +191,8 @@ describe('basics', () => {
authorization: 'shhh'
}
const res: httpm.HttpClientResponse = await _http.get(
`https://httpbin.org/redirect-to?url=${encodeURIComponent(
'https://www.httpbin.org/get'
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
'https://www.postman-echo.com/get'
)}`,
headers
)
@@ -201,10 +201,10 @@ describe('basics', () => {
const body: string = await res.readBody()
const obj = JSON.parse(body)
// httpbin "fixes" the casing
expect(obj.headers['Accept']).toBe('application/json')
expect(obj.headers[httpm.Headers.Accept]).toBe('application/json')
expect(obj.headers['Authorization']).toBeUndefined()
expect(obj.headers['authorization']).toBeUndefined()
expect(obj.url).toBe('https://www.httpbin.org/get')
expect(obj.url).toBe('https://www.postman-echo.com/get')
})
it('does not pass Auth with diff hostname redirects', async () => {
@@ -213,8 +213,8 @@ describe('basics', () => {
Authorization: 'shhh'
}
const res: httpm.HttpClientResponse = await _http.get(
`https://httpbin.org/redirect-to?url=${encodeURIComponent(
'https://www.httpbin.org/get'
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
'https://www.postman-echo.com/get'
)}`,
headers
)
@@ -223,22 +223,22 @@ describe('basics', () => {
const body: string = await res.readBody()
const obj = JSON.parse(body)
// httpbin "fixes" the casing
expect(obj.headers['Accept']).toBe('application/json')
expect(obj.headers[httpm.Headers.Accept]).toBe('application/json')
expect(obj.headers['Authorization']).toBeUndefined()
expect(obj.headers['authorization']).toBeUndefined()
expect(obj.url).toBe('https://www.httpbin.org/get')
expect(obj.url).toBe('https://www.postman-echo.com/get')
})
it('does basic head request', async () => {
const res: httpm.HttpClientResponse = await _http.head(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
})
it('does basic http delete request', async () => {
const res: httpm.HttpClientResponse = await _http.del(
'http://httpbin.org/delete'
'http://postman-echo.com/delete'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
@@ -248,32 +248,32 @@ describe('basics', () => {
it('does basic http post request', async () => {
const b = 'Hello World!'
const res: httpm.HttpClientResponse = await _http.post(
'http://httpbin.org/post',
'http://postman-echo.com/post',
b
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/post')
expect(obj.url).toBe('http://postman-echo.com/post')
})
it('does basic http patch request', async () => {
const b = 'Hello World!'
const res: httpm.HttpClientResponse = await _http.patch(
'http://httpbin.org/patch',
'http://postman-echo.com/patch',
b
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/patch')
expect(obj.url).toBe('http://postman-echo.com/patch')
})
it('does basic http options request', async () => {
const res: httpm.HttpClientResponse = await _http.options(
'http://httpbin.org'
'http://postman-echo.com'
)
expect(res.message.statusCode).toBe(200)
await res.readBody()
@@ -281,28 +281,30 @@ describe('basics', () => {
it('returns 404 for not found get request', async () => {
const res: httpm.HttpClientResponse = await _http.get(
'http://httpbin.org/status/404'
'http://postman-echo.com/status/404'
)
expect(res.message.statusCode).toBe(404)
await res.readBody()
})
it('gets a json object', async () => {
const jsonObj = await _http.getJson<HttpBinData>('https://httpbin.org/get')
const jsonObj = await _http.getJson<HttpBinData>(
'https://postman-echo.com/get'
)
expect(jsonObj.statusCode).toBe(200)
expect(jsonObj.result).toBeDefined()
expect(jsonObj.result?.url).toBe('https://httpbin.org/get')
expect(jsonObj.result?.headers['Accept']).toBe(
expect(jsonObj.result?.url).toBe('https://postman-echo.com/get')
expect(jsonObj.result?.headers[httpm.Headers.Accept]).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
expect(jsonObj.headers['content-type']).toContain(
httpm.MediaTypes.ApplicationJson
)
})
it('getting a non existent json object returns null', async () => {
const jsonObj = await _http.getJson<HttpBinData>(
'https://httpbin.org/status/404'
'https://postman-echo.com/status/404'
)
expect(jsonObj.statusCode).toBe(404)
expect(jsonObj.result).toBeNull()
@@ -311,20 +313,20 @@ describe('basics', () => {
it('posts a json object', async () => {
const res = {name: 'foo'}
const restRes = await _http.postJson<HttpBinData>(
'https://httpbin.org/post',
'https://postman-echo.com/post',
res
)
expect(restRes.statusCode).toBe(200)
expect(restRes.result).toBeDefined()
expect(restRes.result?.url).toBe('https://httpbin.org/post')
expect(restRes.result?.url).toBe('https://postman-echo.com/post')
expect(restRes.result?.json.name).toBe('foo')
expect(restRes.result?.headers['Accept']).toBe(
expect(restRes.result?.headers[httpm.Headers.Accept]).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.result?.headers['Content-Type']).toBe(
expect(restRes.result?.headers['content-type']).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.headers[httpm.Headers.ContentType]).toBe(
expect(restRes.headers['content-type']).toContain(
httpm.MediaTypes.ApplicationJson
)
})
@@ -332,21 +334,21 @@ describe('basics', () => {
it('puts a json object', async () => {
const res = {name: 'foo'}
const restRes = await _http.putJson<HttpBinData>(
'https://httpbin.org/put',
'https://postman-echo.com/put',
res
)
expect(restRes.statusCode).toBe(200)
expect(restRes.result).toBeDefined()
expect(restRes.result?.url).toBe('https://httpbin.org/put')
expect(restRes.result?.url).toBe('https://postman-echo.com/put')
expect(restRes.result?.json.name).toBe('foo')
expect(restRes.result?.headers['Accept']).toBe(
expect(restRes.result?.headers[httpm.Headers.Accept]).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.result?.headers['Content-Type']).toBe(
expect(restRes.result?.headers['content-type']).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.headers[httpm.Headers.ContentType]).toBe(
expect(restRes.headers['content-type']).toContain(
httpm.MediaTypes.ApplicationJson
)
})
@@ -354,20 +356,20 @@ describe('basics', () => {
it('patch a json object', async () => {
const res = {name: 'foo'}
const restRes = await _http.patchJson<HttpBinData>(
'https://httpbin.org/patch',
'https://postman-echo.com/patch',
res
)
expect(restRes.statusCode).toBe(200)
expect(restRes.result).toBeDefined()
expect(restRes.result?.url).toBe('https://httpbin.org/patch')
expect(restRes.result?.url).toBe('https://postman-echo.com/patch')
expect(restRes.result?.json.name).toBe('foo')
expect(restRes.result?.headers['Accept']).toBe(
expect(restRes.result?.headers[httpm.Headers.Accept]).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.result?.headers['Content-Type']).toBe(
expect(restRes.result?.headers['content-type']).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.headers[httpm.Headers.ContentType]).toBe(
expect(restRes.headers['content-type']).toContain(
httpm.MediaTypes.ApplicationJson
)
})
+27 -24
View File
@@ -12,11 +12,11 @@ describe('headers', () => {
it('preserves existing headers on getJson', async () => {
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj = await _http.getJson<any>(
'https://httpbin.org/get',
'https://postman-echo.com/get',
additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
@@ -26,9 +26,9 @@ describe('headers', () => {
[httpm.Headers.Accept]: 'baz'
}
}
jsonObj = await httpWithHeaders.getJson<any>('https://httpbin.org/get')
expect(jsonObj.result.headers['Accept']).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
jsonObj = await httpWithHeaders.getJson<any>('https://postman-echo.com/get')
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
})
@@ -36,12 +36,12 @@ describe('headers', () => {
it('preserves existing headers on postJson', async () => {
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj = await _http.postJson<any>(
'https://httpbin.org/post',
'https://postman-echo.com/post',
{},
additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
@@ -52,11 +52,11 @@ describe('headers', () => {
}
}
jsonObj = await httpWithHeaders.postJson<any>(
'https://httpbin.org/post',
'https://postman-echo.com/post',
{}
)
expect(jsonObj.result.headers['Accept']).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
})
@@ -64,12 +64,12 @@ describe('headers', () => {
it('preserves existing headers on putJson', async () => {
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj = await _http.putJson<any>(
'https://httpbin.org/put',
'https://postman-echo.com/put',
{},
additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
@@ -79,9 +79,12 @@ describe('headers', () => {
[httpm.Headers.Accept]: 'baz'
}
}
jsonObj = await httpWithHeaders.putJson<any>('https://httpbin.org/put', {})
expect(jsonObj.result.headers['Accept']).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
jsonObj = await httpWithHeaders.putJson<any>(
'https://postman-echo.com/put',
{}
)
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
})
@@ -89,12 +92,12 @@ describe('headers', () => {
it('preserves existing headers on patchJson', async () => {
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj = await _http.patchJson<any>(
'https://httpbin.org/patch',
'https://postman-echo.com/patch',
{},
additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
@@ -105,11 +108,11 @@ describe('headers', () => {
}
}
jsonObj = await httpWithHeaders.patchJson<any>(
'https://httpbin.org/patch',
'https://postman-echo.com/patch',
{}
)
expect(jsonObj.result.headers['Accept']).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
httpm.MediaTypes.ApplicationJson
)
})
@@ -13,24 +13,24 @@ describe('basics', () => {
it('does basic http get request with keepAlive true', async () => {
const res: httpm.HttpClientResponse = await _http.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.url).toBe('http://postman-echo.com/get')
})
it('does basic head request with keepAlive true', async () => {
const res: httpm.HttpClientResponse = await _http.head(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
})
it('does basic http delete request with keepAlive true', async () => {
const res: httpm.HttpClientResponse = await _http.del(
'http://httpbin.org/delete'
'http://postman-echo.com/delete'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
@@ -40,32 +40,32 @@ describe('basics', () => {
it('does basic http post request with keepAlive true', async () => {
const b = 'Hello World!'
const res: httpm.HttpClientResponse = await _http.post(
'http://httpbin.org/post',
'http://postman-echo.com/post',
b
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/post')
expect(obj.url).toBe('http://postman-echo.com/post')
})
it('does basic http patch request with keepAlive true', async () => {
const b = 'Hello World!'
const res: httpm.HttpClientResponse = await _http.patch(
'http://httpbin.org/patch',
'http://postman-echo.com/patch',
b
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/patch')
expect(obj.url).toBe('http://postman-echo.com/patch')
})
it('does basic http options request with keepAlive true', async () => {
const res: httpm.HttpClientResponse = await _http.options(
'http://httpbin.org'
'http://postman-echo.com'
)
expect(res.message.statusCode).toBe(200)
await res.readBody()
+51 -15
View File
@@ -91,6 +91,12 @@ describe('proxy', () => {
expect(proxyUrl).toBeDefined()
})
it('getProxyUrl returns proxyUrl if http_proxy has no protocol', () => {
process.env['http_proxy'] = 'myproxysvr'
const proxyUrl = pm.getProxyUrl(new URL('http://github.com'))
expect(proxyUrl?.toString()).toBe('http://myproxysvr/')
})
it('checkBypass returns true if host as no_proxy list', () => {
process.env['no_proxy'] = 'myserver'
const bypass = pm.checkBypass(new URL('https://myserver'))
@@ -176,37 +182,42 @@ describe('proxy', () => {
expect(bypass).toBeTruthy()
})
// Do not match wildcard ("*") as per https://github.com/actions/runner/blob/97195bad5870e2ad0915ebfef1616083aacf5818/docs/adrs/0263-proxy-support.md
it('checkBypass returns true if no_proxy is "*"', () => {
process.env['no_proxy'] = '*'
const bypass = pm.checkBypass(new URL('https://anything.whatsoever.com'))
expect(bypass).toBeFalsy()
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()
const res: httpm.HttpClientResponse = await httpClient.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(_proxyConnects).toEqual(['httpbin.org:80'])
expect(obj.url).toBe('http://postman-echo.com/get')
expect(_proxyConnects).toEqual(['postman-echo.com:80'])
})
it('HttoClient does basic http get request when bypass proxy', async () => {
it('HttpClient does basic http get request when bypass proxy', async () => {
process.env['http_proxy'] = _proxyUrl
process.env['no_proxy'] = 'httpbin.org'
process.env['no_proxy'] = 'postman-echo.com'
const httpClient = new httpm.HttpClient()
const res: httpm.HttpClientResponse = await httpClient.get(
'http://httpbin.org/get'
'http://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.url).toBe('http://postman-echo.com/get')
expect(_proxyConnects).toHaveLength(0)
})
@@ -214,29 +225,54 @@ describe('proxy', () => {
process.env['https_proxy'] = _proxyUrl
const httpClient = new httpm.HttpClient()
const res: httpm.HttpClientResponse = await httpClient.get(
'https://httpbin.org/get'
'https://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(_proxyConnects).toEqual(['httpbin.org:443'])
expect(obj.url).toBe('https://postman-echo.com/get')
expect(_proxyConnects).toEqual(['postman-echo.com:443'])
})
it('HttpClient does basic https get request when bypass proxy', async () => {
process.env['https_proxy'] = _proxyUrl
process.env['no_proxy'] = 'httpbin.org'
process.env['no_proxy'] = 'postman-echo.com'
const httpClient = new httpm.HttpClient()
const res: httpm.HttpClientResponse = await httpClient.get(
'https://httpbin.org/get'
'https://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(obj.url).toBe('https://postman-echo.com/get')
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",
+22 -1
View File
@@ -14,7 +14,12 @@ export function getProxyUrl(reqUrl: URL): URL | undefined {
})()
if (proxyVar) {
return new URL(proxyVar)
try {
return new URL(proxyVar)
} catch {
if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://'))
return new URL(`http://${proxyVar}`)
}
} else {
return undefined
}
@@ -25,6 +30,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
@@ -52,6 +62,7 @@ export function checkBypass(reqUrl: URL): boolean {
.map(x => x.trim().toUpperCase())
.filter(x => x)) {
if (
upperNoProxyItem === '*' ||
upperReqHosts.some(
x =>
x === upperNoProxyItem ||
@@ -66,3 +77,13 @@ export function checkBypass(reqUrl: URL): boolean {
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}`)
}
}