mirror of https://github.com/actions/cache.git
Compare commits
56 Commits
e60ad5c987
...
707ad40d6c
Author | SHA1 | Date |
---|---|---|
Mustafacco | 707ad40d6c | |
Jan T. Sott | 8469c94c6a | |
Josh Gross | 3624ceb22c | |
Josh Gross | 2cdf405574 | |
Eman Resu | a11fb02296 | |
mackey0225 | cf7a75e7b9 | |
Josh Gross | c74ca4022c | |
Joel Ambass | f8a7ab490b | |
Joel Ambass | 45b7be0774 | |
Bassem Dghaidi | 81382a721f | |
Bassem Dghaidi | c4ee99a3bd | |
Soubhik Kumar Mitra | 57b8e405f0 | |
r4mimu | 40c3b67b29 | |
Oleg A. | e47d9f9ec8 | |
P. Ottlinger | 4a28cbc054 | |
todgru | bf9a7572fe | |
Bethany | 0c45773b62 | |
Marc Mueller | 8a55f839aa | |
Marc Mueller | 3884cace14 | |
Marc Mueller | e29dad3e36 | |
Bethany | ab5e6d0c87 | |
bethanyj28 | 89c7d86c71 | |
bethanyj28 | d2c84da363 | |
Bethany | 37e7d4eb16 | |
Bethany | a18323f504 | |
todgru | 104f95683b | |
Yang Cao | a2ed59d39b | |
Yang Cao | dc88ab52d7 | |
Yang Cao | 1d78355196 | |
Yang Cao | c36458f13b | |
Rob Herley | 13aacd865c | |
Rob Herley | 53b35c5439 | |
Yang Cao | 65b8989fab | |
Tatyana Kostromskaya | d0be34d544 | |
Tatyana Kostromskaya | 66cf064d47 | |
Rob Herley | 1326563738 | |
Rob Herley | e12d46a63a | |
Rob Herley | 1baebfc3ba | |
Rob Herley | eb94f1a6bf | |
Tatyana Kostromskaya | e71876755e | |
Tatyana Kostromskaya | 01229828ff | |
Tatyana Kostromskaya | 3185ecfd61 | |
Tatyana Kostromskaya | 25618a0a67 | |
Tatyana Kostromskaya | a0a285ffd4 | |
Tatyana Kostromskaya | b00bedba4a | |
Tatyana Kostromskaya | 99d573b49d | |
Tatyana Kostromskaya | 6f0a1fdd90 | |
Tatyana Kostromskaya | 2001ca4114 | |
to-s | 0e9aed0d0d | |
to-s | 3b7dac1789 | |
to-s | b1378c8403 | |
Bethany | 704facf57e | |
bethanyj28 | 17e2888746 | |
bethanyj28 | 667d8fdfa2 | |
Chad Kimes | f7ebb81a3f | |
Johanan Idicula | 67b839edb6 |
|
@ -15,3 +15,5 @@ jobs:
|
||||||
call-check-dist:
|
call-check-dist:
|
||||||
name: Check dist/
|
name: Check dist/
|
||||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||||
|
with:
|
||||||
|
node-version: "20.x"
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
name: 'Publish Immutable Action Version'
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checking out
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Publish
|
||||||
|
id: publish
|
||||||
|
uses: actions/publish-immutable-action@0.0.3
|
|
@ -0,0 +1,28 @@
|
||||||
|
name: Release new action version
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [released]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
TAG_NAME:
|
||||||
|
description: 'Tag name that the major tag will point to'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_tag:
|
||||||
|
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
||||||
|
environment:
|
||||||
|
name: releaseNewActionVersion
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
|
id: update-major-tag
|
||||||
|
uses: actions/publish-action@v0.3.0
|
||||||
|
with:
|
||||||
|
source-tag: ${{ env.TAG_NAME }}
|
||||||
|
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
|
@ -21,10 +21,10 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Setup Node.js 16.x
|
- name: Setup Node.js 20.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16.x
|
node-version: 20.x
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- name: Prettier Format Check
|
- name: Prettier Format Check
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
---
|
---
|
||||||
name: "@actions/cache"
|
name: "@actions/cache"
|
||||||
version: 3.2.1
|
version: 3.2.4
|
||||||
type: npm
|
type: npm
|
||||||
summary:
|
summary: Actions cache lib
|
||||||
homepage:
|
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE.md
|
- sources: LICENSE.md
|
||||||
text: |-
|
text: |-
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright 2019 GitHub
|
Copyright 2019 GitHub
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
notices: []
|
notices: []
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
name: "@actions/http-client"
|
name: "@actions/http-client"
|
||||||
version: 2.0.1
|
version: 2.1.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: Actions Http Client
|
summary: Actions Http Client
|
||||||
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
|
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
name: "@azure/core-http"
|
name: "@azure/core-http"
|
||||||
version: 3.0.0
|
version: 3.0.4
|
||||||
type: npm
|
type: npm
|
||||||
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
|
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
|
||||||
libraries generated using AutoRest
|
libraries generated using AutoRest
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
---
|
---
|
||||||
name: "@azure/ms-rest-js"
|
name: "@azure/ms-rest-js"
|
||||||
version: 2.6.1
|
version: 2.7.0
|
||||||
type: npm
|
type: npm
|
||||||
summary:
|
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
|
||||||
homepage:
|
libraries generated using AutoRest
|
||||||
|
homepage: https://github.com/Azure/ms-rest-js
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE
|
- sources: LICENSE
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
name: ip-regex
|
|
||||||
version: 2.1.0
|
|
||||||
type: npm
|
|
||||||
summary: Regular expression for matching IP addresses (IPv4 & IPv6)
|
|
||||||
homepage: https://github.com/sindresorhus/ip-regex#readme
|
|
||||||
license: mit
|
|
||||||
licenses:
|
|
||||||
- sources: license
|
|
||||||
text: |
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
- sources: readme.md
|
|
||||||
text: MIT © [Sindre Sorhus](https://sindresorhus.com)
|
|
||||||
notices: []
|
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
name: psl
|
|
||||||
version: 1.8.0
|
|
||||||
type: npm
|
|
||||||
summary: Domain name parser based on the Public Suffix List
|
|
||||||
homepage: https://github.com/lupomontero/psl#readme
|
|
||||||
license: mit
|
|
||||||
licenses:
|
|
||||||
- sources: LICENSE
|
|
||||||
text: |
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2017 Lupo Montero lupomontero@gmail.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
- sources: README.md
|
|
||||||
text: |-
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2017 Lupo Montero <lupomontero@gmail.com>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
notices: []
|
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
name: punycode
|
|
||||||
version: 2.1.1
|
|
||||||
type: npm
|
|
||||||
summary: A robust Punycode converter that fully complies to RFC 3492 and RFC 5891,
|
|
||||||
and works on nearly all JavaScript platforms.
|
|
||||||
homepage: https://mths.be/punycode
|
|
||||||
license: mit
|
|
||||||
licenses:
|
|
||||||
- sources: LICENSE-MIT.txt
|
|
||||||
text: |
|
|
||||||
Copyright Mathias Bynens <https://mathiasbynens.be/>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
- sources: README.md
|
|
||||||
text: Punycode.js is available under the [MIT](https://mths.be/mit) license.
|
|
||||||
notices: []
|
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
name: semver
|
name: semver
|
||||||
version: 6.3.0
|
version: 6.3.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: The semantic version parser used by npm.
|
summary: The semantic version parser used by npm.
|
||||||
homepage: https://github.com/npm/node-semver#readme
|
homepage:
|
||||||
license: isc
|
license: isc
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE
|
- sources: LICENSE
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
name: tough-cookie
|
|
||||||
version: 3.0.1
|
|
||||||
type: npm
|
|
||||||
summary: RFC6265 Cookies and Cookie Jar for node.js
|
|
||||||
homepage: https://github.com/salesforce/tough-cookie
|
|
||||||
license: bsd-3-clause
|
|
||||||
licenses:
|
|
||||||
- sources: LICENSE
|
|
||||||
text: |
|
|
||||||
Copyright (c) 2015, Salesforce.com, Inc.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
notices: []
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
name: xml2js
|
name: xml2js
|
||||||
version: 0.4.23
|
version: 0.5.0
|
||||||
type: npm
|
type: npm
|
||||||
summary: Simple XML to JavaScript object converter.
|
summary: Simple XML to JavaScript object converter.
|
||||||
homepage: https://github.com/Leonidas-from-XIV/node-xml2js
|
homepage: https://github.com/Leonidas-from-XIV/node-xml2js
|
||||||
|
|
41
README.md
41
README.md
|
@ -14,6 +14,10 @@ See ["Caching dependencies to speed up workflows"](https://docs.github.com/en/ac
|
||||||
|
|
||||||
## What's New
|
## What's New
|
||||||
|
|
||||||
|
### v4
|
||||||
|
|
||||||
|
* Updated to node 20
|
||||||
|
|
||||||
### v3
|
### v3
|
||||||
|
|
||||||
* Added support for caching in GHES 3.5+.
|
* Added support for caching in GHES 3.5+.
|
||||||
|
@ -49,7 +53,7 @@ If you are using a `self-hosted` Windows runner, `GNU tar` and `zstd` are requir
|
||||||
|
|
||||||
* `key` - An explicit key for a cache entry. See [creating a cache key](#creating-a-cache-key).
|
* `key` - An explicit key for a cache entry. See [creating a cache key](#creating-a-cache-key).
|
||||||
* `path` - A list of files, directories, and wildcard patterns to cache and restore. See [`@actions/glob`](https://github.com/actions/toolkit/tree/main/packages/glob) for supported patterns.
|
* `path` - A list of files, directories, and wildcard patterns to cache and restore. See [`@actions/glob`](https://github.com/actions/toolkit/tree/main/packages/glob) for supported patterns.
|
||||||
* `restore-keys` - An ordered list of prefix-matched keys to use for restoring stale cache if no cache hit occurred for key.
|
* `restore-keys` - An ordered multiline string listing the prefix-matched keys, that are used for restoring stale cache if no cache hit occurred for key.
|
||||||
* `enableCrossOsArchive` - An optional boolean when enabled, allows Windows runners to save or restore caches that can be restored or saved respectively on other platforms. Default: `false`
|
* `enableCrossOsArchive` - An optional boolean when enabled, allows Windows runners to save or restore caches that can be restored or saved respectively on other platforms. Default: `false`
|
||||||
* `fail-on-cache-miss` - Fail the workflow if cache entry is not found. Default: `false`
|
* `fail-on-cache-miss` - Fail the workflow if cache entry is not found. Default: `false`
|
||||||
* `lookup-only` - If true, only checks if cache entry exists and skips download. Does not change save cache behavior. Default: `false`
|
* `lookup-only` - If true, only checks if cache entry exists and skips download. Does not change save cache behavior. Default: `false`
|
||||||
|
@ -60,9 +64,9 @@ If you are using a `self-hosted` Windows runner, `GNU tar` and `zstd` are requir
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
* `cache-hit` - A boolean value to indicate an exact match was found for the key.
|
* `cache-hit` - A string value to indicate an exact match was found for the key.
|
||||||
|
* If there's a cache hit, this will be 'true' or 'false' to indicate if there's an exact match for `key`.
|
||||||
> **Note** `cache-hit` will only be set to `true` when a cache hit occurs for the exact `key` match. For a partial key match via `restore-keys` or a cache miss, it will be set to `false`.
|
* If there's a cache miss, this will be an empty string.
|
||||||
|
|
||||||
See [Skipping steps based on cache-hit](#skipping-steps-based-on-cache-hit) for info on using this output
|
See [Skipping steps based on cache-hit](#skipping-steps-based-on-cache-hit) for info on using this output
|
||||||
|
|
||||||
|
@ -86,11 +90,11 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cache Primes
|
- name: Cache Primes
|
||||||
id: cache-primes
|
id: cache-primes
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: prime-numbers
|
path: prime-numbers
|
||||||
key: ${{ runner.os }}-primes
|
key: ${{ runner.os }}-primes
|
||||||
|
@ -117,11 +121,11 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Restore cached Primes
|
- name: Restore cached Primes
|
||||||
id: cache-primes-restore
|
id: cache-primes-restore
|
||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -132,7 +136,7 @@ jobs:
|
||||||
.
|
.
|
||||||
- name: Save Primes
|
- name: Save Primes
|
||||||
id: cache-primes-save
|
id: cache-primes-save
|
||||||
uses: actions/cache/save@v3
|
uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -153,6 +157,7 @@ Every programming language and framework has its own way of caching.
|
||||||
|
|
||||||
See [Examples](examples.md) for a list of `actions/cache` implementations for use with:
|
See [Examples](examples.md) for a list of `actions/cache` implementations for use with:
|
||||||
|
|
||||||
|
* [Bun](./examples.md#bun)
|
||||||
* [C# - NuGet](./examples.md#c---nuget)
|
* [C# - NuGet](./examples.md#c---nuget)
|
||||||
* [Clojure - Lein Deps](./examples.md#clojure---lein-deps)
|
* [Clojure - Lein Deps](./examples.md#clojure---lein-deps)
|
||||||
* [D - DUB](./examples.md#d---dub)
|
* [D - DUB](./examples.md#d---dub)
|
||||||
|
@ -186,7 +191,7 @@ A cache key can include any of the contexts, functions, literals, and operators
|
||||||
For example, using the [`hashFiles`](https://docs.github.com/en/actions/learn-github-actions/expressions#hashfiles) function allows you to create a new cache when dependencies change.
|
For example, using the [`hashFiles`](https://docs.github.com/en/actions/learn-github-actions/expressions#hashfiles) function allows you to create a new cache when dependencies change.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -204,7 +209,7 @@ Additionally, you can use arbitrary command output in a cache key, such as a dat
|
||||||
echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
|
echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/lockfiles') }}
|
key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/lockfiles') }}
|
||||||
|
@ -224,9 +229,9 @@ Example:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -254,11 +259,11 @@ jobs:
|
||||||
build-linux:
|
build-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cache Primes
|
- name: Cache Primes
|
||||||
id: cache-primes
|
id: cache-primes
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: prime-numbers
|
path: prime-numbers
|
||||||
key: primes
|
key: primes
|
||||||
|
@ -269,7 +274,7 @@ jobs:
|
||||||
|
|
||||||
- name: Cache Numbers
|
- name: Cache Numbers
|
||||||
id: cache-numbers
|
id: cache-numbers
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: numbers
|
path: numbers
|
||||||
key: primes
|
key: primes
|
||||||
|
@ -281,11 +286,11 @@ jobs:
|
||||||
build-windows:
|
build-windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cache Primes
|
- name: Cache Primes
|
||||||
id: cache-primes
|
id: cache-primes
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: prime-numbers
|
path: prime-numbers
|
||||||
key: primes
|
key: primes
|
||||||
|
|
152
RELEASES.md
152
RELEASES.md
|
@ -1,77 +1,61 @@
|
||||||
# Releases
|
# Releases
|
||||||
|
|
||||||
### 3.0.0
|
### 4.1.1
|
||||||
|
- Restore original behavior of `cache-hit` output - [#1467](https://github.com/actions/cache/pull/1467)
|
||||||
|
|
||||||
- Updated minimum runner version support from node 12 -> node 16
|
### 4.1.0
|
||||||
|
- Ensure `cache-hit` output is set when a cache is missed - [#1404](https://github.com/actions/cache/pull/1404)
|
||||||
|
- Deprecate `save-always` input - [#1452](https://github.com/actions/cache/pull/1452)
|
||||||
|
|
||||||
### 3.0.1
|
### 4.0.2
|
||||||
|
|
||||||
- Added support for caching from GHES 3.5.
|
- Fixed restore `fail-on-cache-miss` not working.
|
||||||
- Fixed download issue for files > 2GB during restore.
|
|
||||||
|
|
||||||
### 3.0.2
|
### 4.0.1
|
||||||
|
|
||||||
- Added support for dynamic cache size cap on GHES.
|
- Updated `isGhes` check
|
||||||
|
|
||||||
### 3.0.3
|
### 4.0.0
|
||||||
|
|
||||||
- Fixed avoiding empty cache save when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
|
- Updated minimum runner version support from node 12 -> node 20
|
||||||
|
|
||||||
### 3.0.4
|
### 3.3.3
|
||||||
|
|
||||||
- Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. ([issue](https://github.com/actions/cache/issues/689))
|
- Updates @actions/cache to v3.2.3 to fix accidental mutated path arguments to `getCacheVersion` [actions/toolkit#1378](https://github.com/actions/toolkit/pull/1378)
|
||||||
|
- Additional audit fixes of npm package(s)
|
||||||
|
|
||||||
### 3.0.5
|
### 3.3.2
|
||||||
|
|
||||||
- Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. ([PR](https://github.com/actions/cache/pull/834))
|
- Fixes bug with Azure SDK causing blob downloads to get stuck.
|
||||||
|
|
||||||
### 3.0.6
|
### 3.3.1
|
||||||
|
|
||||||
- Fixed [#809](https://github.com/actions/cache/issues/809) - zstd -d: no such file or directory error
|
- Reduced segment size to 128MB and segment timeout to 10 minutes to fail fast in case the cache download is stuck.
|
||||||
- Fixed [#833](https://github.com/actions/cache/issues/833) - cache doesn't work with github workspace directory
|
|
||||||
|
|
||||||
### 3.0.7
|
### 3.3.0
|
||||||
|
|
||||||
- Fixed [#810](https://github.com/actions/cache/issues/810) - download stuck issue. A new timeout is introduced in the download process to abort the download if it gets stuck and doesn't finish within an hour.
|
- Added option to lookup cache without downloading it.
|
||||||
|
|
||||||
### 3.0.8
|
### 3.2.6
|
||||||
|
|
||||||
- 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).
|
- Fix zstd not being used after zstd version upgrade to 1.5.4 on hosted runners.
|
||||||
- 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.9
|
### 3.2.5
|
||||||
|
|
||||||
- Enhanced the warning message for cache unavailablity in case of GHES.
|
- Added fix to prevent from setting MYSYS environment variable globally.
|
||||||
|
|
||||||
### 3.0.10
|
### 3.2.4
|
||||||
|
|
||||||
- Fix a bug with sorting inputs.
|
- Added option to fail job on cache miss.
|
||||||
- Update definition for restore-keys in README.md
|
|
||||||
|
|
||||||
### 3.0.11
|
### 3.2.3
|
||||||
|
|
||||||
- Update toolkit version to 3.0.5 to include `@actions/core@^1.10.0`
|
- Support cross os caching on Windows as an opt-in feature.
|
||||||
- Update `@actions/cache` to use updated `saveState` and `setOutput` functions from `@actions/core@^1.10.0`
|
- Fix issue with symlink restoration on Windows for cross-os caches.
|
||||||
|
|
||||||
### 3.1.0-beta.1
|
### 3.2.2
|
||||||
|
|
||||||
- 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))
|
- Reverted the changes made in 3.2.1 to use gnu tar and zstd by default on windows.
|
||||||
|
|
||||||
### 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 bsdtar fallback if gnutar not available and gzip fallback if cache saved using old cache action on windows.
|
|
||||||
|
|
||||||
### 3.2.0-beta.1
|
|
||||||
|
|
||||||
- Added two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache.
|
|
||||||
|
|
||||||
### 3.2.0
|
|
||||||
|
|
||||||
- Released the two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache
|
|
||||||
|
|
||||||
### 3.2.1
|
### 3.2.1
|
||||||
|
|
||||||
|
@ -79,31 +63,75 @@
|
||||||
- Added support for fallback to gzip to restore old caches on windows.
|
- Added support for fallback to gzip to restore old caches on windows.
|
||||||
- Added logs for cache version in case of a cache miss.
|
- Added logs for cache version in case of a cache miss.
|
||||||
|
|
||||||
### 3.2.2
|
### 3.2.0
|
||||||
|
|
||||||
- Reverted the changes made in 3.2.1 to use gnu tar and zstd by default on windows.
|
- Released the two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache
|
||||||
|
|
||||||
### 3.2.3
|
### 3.2.0-beta.1
|
||||||
|
|
||||||
- Support cross os caching on Windows as an opt-in feature.
|
- Added two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache.
|
||||||
- Fix issue with symlink restoration on Windows for cross-os caches.
|
|
||||||
|
|
||||||
### 3.2.4
|
### 3.1.0-beta.3
|
||||||
|
|
||||||
- Added option to fail job on cache miss.
|
- Bug fixes for bsdtar fallback if gnutar not available and gzip fallback if cache saved using old cache action on windows.
|
||||||
|
|
||||||
### 3.2.5
|
### 3.1.0-beta.2
|
||||||
|
|
||||||
- Added fix to prevent from setting MYSYS environment variable globally.
|
- Added support for fallback to gzip to restore old caches on windows.
|
||||||
|
|
||||||
### 3.2.6
|
### 3.1.0-beta.1
|
||||||
|
|
||||||
- Fix zstd not being used after zstd version upgrade to 1.5.4 on hosted runners.
|
- 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.3.0
|
### 3.0.11
|
||||||
|
|
||||||
- Added option to lookup cache without downloading it.
|
- Update toolkit version to 3.0.5 to include `@actions/core@^1.10.0`
|
||||||
|
- Update `@actions/cache` to use updated `saveState` and `setOutput` functions from `@actions/core@^1.10.0`
|
||||||
|
|
||||||
### 3.3.1
|
### 3.0.10
|
||||||
|
|
||||||
- Reduced segment size to 128MB and segment timeout to 10 minutes to fail fast in case the cache download is stuck.
|
- Fix a bug with sorting inputs.
|
||||||
|
- Update definition for restore-keys in README.md
|
||||||
|
|
||||||
|
### 3.0.9
|
||||||
|
|
||||||
|
- Enhanced the warning message for cache unavailablity in case of GHES.
|
||||||
|
|
||||||
|
### 3.0.8
|
||||||
|
|
||||||
|
- 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.7
|
||||||
|
|
||||||
|
- Fixed [#810](https://github.com/actions/cache/issues/810) - download stuck issue. A new timeout is introduced in the download process to abort the download if it gets stuck and doesn't finish within an hour.
|
||||||
|
|
||||||
|
### 3.0.6
|
||||||
|
|
||||||
|
- Fixed [#809](https://github.com/actions/cache/issues/809) - zstd -d: no such file or directory error
|
||||||
|
- Fixed [#833](https://github.com/actions/cache/issues/833) - cache doesn't work with github workspace directory
|
||||||
|
|
||||||
|
### 3.0.5
|
||||||
|
|
||||||
|
- Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. ([PR](https://github.com/actions/cache/pull/834))
|
||||||
|
|
||||||
|
### 3.0.4
|
||||||
|
|
||||||
|
- Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. ([issue](https://github.com/actions/cache/issues/689))
|
||||||
|
|
||||||
|
### 3.0.3
|
||||||
|
|
||||||
|
- Fixed avoiding empty cache save when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
|
||||||
|
|
||||||
|
### 3.0.2
|
||||||
|
|
||||||
|
- Added support for dynamic cache size cap on GHES.
|
||||||
|
|
||||||
|
### 3.0.1
|
||||||
|
|
||||||
|
- Added support for caching from GHES 3.5.
|
||||||
|
- Fixed download issue for files > 2GB during restore.
|
||||||
|
|
||||||
|
### 3.0.0
|
||||||
|
|
||||||
|
- Updated minimum runner version support from node 12 -> node 16
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, RefKey } from "../src/constants";
|
import { Events, RefKey } from "../src/constants";
|
||||||
import run from "../src/restore";
|
import { restoreRun } from "../src/restoreImpl";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ test("restore with no cache found", async () => {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -114,7 +114,7 @@ test("restore with restore keys and no cache found", async () => {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -156,7 +156,7 @@ test("restore with cache found for key", async () => {
|
||||||
return Promise.resolve(key);
|
return Promise.resolve(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -201,7 +201,7 @@ test("restore with cache found for restore key", async () => {
|
||||||
return Promise.resolve(restoreKey);
|
return Promise.resolve(restoreKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -246,7 +246,7 @@ test("Fail restore when fail on cache miss is enabled and primary + restore keys
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -289,7 +289,7 @@ test("restore when fail on cache miss is enabled and primary key doesn't match r
|
||||||
return Promise.resolve(restoreKey);
|
return Promise.resolve(restoreKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -335,7 +335,7 @@ test("restore with fail on cache miss disabled and no cache found", async () =>
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, Inputs, RefKey } from "../src/constants";
|
import { Events, Inputs, RefKey } from "../src/constants";
|
||||||
import run from "../src/restoreImpl";
|
import { restoreImpl } from "../src/restoreImpl";
|
||||||
import { StateProvider } from "../src/stateProvider";
|
import { StateProvider } from "../src/stateProvider";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
@ -60,7 +60,7 @@ test("restore with invalid event outputs warning", async () => {
|
||||||
const invalidEvent = "commit_comment";
|
const invalidEvent = "commit_comment";
|
||||||
process.env[Events.Key] = invalidEvent;
|
process.env[Events.Key] = invalidEvent;
|
||||||
delete process.env[RefKey];
|
delete process.env[RefKey];
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
||||||
);
|
);
|
||||||
|
@ -76,7 +76,7 @@ test("restore without AC available should no-op", async () => {
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
|
@ -92,7 +92,7 @@ test("restore on GHES without AC available should no-op", async () => {
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
|
||||||
|
@ -119,7 +119,7 @@ test("restore on GHES with AC available ", async () => {
|
||||||
return Promise.resolve(key);
|
return Promise.resolve(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -143,7 +143,7 @@ test("restore on GHES with AC available ", async () => {
|
||||||
test("restore with no path should fail", async () => {
|
test("restore with no path should fail", async () => {
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
// this input isn't necessary for restore b/c tarball contains entries relative to workspace
|
// this input isn't necessary for restore b/c tarball contains entries relative to workspace
|
||||||
expect(failedMock).not.toHaveBeenCalledWith(
|
expect(failedMock).not.toHaveBeenCalledWith(
|
||||||
|
@ -155,7 +155,7 @@ test("restore with no key", async () => {
|
||||||
testUtils.setInput(Inputs.Path, "node_modules");
|
testUtils.setInput(Inputs.Path, "node_modules");
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
expect(failedMock).toHaveBeenCalledWith(
|
expect(failedMock).toHaveBeenCalledWith(
|
||||||
"Input required and not supplied: key"
|
"Input required and not supplied: key"
|
||||||
|
@ -174,7 +174,7 @@ test("restore with too many keys should fail", async () => {
|
||||||
});
|
});
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
[path],
|
[path],
|
||||||
|
@ -200,7 +200,7 @@ test("restore with large key should fail", async () => {
|
||||||
});
|
});
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
[path],
|
[path],
|
||||||
|
@ -226,7 +226,7 @@ test("restore with invalid key should fail", async () => {
|
||||||
});
|
});
|
||||||
const failedMock = jest.spyOn(core, "setFailed");
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
[path],
|
[path],
|
||||||
|
@ -260,7 +260,7 @@ test("restore with no cache found", async () => {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -301,7 +301,7 @@ test("restore with restore keys and no cache found", async () => {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -341,7 +341,7 @@ test("restore with cache found for key", async () => {
|
||||||
return Promise.resolve(key);
|
return Promise.resolve(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -383,7 +383,7 @@ test("restore with cache found for restore key", async () => {
|
||||||
return Promise.resolve(restoreKey);
|
return Promise.resolve(restoreKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -424,7 +424,7 @@ test("restore with lookup-only set", async () => {
|
||||||
return Promise.resolve(key);
|
return Promise.resolve(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await restoreImpl(new StateProvider());
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -449,3 +449,19 @@ test("restore with lookup-only set", async () => {
|
||||||
);
|
);
|
||||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("restore failure with earlyExit should call process exit", async () => {
|
||||||
|
testUtils.setInput(Inputs.Path, "node_modules");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
|
||||||
|
const processExitMock = jest.spyOn(process, "exit").mockImplementation();
|
||||||
|
|
||||||
|
// call restoreImpl with `earlyExit` set to true
|
||||||
|
await restoreImpl(new StateProvider(), true);
|
||||||
|
|
||||||
|
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
|
||||||
|
expect(failedMock).toHaveBeenCalledWith(
|
||||||
|
"Input required and not supplied: key"
|
||||||
|
);
|
||||||
|
expect(processExitMock).toHaveBeenCalledWith(1);
|
||||||
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, RefKey } from "../src/constants";
|
import { Events, RefKey } from "../src/constants";
|
||||||
import run from "../src/restoreOnly";
|
import { restoreOnlyRun } from "../src/restoreImpl";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ test("restore with no cache found", async () => {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreOnlyRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -114,7 +114,7 @@ test("restore with restore keys and no cache found", async () => {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreOnlyRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -153,7 +153,7 @@ test("restore with cache found for key", async () => {
|
||||||
return Promise.resolve(key);
|
return Promise.resolve(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreOnlyRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -196,7 +196,7 @@ test("restore with cache found for restore key", async () => {
|
||||||
return Promise.resolve(restoreKey);
|
return Promise.resolve(restoreKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await restoreOnlyRun();
|
||||||
|
|
||||||
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(restoreCacheMock).toHaveBeenCalledWith(
|
expect(restoreCacheMock).toHaveBeenCalledWith(
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, Inputs, RefKey } from "../src/constants";
|
import { Events, Inputs, RefKey } from "../src/constants";
|
||||||
import run from "../src/save";
|
import { saveRun } from "../src/saveImpl";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ test("save with valid inputs uploads a cache", async () => {
|
||||||
return Promise.resolve(cacheId);
|
return Promise.resolve(cacheId);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await saveRun();
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, Inputs, RefKey } from "../src/constants";
|
import { Events, Inputs, RefKey } from "../src/constants";
|
||||||
import run from "../src/saveImpl";
|
import { saveImpl } from "../src/saveImpl";
|
||||||
import { StateProvider } from "../src/stateProvider";
|
import { StateProvider } from "../src/stateProvider";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
@ -77,7 +77,7 @@ test("save with invalid event outputs warning", async () => {
|
||||||
const invalidEvent = "commit_comment";
|
const invalidEvent = "commit_comment";
|
||||||
process.env[Events.Key] = invalidEvent;
|
process.env[Events.Key] = invalidEvent;
|
||||||
delete process.env[RefKey];
|
delete process.env[RefKey];
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
|
||||||
);
|
);
|
||||||
|
@ -100,7 +100,7 @@ test("save with no primary key in state outputs warning", async () => {
|
||||||
});
|
});
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(`Key is not specified.`);
|
expect(logWarningMock).toHaveBeenCalledWith(`Key is not specified.`);
|
||||||
|
@ -115,7 +115,7 @@ test("save without AC available should no-op", async () => {
|
||||||
|
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
@ -128,7 +128,7 @@ test("save on ghes without AC available should no-op", async () => {
|
||||||
|
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
@ -161,7 +161,7 @@ test("save on GHES with AC available", async () => {
|
||||||
return Promise.resolve(cacheId);
|
return Promise.resolve(cacheId);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -194,7 +194,7 @@ test("save with exact match returns early", async () => {
|
||||||
});
|
});
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
expect(infoMock).toHaveBeenCalledWith(
|
expect(infoMock).toHaveBeenCalledWith(
|
||||||
|
@ -221,7 +221,7 @@ test("save with missing input outputs warning", async () => {
|
||||||
});
|
});
|
||||||
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
const saveCacheMock = jest.spyOn(cache, "saveCache");
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
expect(saveCacheMock).toHaveBeenCalledTimes(0);
|
||||||
expect(logWarningMock).toHaveBeenCalledWith(
|
expect(logWarningMock).toHaveBeenCalledWith(
|
||||||
|
@ -259,7 +259,7 @@ test("save with large cache outputs warning", async () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -306,7 +306,7 @@ test("save with reserve cache failure outputs warning", async () => {
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -349,7 +349,7 @@ test("save with server error outputs warning", async () => {
|
||||||
throw new Error("HTTP Error Occurred");
|
throw new Error("HTTP Error Occurred");
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -392,7 +392,7 @@ test("save with valid inputs uploads a cache", async () => {
|
||||||
return Promise.resolve(cacheId);
|
return Promise.resolve(cacheId);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run(new StateProvider());
|
await saveImpl(new StateProvider());
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, Inputs, RefKey } from "../src/constants";
|
import { Events, Inputs, RefKey } from "../src/constants";
|
||||||
import run from "../src/saveOnly";
|
import { saveOnlyRun } from "../src/saveImpl";
|
||||||
import * as actionUtils from "../src/utils/actionUtils";
|
import * as actionUtils from "../src/utils/actionUtils";
|
||||||
import * as testUtils from "../src/utils/testUtils";
|
import * as testUtils from "../src/utils/testUtils";
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ test("save with valid inputs uploads a cache", async () => {
|
||||||
return Promise.resolve(cacheId);
|
return Promise.resolve(cacheId);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await saveOnlyRun();
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
@ -122,7 +122,7 @@ test("save failing logs the warning message", async () => {
|
||||||
return Promise.resolve(cacheId);
|
return Promise.resolve(cacheId);
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await saveOnlyRun();
|
||||||
|
|
||||||
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
expect(saveCacheMock).toHaveBeenCalledTimes(1);
|
||||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||||
|
|
14
action.yml
14
action.yml
|
@ -9,7 +9,7 @@ inputs:
|
||||||
description: 'An explicit key for restoring and saving the cache'
|
description: 'An explicit key for restoring and saving the cache'
|
||||||
required: true
|
required: true
|
||||||
restore-keys:
|
restore-keys:
|
||||||
description: 'An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
|
description: 'An ordered multiline string listing the prefix-matched keys, that are used for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
|
||||||
required: false
|
required: false
|
||||||
upload-chunk-size:
|
upload-chunk-size:
|
||||||
description: 'The chunk size used to split up large files during upload, in bytes'
|
description: 'The chunk size used to split up large files during upload, in bytes'
|
||||||
|
@ -26,14 +26,22 @@ inputs:
|
||||||
description: 'Check if a cache entry exists for the given input(s) (key, restore-keys) without downloading the cache'
|
description: 'Check if a cache entry exists for the given input(s) (key, restore-keys) without downloading the cache'
|
||||||
default: 'false'
|
default: 'false'
|
||||||
required: false
|
required: false
|
||||||
|
save-always:
|
||||||
|
description: 'Run the post step to save the cache even if another step before fails'
|
||||||
|
default: 'false'
|
||||||
|
required: false
|
||||||
|
deprecationMessage: |
|
||||||
|
save-always does not work as intended and will be removed in a future release.
|
||||||
|
A separate `actions/cache/restore` step should be used instead.
|
||||||
|
See https://github.com/actions/cache/tree/main/save#always-save-cache for more details.
|
||||||
outputs:
|
outputs:
|
||||||
cache-hit:
|
cache-hit:
|
||||||
description: 'A boolean value to indicate an exact match was found for the primary key'
|
description: 'A boolean value to indicate an exact match was found for the primary key'
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node20'
|
||||||
main: 'dist/restore/index.js'
|
main: 'dist/restore/index.js'
|
||||||
post: 'dist/save/index.js'
|
post: 'dist/save/index.js'
|
||||||
post-if: success()
|
post-if: "success()"
|
||||||
branding:
|
branding:
|
||||||
icon: 'archive'
|
icon: 'archive'
|
||||||
color: 'gray-dark'
|
color: 'gray-dark'
|
||||||
|
|
|
@ -12,7 +12,7 @@ This document lists some of the strategies (and example workflows if possible) w
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
key: ${{ some-metadata }}-cache
|
key: ${{ some-metadata }}-cache
|
||||||
```
|
```
|
||||||
|
@ -24,7 +24,7 @@ In your workflows, you can use different strategies to name your key depending o
|
||||||
One of the most common use case is to use hash for lockfile as key. This way, same cache will be restored for a lockfile until there's a change in dependencies listed in lockfile.
|
One of the most common use case is to use hash for lockfile as key. This way, same cache will be restored for a lockfile until there's a change in dependencies listed in lockfile.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -37,7 +37,7 @@ One of the most common use case is to use hash for lockfile as key. This way, sa
|
||||||
If cache is not found matching the primary key, restore keys can be used to download the closest matching cache that was recently created. This ensures that the build/install step will need to additionally fetch just a handful of newer dependencies, and hence saving build time.
|
If cache is not found matching the primary key, restore keys can be used to download the closest matching cache that was recently created. This ensures that the build/install step will need to additionally fetch just a handful of newer dependencies, and hence saving build time.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -54,7 +54,7 @@ The restore keys can be provided as a complete name, or a prefix, read more [her
|
||||||
In case of workflows with matrix running for multiple Operating Systems, the caches can be stored separately for each of them. This can be used in combination with hashfiles in case multiple caches are being generated per OS.
|
In case of workflows with matrix running for multiple Operating Systems, the caches can be stored separately for each of them. This can be used in combination with hashfiles in case multiple caches are being generated per OS.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -73,7 +73,7 @@ Caches scoped to the particular workflow run id or run attempt can be stored and
|
||||||
On similar lines, commit sha can be used to create a very specialized and short lived cache.
|
On similar lines, commit sha can be used to create a very specialized and short lived cache.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -81,12 +81,12 @@ On similar lines, commit sha can be used to create a very specialized and short
|
||||||
key: cache-${{ github.sha }}
|
key: cache-${{ github.sha }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using multiple factors while forming a key depening on the need
|
### Using multiple factors while forming a key depending on the need
|
||||||
|
|
||||||
Cache key can be formed by combination of more than one metadata, evaluated info.
|
Cache key can be formed by combination of more than one metadata, evaluated info.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -146,9 +146,9 @@ In case you are using a centralized job to create and save your cache that can b
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache/restore@v3
|
- uses: actions/cache/restore@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -171,9 +171,9 @@ You can use the output of this action to exit the workflow on cache miss. This w
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache/restore@v3
|
- uses: actions/cache/restore@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -194,7 +194,7 @@ steps:
|
||||||
If you want to avoid re-computing the cache key again in `save` action, the outputs from `restore` action can be used as input to the `save` action.
|
If you want to avoid re-computing the cache key again in `save` action, the outputs from `restore` action can be used as input to the `save` action.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache/restore@v3
|
- uses: actions/cache/restore@v4
|
||||||
id: restore-cache
|
id: restore-cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -204,7 +204,7 @@ If you want to avoid re-computing the cache key again in `save` action, the outp
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
- uses: actions/cache/save@v3
|
- uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
path/to/dependencies
|
path/to/dependencies
|
||||||
|
@ -219,7 +219,7 @@ On the other hand, the key can also be explicitly re-computed while executing th
|
||||||
Let's say we have a restore step that computes key at runtime
|
Let's say we have a restore step that computes key at runtime
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v4
|
||||||
id: restore-cache
|
id: restore-cache
|
||||||
with:
|
with:
|
||||||
key: cache-${{ hashFiles('**/lockfiles') }}
|
key: cache-${{ hashFiles('**/lockfiles') }}
|
||||||
|
@ -228,7 +228,7 @@ with:
|
||||||
Case 1: Where an user would want to reuse the key as it is
|
Case 1: Where an user would want to reuse the key as it is
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: actions/cache/save@v3
|
uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
|
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
|
||||||
```
|
```
|
||||||
|
@ -236,31 +236,14 @@ with:
|
||||||
Case 2: Where the user would want to re-evaluate the key
|
Case 2: Where the user would want to re-evaluate the key
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: actions/cache/save@v3
|
uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
key: npm-cache-${{hashfiles(package-lock.json)}}
|
key: npm-cache-${{hashfiles(package-lock.json)}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Saving cache even if the build fails
|
### Saving cache even if the build fails
|
||||||
|
|
||||||
There can be cases where a cache should be saved even if the build job fails. For example, a job can fail due to flaky tests but the caches can still be re-used. You can use `actions/cache/save` action to save the cache by using `if: always()` condition.
|
See [Always save cache](./save/README.md#always-save-cache).
|
||||||
|
|
||||||
Similarly, `actions/cache/save` action can be conditionally used based on the output of the previous steps. This way you get more control on when to save the cache.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
.
|
|
||||||
. // restore if need be
|
|
||||||
.
|
|
||||||
- name: Build
|
|
||||||
run: /build.sh
|
|
||||||
- uses: actions/cache/save@v3
|
|
||||||
if: always() // or any other condition to invoke the save action
|
|
||||||
with:
|
|
||||||
path: path/to/dependencies
|
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Saving cache once and reusing in multiple workflows
|
### Saving cache once and reusing in multiple workflows
|
||||||
|
|
||||||
|
@ -270,12 +253,12 @@ In case of multi-module projects, where the built artifact of one project needs
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./build-parent-module.sh
|
run: ./build-parent-module.sh
|
||||||
|
|
||||||
- uses: actions/cache/save@v3
|
- uses: actions/cache/save@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -286,9 +269,9 @@ steps:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache/restore@v3
|
- uses: actions/cache/restore@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
108
examples.md
108
examples.md
|
@ -1,5 +1,6 @@
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
|
- [Bun](#bun)
|
||||||
- [C# - NuGet](#c---nuget)
|
- [C# - NuGet](#c---nuget)
|
||||||
- [Clojure - Lein Deps](#clojure---lein-deps)
|
- [Clojure - Lein Deps](#clojure---lein-deps)
|
||||||
- [D - DUB](#d---dub)
|
- [D - DUB](#d---dub)
|
||||||
|
@ -41,12 +42,32 @@
|
||||||
- [Swift - Mint](#swift---mint)
|
- [Swift - Mint](#swift---mint)
|
||||||
- [* - Bazel](#---bazel)
|
- [* - Bazel](#---bazel)
|
||||||
|
|
||||||
|
## Bun
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.bun/install/cache
|
||||||
|
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~\.bun
|
||||||
|
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||||
|
```
|
||||||
|
|
||||||
## C# - NuGet
|
## C# - NuGet
|
||||||
|
|
||||||
Using [NuGet lock files](https://docs.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies):
|
Using [NuGet lock files](https://docs.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.nuget/packages
|
path: ~/.nuget/packages
|
||||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||||
|
@ -55,10 +76,10 @@ Using [NuGet lock files](https://docs.microsoft.com/nuget/consume-packages/packa
|
||||||
```
|
```
|
||||||
|
|
||||||
Depending on the environment, huge packages might be pre-installed in the global cache folder.
|
Depending on the environment, huge packages might be pre-installed in the global cache folder.
|
||||||
With `actions/cache@v3` you can now exclude unwanted packages with [exclude pattern](https://github.com/actions/toolkit/tree/main/packages/glob#exclude-patterns)
|
With `actions/cache@v4` you can now exclude unwanted packages with [exclude pattern](https://github.com/actions/toolkit/tree/main/packages/glob#exclude-patterns)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.nuget/packages
|
~/.nuget/packages
|
||||||
|
@ -75,7 +96,7 @@ Or you could move the cache folder like below.
|
||||||
env:
|
env:
|
||||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ github.workspace }}/.nuget/packages
|
path: ${{ github.workspace }}/.nuget/packages
|
||||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||||
|
@ -87,7 +108,7 @@ steps:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache lein project dependencies
|
- name: Cache lein project dependencies
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.m2/repository
|
path: ~/.m2/repository
|
||||||
key: ${{ runner.os }}-clojure-${{ hashFiles('**/project.clj') }}
|
key: ${{ runner.os }}-clojure-${{ hashFiles('**/project.clj') }}
|
||||||
|
@ -101,7 +122,7 @@ steps:
|
||||||
### POSIX
|
### POSIX
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.dub
|
path: ~/.dub
|
||||||
key: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}
|
key: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}
|
||||||
|
@ -112,7 +133,7 @@ steps:
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~\AppData\Local\dub
|
path: ~\AppData\Local\dub
|
||||||
key: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}
|
key: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}
|
||||||
|
@ -125,7 +146,7 @@ steps:
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.deno
|
~/.deno
|
||||||
|
@ -136,7 +157,7 @@ steps:
|
||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.deno
|
~/.deno
|
||||||
|
@ -147,7 +168,7 @@ steps:
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~\.deno
|
~\.deno
|
||||||
|
@ -158,7 +179,7 @@ steps:
|
||||||
## Elixir - Mix
|
## Elixir - Mix
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
deps
|
deps
|
||||||
|
@ -185,7 +206,7 @@ steps:
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cache/go-build
|
~/.cache/go-build
|
||||||
|
@ -198,7 +219,7 @@ steps:
|
||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/Library/Caches/go-build
|
~/Library/Caches/go-build
|
||||||
|
@ -211,7 +232,7 @@ steps:
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~\AppData\Local\go-build
|
~\AppData\Local\go-build
|
||||||
|
@ -227,7 +248,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache ~/.cabal/packages, ~/.cabal/store and dist-newstyle
|
- name: Cache ~/.cabal/packages, ~/.cabal/store and dist-newstyle
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cabal/packages
|
~/.cabal/packages
|
||||||
|
@ -242,14 +263,14 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
|
||||||
### Linux or macOS
|
### Linux or macOS
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
name: Cache ~/.stack
|
name: Cache ~/.stack
|
||||||
with:
|
with:
|
||||||
path: ~/.stack
|
path: ~/.stack
|
||||||
key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
|
key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-stack-global-
|
${{ runner.os }}-stack-global-
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
name: Cache .stack-work
|
name: Cache .stack-work
|
||||||
with:
|
with:
|
||||||
path: .stack-work
|
path: .stack-work
|
||||||
|
@ -261,7 +282,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
name: Cache %APPDATA%\stack %LOCALAPPDATA%\Programs\stack
|
name: Cache %APPDATA%\stack %LOCALAPPDATA%\Programs\stack
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -270,7 +291,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
|
||||||
key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
|
key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-stack-global-
|
${{ runner.os }}-stack-global-
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
name: Cache .stack-work
|
name: Cache .stack-work
|
||||||
with:
|
with:
|
||||||
path: .stack-work
|
path: .stack-work
|
||||||
|
@ -284,7 +305,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
|
||||||
> **Note** Ensure no Gradle daemons are running anymore when your workflow completes. Creating the cache package might fail due to locks being held by Gradle. Refer to the [Gradle Daemon documentation](https://docs.gradle.org/current/userguide/gradle_daemon.html) on how to disable or stop the Gradle Daemons.
|
> **Note** Ensure no Gradle daemons are running anymore when your workflow completes. Creating the cache package might fail due to locks being held by Gradle. Refer to the [Gradle Daemon documentation](https://docs.gradle.org/current/userguide/gradle_daemon.html) on how to disable or stop the Gradle Daemons.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.gradle/caches
|
~/.gradle/caches
|
||||||
|
@ -298,7 +319,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache local Maven repository
|
- name: Cache local Maven repository
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.m2/repository
|
path: ~/.m2/repository
|
||||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||||
|
@ -334,7 +355,7 @@ After [deprecation](https://github.blog/changelog/2022-10-11-github-actions-depr
|
||||||
`Get npm cache directory` step can then be used with `actions/cache` as shown below
|
`Get npm cache directory` step can then be used with `actions/cache` as shown below
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
|
id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||||
|
@ -347,7 +368,7 @@ After [deprecation](https://github.blog/changelog/2022-10-11-github-actions-depr
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: restore lerna
|
- name: restore lerna
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: '**/node_modules'
|
path: '**/node_modules'
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
@ -361,7 +382,7 @@ The yarn cache directory will depend on your operating system and version of `ya
|
||||||
id: yarn-cache-dir-path
|
id: yarn-cache-dir-path
|
||||||
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
|
@ -379,7 +400,7 @@ The yarn 2 cache directory will depend on your config. See https://yarnpkg.com/c
|
||||||
id: yarn-cache-dir-path
|
id: yarn-cache-dir-path
|
||||||
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
|
@ -394,7 +415,7 @@ Esy allows you to export built dependencies and import pre-built dependencies.
|
||||||
```yaml
|
```yaml
|
||||||
- name: Restore Cache
|
- name: Restore Cache
|
||||||
id: restore-cache
|
id: restore-cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: _export
|
path: _export
|
||||||
key: ${{ runner.os }}-esy-${{ hashFiles('esy.lock/index.json') }}
|
key: ${{ runner.os }}-esy-${{ hashFiles('esy.lock/index.json') }}
|
||||||
|
@ -423,7 +444,7 @@ Esy allows you to export built dependencies and import pre-built dependencies.
|
||||||
id: composer-cache
|
id: composer-cache
|
||||||
run: |
|
run: |
|
||||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.composer-cache.outputs.dir }}
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
@ -444,7 +465,7 @@ Locations:
|
||||||
### Simple example
|
### Simple example
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||||
|
@ -457,7 +478,7 @@ Replace `~/.cache/pip` with the correct `path` if not using Ubuntu.
|
||||||
### Multiple OS's in a workflow
|
### Multiple OS's in a workflow
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
if: startsWith(runner.os, 'Linux')
|
if: startsWith(runner.os, 'Linux')
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
|
@ -465,7 +486,7 @@ Replace `~/.cache/pip` with the correct `path` if not using Ubuntu.
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
if: startsWith(runner.os, 'macOS')
|
if: startsWith(runner.os, 'macOS')
|
||||||
with:
|
with:
|
||||||
path: ~/Library/Caches/pip
|
path: ~/Library/Caches/pip
|
||||||
|
@ -473,7 +494,7 @@ Replace `~/.cache/pip` with the correct `path` if not using Ubuntu.
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
if: startsWith(runner.os, 'Windows')
|
if: startsWith(runner.os, 'Windows')
|
||||||
with:
|
with:
|
||||||
path: ~\AppData\Local\pip\Cache
|
path: ~\AppData\Local\pip\Cache
|
||||||
|
@ -499,7 +520,7 @@ jobs:
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
path: ~\AppData\Local\pip\Cache
|
path: ~\AppData\Local\pip\Cache
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ matrix.path }}
|
path: ${{ matrix.path }}
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||||
|
@ -513,11 +534,12 @@ jobs:
|
||||||
```yaml
|
```yaml
|
||||||
- name: Get pip cache dir
|
- name: Get pip cache dir
|
||||||
id: pip-cache
|
id: pip-cache
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
|
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: pip cache
|
- name: pip cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.pip-cache.outputs.dir }}
|
path: ${{ steps.pip-cache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||||
|
@ -535,7 +557,7 @@ jobs:
|
||||||
|
|
||||||
⋮
|
⋮
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.local/share/virtualenvs
|
path: ~/.local/share/virtualenvs
|
||||||
key: ${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-pipenv-${{ hashFiles('Pipfile.lock') }}
|
key: ${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-pipenv-${{ hashFiles('Pipfile.lock') }}
|
||||||
|
@ -562,7 +584,7 @@ For renv, the cache directory will vary by OS. The `RENV_PATHS_ROOT` environment
|
||||||
cat("##[set-output name=r-version;]", R.Version()$version.string, sep = "")
|
cat("##[set-output name=r-version;]", R.Version()$version.string, sep = "")
|
||||||
shell: Rscript {0}
|
shell: Rscript {0}
|
||||||
- name: Restore Renv package cache
|
- name: Restore Renv package cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ env.RENV_PATHS_ROOT }}
|
path: ${{ env.RENV_PATHS_ROOT }}
|
||||||
key: ${{ steps.get-version.outputs.os-version }}-${{ steps.get-version.outputs.r-version }}-${{ inputs.cache-version }}-${{ hashFiles('renv.lock') }}
|
key: ${{ steps.get-version.outputs.os-version }}-${{ steps.get-version.outputs.r-version }}-${{ inputs.cache-version }}-${{ hashFiles('renv.lock') }}
|
||||||
|
@ -588,7 +610,7 @@ whenever possible:
|
||||||
## Rust - Cargo
|
## Rust - Cargo
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/bin/
|
~/.cargo/bin/
|
||||||
|
@ -603,7 +625,7 @@ whenever possible:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache SBT
|
- name: Cache SBT
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.ivy2/cache
|
~/.ivy2/cache
|
||||||
|
@ -614,7 +636,7 @@ whenever possible:
|
||||||
## Swift, Objective-C - Carthage
|
## Swift, Objective-C - Carthage
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: Carthage
|
path: Carthage
|
||||||
key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
|
key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
|
||||||
|
@ -625,7 +647,7 @@ whenever possible:
|
||||||
## Swift, Objective-C - CocoaPods
|
## Swift, Objective-C - CocoaPods
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: Pods
|
path: Pods
|
||||||
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
|
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
|
||||||
|
@ -636,7 +658,7 @@ whenever possible:
|
||||||
## Swift - Swift Package Manager
|
## Swift - Swift Package Manager
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: .build
|
path: .build
|
||||||
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
|
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
|
||||||
|
@ -651,7 +673,7 @@ env:
|
||||||
MINT_PATH: .mint/lib
|
MINT_PATH: .mint/lib
|
||||||
MINT_LINK_PATH: .mint/bin
|
MINT_LINK_PATH: .mint/bin
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: .mint
|
path: .mint
|
||||||
key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
|
key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
|
||||||
|
@ -667,7 +689,7 @@ steps:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache Bazel
|
- name: Cache Bazel
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cache/bazel
|
~/.cache/bazel
|
||||||
|
@ -681,7 +703,7 @@ steps:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache Bazel
|
- name: Cache Bazel
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
/private/var/tmp/_bazel_runner/
|
/private/var/tmp/_bazel_runner/
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"version": "3.3.1",
|
"version": "4.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Cache dependencies and build outputs",
|
"description": "Cache dependencies and build outputs",
|
||||||
"main": "dist/restore/index.js",
|
"main": "dist/restore/index.js",
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^3.2.1",
|
"@actions/cache": "^3.2.3",
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/io": "^1.1.2"
|
"@actions/io": "^1.1.2"
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
"@types/node": "^16.18.3",
|
"@types/node": "^16.18.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
"@typescript-eslint/parser": "^5.45.0",
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
"@zeit/ncc": "^0.20.5",
|
"@vercel/ncc": "^0.38.1",
|
||||||
"eslint": "^8.28.0",
|
"eslint": "^8.28.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
|
|
|
@ -35,9 +35,9 @@ If you are using separate jobs to create and save your cache(s) to be reused by
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache/restore@v3
|
- uses: actions/cache/restore@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -64,12 +64,12 @@ In case of multi-module projects, where the built artifact of one project needs
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: /build-parent-module.sh
|
run: /build-parent-module.sh
|
||||||
|
|
||||||
- uses: actions/cache/save@v3
|
- uses: actions/cache/save@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -80,9 +80,9 @@ steps:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache/restore@v3
|
- uses: actions/cache/restore@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -107,9 +107,9 @@ To fail if there is no cache hit for the primary key, leave `restore-keys` empty
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache/restore@v3
|
- uses: actions/cache/restore@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
|
|
@ -9,7 +9,7 @@ inputs:
|
||||||
description: 'An explicit key for restoring the cache'
|
description: 'An explicit key for restoring the cache'
|
||||||
required: true
|
required: true
|
||||||
restore-keys:
|
restore-keys:
|
||||||
description: 'An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
|
description: 'An ordered multiline string listing the prefix-matched keys, that are used for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
|
||||||
required: false
|
required: false
|
||||||
enableCrossOsArchive:
|
enableCrossOsArchive:
|
||||||
description: 'An optional boolean when enabled, allows windows runners to restore caches that were saved on other platforms'
|
description: 'An optional boolean when enabled, allows windows runners to restore caches that were saved on other platforms'
|
||||||
|
@ -31,7 +31,7 @@ outputs:
|
||||||
cache-matched-key:
|
cache-matched-key:
|
||||||
description: 'Key of the cache that was restored, it could either be the primary key on cache-hit or a partial/complete match of one of the restore keys'
|
description: 'Key of the cache that was restored, it could either be the primary key on cache-hit or a partial/complete match of one of the restore keys'
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node20'
|
||||||
main: '../dist/restore-only/index.js'
|
main: '../dist/restore-only/index.js'
|
||||||
branding:
|
branding:
|
||||||
icon: 'archive'
|
icon: 'archive'
|
||||||
|
|
|
@ -23,7 +23,7 @@ If you are using separate jobs for generating common artifacts and sharing them
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: /install.sh
|
run: /install.sh
|
||||||
|
@ -31,7 +31,7 @@ steps:
|
||||||
- name: Build artifacts
|
- name: Build artifacts
|
||||||
run: /build.sh
|
run: /build.sh
|
||||||
|
|
||||||
- uses: actions/cache/save@v3
|
- uses: actions/cache/save@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: path/to/dependencies
|
path: path/to/dependencies
|
||||||
|
@ -47,7 +47,7 @@ Let's say we have a restore step that computes a key at runtime.
|
||||||
#### Restore a cache
|
#### Restore a cache
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v4
|
||||||
id: restore-cache
|
id: restore-cache
|
||||||
with:
|
with:
|
||||||
key: cache-${{ hashFiles('**/lockfiles') }}
|
key: cache-${{ hashFiles('**/lockfiles') }}
|
||||||
|
@ -55,7 +55,7 @@ with:
|
||||||
|
|
||||||
#### Case 1 - Where a user would want to reuse the key as it is
|
#### Case 1 - Where a user would want to reuse the key as it is
|
||||||
```yaml
|
```yaml
|
||||||
uses: actions/cache/save@v3
|
uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
|
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
|
||||||
```
|
```
|
||||||
|
@ -63,26 +63,52 @@ with:
|
||||||
#### Case 2 - Where the user would want to re-evaluate the key
|
#### Case 2 - Where the user would want to re-evaluate the key
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: actions/cache/save@v3
|
uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
key: npm-cache-${{hashfiles(package-lock.json)}}
|
key: npm-cache-${{hashfiles(package-lock.json)}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Always save cache
|
### Always save cache
|
||||||
|
|
||||||
There are instances where some flaky test cases would fail the entire workflow and users would get frustrated because the builds would run for hours and the cache couldn't be saved as the workflow failed in between. For such use-cases, users now have the ability to use the `actions/cache/save` action to save the cache by using an `if: always()` condition. This way the cache will always be saved if generated, or a warning will be generated that nothing is found on the cache path. Users can also use the `if` condition to only execute the `actions/cache/save` action depending on the output of previous steps. This way they get more control of when to save the cache.
|
There are instances where some flaky test cases would fail the entire workflow and users would get frustrated because the builds would run for hours and the cache couldn't be saved as the workflow failed in between.
|
||||||
|
For such use-cases, users now have the ability to use the `actions/cache/save` action to save the cache by using an [`always()`](https://docs.github.com/actions/writing-workflows/choosing-what-your-workflow-does/expressions#always) condition.
|
||||||
|
This way the cache will always be saved if generated, or a warning will be generated that nothing is found on the cache path. Users can also use the `if` condition to only execute the `actions/cache/save` action depending on the output of previous steps. This way they get more control of when to save the cache.
|
||||||
|
|
||||||
|
To avoid saving a cache that already exists, the `cache-hit` output from a restore step should be checked.
|
||||||
|
|
||||||
|
The `cache-primary-key` output from the restore step should also be used to ensure
|
||||||
|
the cache key does not change during the build if it's calculated based on file contents.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
name: Always Caching Primes
|
||||||
- uses: actions/checkout@v3
|
|
||||||
.
|
on: push
|
||||||
. // restore if need be
|
|
||||||
.
|
jobs:
|
||||||
- name: Build
|
build:
|
||||||
run: /build.sh
|
runs-on: ubuntu-latest
|
||||||
- uses: actions/cache/save@v3
|
|
||||||
if: always() // or any other condition to invoke the save action
|
steps:
|
||||||
with:
|
- uses: actions/checkout@v4
|
||||||
path: path/to/dependencies
|
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
- name: Restore cached Primes
|
||||||
|
id: cache-primes-restore
|
||||||
|
uses: actions/cache/restore@v4
|
||||||
|
with:
|
||||||
|
key: ${{ runner.os }}-primes
|
||||||
|
path: |
|
||||||
|
path/to/dependencies
|
||||||
|
some/other/dependencies
|
||||||
|
|
||||||
|
# Intermediate workflow steps
|
||||||
|
|
||||||
|
- name: Always Save Primes
|
||||||
|
id: cache-primes-save
|
||||||
|
if: always() && steps.cache-primes-restore.outputs.cache-hit != 'true'
|
||||||
|
uses: actions/cache/save@v4
|
||||||
|
with:
|
||||||
|
key: ${{ steps.cache-primes-restore.outputs.cache-primary-key }}
|
||||||
|
path: |
|
||||||
|
path/to/dependencies
|
||||||
|
some/other/dependencies
|
||||||
```
|
```
|
||||||
|
|
|
@ -16,7 +16,7 @@ inputs:
|
||||||
default: 'false'
|
default: 'false'
|
||||||
required: false
|
required: false
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node20'
|
||||||
main: '../dist/save-only/index.js'
|
main: '../dist/save-only/index.js'
|
||||||
branding:
|
branding:
|
||||||
icon: 'archive'
|
icon: 'archive'
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
import restoreImpl from "./restoreImpl";
|
import { restoreRun } from "./restoreImpl";
|
||||||
import { StateProvider } from "./stateProvider";
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
restoreRun(true);
|
||||||
await restoreImpl(new StateProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
|
||||||
export default run;
|
|
||||||
|
|
|
@ -2,11 +2,16 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, Inputs, Outputs, State } from "./constants";
|
import { Events, Inputs, Outputs, State } from "./constants";
|
||||||
import { IStateProvider } from "./stateProvider";
|
import {
|
||||||
|
IStateProvider,
|
||||||
|
NullStateProvider,
|
||||||
|
StateProvider
|
||||||
|
} from "./stateProvider";
|
||||||
import * as utils from "./utils/actionUtils";
|
import * as utils from "./utils/actionUtils";
|
||||||
|
|
||||||
async function restoreImpl(
|
export async function restoreImpl(
|
||||||
stateProvider: IStateProvider
|
stateProvider: IStateProvider,
|
||||||
|
earlyExit?: boolean | undefined
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
try {
|
try {
|
||||||
if (!utils.isCacheFeatureAvailable()) {
|
if (!utils.isCacheFeatureAvailable()) {
|
||||||
|
@ -46,6 +51,9 @@ async function restoreImpl(
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!cacheKey) {
|
if (!cacheKey) {
|
||||||
|
// `cache-hit` is intentionally not set to `false` here to preserve existing behavior
|
||||||
|
// See https://github.com/actions/cache/issues/1466
|
||||||
|
|
||||||
if (failOnCacheMiss) {
|
if (failOnCacheMiss) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${primaryKey}`
|
`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${primaryKey}`
|
||||||
|
@ -57,7 +65,6 @@ async function restoreImpl(
|
||||||
...restoreKeys
|
...restoreKeys
|
||||||
].join(", ")}`
|
].join(", ")}`
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +86,36 @@ async function restoreImpl(
|
||||||
return cacheKey;
|
return cacheKey;
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
core.setFailed((error as Error).message);
|
core.setFailed((error as Error).message);
|
||||||
|
if (earlyExit) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default restoreImpl;
|
async function run(
|
||||||
|
stateProvider: IStateProvider,
|
||||||
|
earlyExit: boolean | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
await restoreImpl(stateProvider, earlyExit);
|
||||||
|
|
||||||
|
// node will stay alive if any promises are not resolved,
|
||||||
|
// which is a possibility if HTTP requests are dangling
|
||||||
|
// due to retries or timeouts. We know that if we got here
|
||||||
|
// that all promises that we care about have successfully
|
||||||
|
// resolved, so simply exit with success.
|
||||||
|
if (earlyExit) {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function restoreOnlyRun(
|
||||||
|
earlyExit?: boolean | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
await run(new NullStateProvider(), earlyExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function restoreRun(
|
||||||
|
earlyExit?: boolean | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
await run(new StateProvider(), earlyExit);
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
import restoreImpl from "./restoreImpl";
|
import { restoreOnlyRun } from "./restoreImpl";
|
||||||
import { NullStateProvider } from "./stateProvider";
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
restoreOnlyRun(true);
|
||||||
await restoreImpl(new NullStateProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
|
||||||
export default run;
|
|
||||||
|
|
11
src/save.ts
11
src/save.ts
|
@ -1,10 +1,3 @@
|
||||||
import saveImpl from "./saveImpl";
|
import { saveRun } from "./saveImpl";
|
||||||
import { StateProvider } from "./stateProvider";
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
saveRun(true);
|
||||||
await saveImpl(new StateProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
|
||||||
export default run;
|
|
||||||
|
|
|
@ -2,7 +2,11 @@ import * as cache from "@actions/cache";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
import { Events, Inputs, State } from "./constants";
|
import { Events, Inputs, State } from "./constants";
|
||||||
import { IStateProvider } from "./stateProvider";
|
import {
|
||||||
|
IStateProvider,
|
||||||
|
NullStateProvider,
|
||||||
|
StateProvider
|
||||||
|
} from "./stateProvider";
|
||||||
import * as utils from "./utils/actionUtils";
|
import * as utils from "./utils/actionUtils";
|
||||||
|
|
||||||
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
||||||
|
@ -10,7 +14,9 @@ import * as utils from "./utils/actionUtils";
|
||||||
// throw an uncaught exception. Instead of failing this action, just warn.
|
// throw an uncaught exception. Instead of failing this action, just warn.
|
||||||
process.on("uncaughtException", e => utils.logWarning(e.message));
|
process.on("uncaughtException", e => utils.logWarning(e.message));
|
||||||
|
|
||||||
async function saveImpl(stateProvider: IStateProvider): Promise<number | void> {
|
export async function saveImpl(
|
||||||
|
stateProvider: IStateProvider
|
||||||
|
): Promise<number | void> {
|
||||||
let cacheId = -1;
|
let cacheId = -1;
|
||||||
try {
|
try {
|
||||||
if (!utils.isCacheFeatureAvailable()) {
|
if (!utils.isCacheFeatureAvailable()) {
|
||||||
|
@ -72,4 +78,47 @@ async function saveImpl(stateProvider: IStateProvider): Promise<number | void> {
|
||||||
return cacheId;
|
return cacheId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default saveImpl;
|
export async function saveOnlyRun(
|
||||||
|
earlyExit?: boolean | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
const cacheId = await saveImpl(new NullStateProvider());
|
||||||
|
if (cacheId === -1) {
|
||||||
|
core.warning(`Cache save failed.`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
if (earlyExit) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// node will stay alive if any promises are not resolved,
|
||||||
|
// which is a possibility if HTTP requests are dangling
|
||||||
|
// due to retries or timeouts. We know that if we got here
|
||||||
|
// that all promises that we care about have successfully
|
||||||
|
// resolved, so simply exit with success.
|
||||||
|
if (earlyExit) {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveRun(earlyExit?: boolean | undefined): Promise<void> {
|
||||||
|
try {
|
||||||
|
await saveImpl(new StateProvider());
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
if (earlyExit) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// node will stay alive if any promises are not resolved,
|
||||||
|
// which is a possibility if HTTP requests are dangling
|
||||||
|
// due to retries or timeouts. We know that if we got here
|
||||||
|
// that all promises that we care about have successfully
|
||||||
|
// resolved, so simply exit with success.
|
||||||
|
if (earlyExit) {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,3 @@
|
||||||
import * as core from "@actions/core";
|
import { saveOnlyRun } from "./saveImpl";
|
||||||
|
|
||||||
import saveImpl from "./saveImpl";
|
saveOnlyRun(true);
|
||||||
import { NullStateProvider } from "./stateProvider";
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
|
||||||
const cacheId = await saveImpl(new NullStateProvider());
|
|
||||||
if (cacheId === -1) {
|
|
||||||
core.warning(`Cache save failed.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
|
||||||
export default run;
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ A cache today is immutable and cannot be updated. But some use cases require the
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: update cache on every commit
|
- name: update cache on every commit
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: prime-numbers
|
path: prime-numbers
|
||||||
key: primes-${{ runner.os }}-${{ github.run_id }} # Can use time based key as well
|
key: primes-${{ runner.os }}-${{ github.run_id }} # Can use time based key as well
|
||||||
|
@ -61,7 +61,7 @@ jobs:
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cleanup
|
- name: Cleanup
|
||||||
run: |
|
run: |
|
||||||
|
|
Loading…
Reference in New Issue