1
0
Fork 0
mirror of https://code.forgejo.org/actions/cache.git synced 2024-10-16 22:24:41 +02:00

Merge branch 'main' into neo-cache-service

This commit is contained in:
Bassem Dghaidi 2024-10-09 07:47:18 -07:00 committed by GitHub
commit 7cd4aa68d3
17 changed files with 191 additions and 127 deletions

View file

@ -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

View file

@ -17,7 +17,6 @@ See ["Caching dependencies to speed up workflows"](https://docs.github.com/en/ac
### v4 ### v4
* Updated to node 20 * Updated to node 20
* Added a `save-always` flag to save the cache even if a prior step fails
### v3 ### v3
@ -54,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`
@ -65,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
@ -158,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)

View file

@ -1,5 +1,12 @@
# Releases # Releases
### 4.1.1
- Restore original behavior of `cache-hit` output - [#1467](https://github.com/actions/cache/pull/1467)
### 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)
### 4.0.2 ### 4.0.2
- Fixed restore `fail-on-cache-miss` not working. - Fixed restore `fail-on-cache-miss` not working.

View file

@ -260,7 +260,7 @@ test("Fail restore when fail on cache miss is enabled and primary + restore keys
); );
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); expect(setCacheHitOutputMock).toHaveBeenCalledTimes(0);
expect(failedMock).toHaveBeenCalledWith( expect(failedMock).toHaveBeenCalledWith(
`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${key}` `Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${key}`

View file

@ -86,8 +86,7 @@ test("restore with no cache found", async () => {
); );
expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key); expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key);
expect(outputMock).toHaveBeenCalledWith("cache-hit", "false"); expect(outputMock).toHaveBeenCalledTimes(1);
expect(outputMock).toHaveBeenCalledTimes(2);
expect(failedMock).toHaveBeenCalledTimes(0); expect(failedMock).toHaveBeenCalledTimes(0);
expect(infoMock).toHaveBeenCalledWith( expect(infoMock).toHaveBeenCalledWith(

View file

@ -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'
@ -29,7 +29,11 @@ inputs:
save-always: save-always:
description: 'Run the post step to save the cache even if another step before fails' description: 'Run the post step to save the cache even if another step before fails'
default: 'false' default: 'false'
required: 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'
@ -37,7 +41,7 @@ runs:
using: 'node20' 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() || github.event.inputs.save-always" post-if: "success()"
branding: branding:
icon: 'archive' icon: 'archive'
color: 'gray-dark' color: 'gray-dark'

View file

@ -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

View file

@ -137184,7 +137184,8 @@ function restoreImpl(stateProvider, earlyExit) {
const lookupOnly = utils.getInputAsBool(constants_1.Inputs.LookupOnly); const lookupOnly = utils.getInputAsBool(constants_1.Inputs.LookupOnly);
const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys, { lookupOnly: lookupOnly }, enableCrossOsArchive); const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys, { lookupOnly: lookupOnly }, enableCrossOsArchive);
if (!cacheKey) { if (!cacheKey) {
core.setOutput(constants_1.Outputs.CacheHit, false.toString()); // `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(`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${primaryKey}`); throw new Error(`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${primaryKey}`);
} }

View file

@ -137184,7 +137184,8 @@ function restoreImpl(stateProvider, earlyExit) {
const lookupOnly = utils.getInputAsBool(constants_1.Inputs.LookupOnly); const lookupOnly = utils.getInputAsBool(constants_1.Inputs.LookupOnly);
const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys, { lookupOnly: lookupOnly }, enableCrossOsArchive); const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys, { lookupOnly: lookupOnly }, enableCrossOsArchive);
if (!cacheKey) { if (!cacheKey) {
core.setOutput(constants_1.Outputs.CacheHit, false.toString()); // `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(`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${primaryKey}`); throw new Error(`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${primaryKey}`);
} }

View file

@ -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') }}
@ -518,7 +539,7 @@ jobs:
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') }}
@ -536,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') }}
@ -563,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') }}
@ -589,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/
@ -604,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
@ -615,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') }}
@ -626,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') }}
@ -637,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') }}
@ -652,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') }}
@ -668,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
@ -682,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/

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "cache", "name": "cache",
"version": "4.0.2", "version": "4.1.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cache", "name": "cache",
"version": "4.0.2", "version": "4.1.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "file:/workspaces/toolkit/packages/cache", "@actions/cache": "file:/workspaces/toolkit/packages/cache",

View file

@ -1,6 +1,6 @@
{ {
"name": "cache", "name": "cache",
"version": "4.0.2", "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",

View file

@ -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

View file

@ -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'

View file

@ -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
``` ```

View file

@ -50,7 +50,9 @@ export async function restoreImpl(
); );
if (!cacheKey) { if (!cacheKey) {
core.setOutput(Outputs.CacheHit, false.toString()); // `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}`

View file

@ -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: |