cache/examples.md at main · actions/cache

GitHub

Bun

C# - NuGet

Clojure - Lein Deps

D - DUB

POSIX

Windows

Deno

Linux

macOS

Windows

Elixir - Mix

Erlang - Rebar3

Go - Modules

Linux

macOS

Windows

Haskell - Cabal

Haskell - Stack

Java - Gradle

Java - Maven

Node - npm

Node - Lerna

Node - Yarn

Node - Yarn 2

OCaml/Reason - esy

PHP - Composer

Python - pip

Simple example

Multiple OS's in a workflow

Multiple OS's in a workflow with a matrix

Using pip to get cache location

Python - pipenv

R - renv

Ruby - Bundler

Rust - Cargo

Scala - SBT

Swift, Objective-C - Carthage

Swift, Objective-C - CocoaPods

Swift - Swift Package Manager

Swift - Mint

* - Bazel

Bun

- uses: actions/cache@v6with: path: | ~/.bun/install/cachekey: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}Windows

- uses: actions/cache@v6with: path: | ~\.bunkey: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}C# - NuGet

Using

NuGet lock files

:

- uses: actions/cache@v6with: path: ~/.nuget/packageskey: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}restore-keys: | ${{ runner.os }}-nuget-Depending on the environment, huge packages might be pre-installed in the global cache folder. From actions/cache@v3 onwards, you can now exclude unwanted packages with

exclude pattern

- uses: actions/cache@v6with: path: | ~/.nuget/packages !~/.nuget/packages/unwantedkey: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}restore-keys: | ${{ runner.os }}-nuget-Or you could move the cache folder like below.

Note This workflow does not work for projects that require files to be placed in user profile package folder

env: NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packagessteps: - uses: actions/cache@v6with: path: ${{ github.workspace }}/.nuget/packageskey: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}restore-keys: | ${{ runner.os }}-nuget-Clojure - Lein Deps

- name: Cache lein project dependenciesuses: actions/cache@v6with: path: ~/.m2/repositorykey: ${{ runner.os }}-clojure-${{ hashFiles('**/project.clj') }}restore-keys: | ${{ runner.os }}-clojureD - DUB

POSIX

- uses: actions/cache@v6with: path: ~/.dubkey: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}restore-keys: | ${{ runner.os }}-dub-Windows

- uses: actions/cache@v6with: path: ~\AppData\Local\dubkey: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}restore-keys: | ${{ runner.os }}-dub-Deno

Linux

- uses: actions/cache@v6with: path: | ~/.deno ~/.cache/denokey: ${{ runner.os }}-deno-${{ hashFiles('**/deps.ts') }}macOS

- uses: actions/cache@v6with: path: | ~/.deno ~/Library/Caches/denokey: ${{ runner.os }}-deno-${{ hashFiles('**/deps.ts') }}Windows

- uses: actions/cache@v6with: path: | ~\.deno ~\AppData\Local\denokey: ${{ runner.os }}-deno-${{ hashFiles('**/deps.ts') }}Elixir - Mix

- uses: actions/cache@v6with: path: | deps _buildkey: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}restore-keys: | ${{ runner.os }}-mix-Erlang - Rebar3

- uses: actions/cache@v6with: path: | ~/.cache/rebar3 _buildkey: ${{ runner.os }}-erlang-${{ env.OTP_VERSION }}-${{ hashFiles('**/*rebar.lock') }}restore-keys: | ${{ runner.os }}-erlang-${{ env.OTP_VERSION }}-Go - Modules

Linux

- uses: actions/cache@v6with: path: | ~/.cache/go-build ~/go/pkg/modkey: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}restore-keys: | ${{ runner.os }}-go-macOS

- uses: actions/cache@v6with: path: | ~/Library/Caches/go-build ~/go/pkg/modkey: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}restore-keys: | ${{ runner.os }}-go-Windows

- uses: actions/cache@v6with: path: | ~\AppData\Local\go-build ~\go\pkg\modkey: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}restore-keys: | ${{ runner.os }}-go-Haskell - Cabal

We cache the elements of the Cabal store separately, as the entirety of ~/.cabal can grow very large for projects with many dependencies.

- name: Cache ~/.cabal/packages, ~/.cabal/store and dist-newstyleuses: actions/cache@v6with: path: | ~/.cabal/packages ~/.cabal/store dist-newstylekey: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/*.cabal', '**/cabal.project', '**/cabal.project.freeze') }}restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-Haskell - Stack

Linux or macOS

- uses: actions/cache@v6name: Cache ~/.stackwith: path: ~/.stackkey: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}restore-keys: | ${{ runner.os }}-stack-global-- uses: actions/cache@v6name: Cache .stack-workwith: path: .stack-workkey: ${{ runner.os }}-stack-work-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}-${{ hashFiles('**/*.hs') }}restore-keys: | ${{ runner.os }}-stack-work-Windows

- uses: actions/cache@v6name: Cache %APPDATA%\stack %LOCALAPPDATA%\Programs\stackwith: path: | ~\AppData\Roaming\stack ~\AppData\Local\Programs\stackkey: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}restore-keys: | ${{ runner.os }}-stack-global-- uses: actions/cache@v6name: Cache .stack-workwith: path: .stack-workkey: ${{ runner.os }}-stack-work-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}-${{ hashFiles('**/*.hs') }}restore-keys: | ${{ runner.os }}-stack-work-Java - Gradle

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

on how to disable or stop the Gradle Daemons.

- uses: actions/cache@v6with: path: | ~/.gradle/caches ~/.gradle/wrapperkey: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}restore-keys: | ${{ runner.os }}-gradle-Java - Maven

- name: Cache local Maven repositoryuses: actions/cache@v6with: path: ~/.m2/repositorykey: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}restore-keys: | ${{ runner.os }}-maven-Node - npm

For npm, cache files are stored in ~/.npm on Posix, or ~\AppData\npm-cache on Windows, but it's possible to use npm config get cache to find the path on any platform. See

the npm docs

for more details.

If using npm config to retrieve the cache directory, ensure you run

actions/setup-node

first to ensure your npm version is correct. After

deprecation

of save-state and set-output commands, the correct way to set output is using ${GITHUB_OUTPUT}. For linux, we can use ${GITHUB_OUTPUT} whereas for windows we need to use ${env:GITHUB_OUTPUT} due to two different default shells in these two different OS ie bash and pwsh respectively.

Note It is not recommended to cache node_modules, as it can break across Node versions and won't work with npm ci

Get npm cache directory using same shell

Bash shell

- name: Get npm cache directoryid: npm-cache-dirshell: bashrun: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}PWSH shell

- name: Get npm cache directoryid: npm-cache-dirshell: pwshrun: echo "dir=$(npm config get cache)" >> ${env:GITHUB_OUTPUT}Get npm cache directory step can then be used with actions/cache as shown below

- uses: actions/cache@v6id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'with: path: ${{ steps.npm-cache-dir.outputs.dir }}key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}restore-keys: | ${{ runner.os }}-node-Node - Lerna

- name: restore lernauses: actions/cache@v6with: path: '**/node_modules'key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}Node - Yarn

The yarn cache directory will depend on your operating system and version of yarn. See

https://yarnpkg.com/lang/en/docs/cli/cache/

for more info.

- name: Get yarn cache directory pathid: yarn-cache-dir-pathrun: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - uses: actions/cache@v6id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)with: path: ${{ steps.yarn-cache-dir-path.outputs.dir }}key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}restore-keys: | ${{ runner.os }}-yarn-Node - Yarn 2

The yarn 2 cache directory will depend on your config. See

https://yarnpkg.com/configuration/yarnrc#cacheFolder

for more info.

- name: Get yarn cache directory pathid: yarn-cache-dir-pathrun: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT - uses: actions/cache@v6id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)with: path: ${{ steps.yarn-cache-dir-path.outputs.dir }}key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}restore-keys: | ${{ runner.os }}-yarn-OCaml/Reason - esy

Esy allows you to export built dependencies and import pre-built dependencies.

- name: Restore Cacheid: restore-cacheuses: actions/cache@v6with: path: _exportkey: ${{ runner.os }}-esy-${{ hashFiles('esy.lock/index.json') }}restore-keys: | ${{ runner.os }}-esy- - name: Esy installrun: 'esy install' - name: Import Cacherun: | esy import-dependencies _export rm -rf _export...(Build job)...# Re-export dependencies if anything has changed or if it is the first time - name: Setting dependency cacherun: | esy export-dependenciesif: steps.restore-cache.outputs.cache-hit != 'true'PHP - Composer

- name: Get Composer Cache Directoryid: composer-cacherun: | echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT- uses: actions/cache@v6with: path: ${{ steps.composer-cache.outputs.dir }}key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}restore-keys: | ${{ runner.os }}-composer-Python - pip

For pip, the cache directory will vary by OS. See

https://pip.pypa.io/en/stable/reference/pip_install/#caching

Locations:

Ubuntu: ~/.cache/pip

Windows: ~\AppData\Local\pip\Cache

macOS: ~/Library/Caches/pip

Simple example

- uses: actions/cache@v6with: path: ~/.cache/pipkey: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}restore-keys: | ${{ runner.os }}-pip-Replace ~/.cache/pip with the correct path if not using Ubuntu.

Multiple OS's in a workflow

- uses: actions/cache@v6if: startsWith(runner.os, 'Linux')with: path: ~/.cache/pipkey: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}restore-keys: | ${{ runner.os }}-pip-- uses: actions/cache@v6if: startsWith(runner.os, 'macOS')with: path: ~/Library/Caches/pipkey: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}restore-keys: | ${{ runner.os }}-pip-- uses: actions/cache@v6if: startsWith(runner.os, 'Windows')with: path: ~\AppData\Local\pip\Cachekey: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}restore-keys: | ${{ runner.os }}-pip-Multiple OS's in a workflow with a matrix

jobs: build: runs-on: ${{ matrix.os }}strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest]include: - os: ubuntu-latestpath: ~/.cache/pip - os: macos-latestpath: ~/Library/Caches/pip - os: windows-latestpath: ~\AppData\Local\pip\Cachesteps: - uses: actions/cache@v6with: path: ${{ matrix.path }}key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}restore-keys: | ${{ runner.os }}-pip-Using pip to get cache location

Note This requires pip 20.1+

- name: Get pip cache dirid: pip-cacheshell: bashrun: | echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT- name: pip cacheuses: actions/cache@v6with: path: ${{ steps.pip-cache.outputs.dir }}key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}restore-keys: | ${{ runner.os }}-pip-Python - pipenv

- name: Set up Python# The actions/cache step below uses this id to get the exact python versionid: setup-pythonuses: actions/setup-python@v6⋮ - uses: actions/cache@v6with: path: ~/.local/share/virtualenvskey: ${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-pipenv-${{ hashFiles('Pipfile.lock') }}R - renv

For renv, the cache directory will vary by OS. The RENV_PATHS_ROOT environment variable is used to set the cache location. Have a look at

https://rstudio.github.io/renv/reference/paths.html#details

for more details.

- name: Set RENV_PATHS_ROOTshell: bashrun: | echo "RENV_PATHS_ROOT=${{ runner.temp }}/renv" >> $GITHUB_ENV- name: Install and activate renvrun: | install.packages("renv") renv::activate()shell: Rscript {0} - name: Get R and OS versionid: get-versionrun: | cat("##[set-output name=os-version;]", sessionInfo()$running, "\n", sep = "") cat("##[set-output name=r-version;]", R.Version()$version.string, sep = "")shell: Rscript {0} - name: Restore Renv package cacheuses: actions/cache@v6with: path: ${{ env.RENV_PATHS_ROOT }}key: ${{ steps.get-version.outputs.os-version }}-${{ steps.get-version.outputs.r-version }}-${{ inputs.cache-version }}-${{ hashFiles('renv.lock') }}restore-keys: ${{ steps.get-version.outputs.os-version }}-${{ steps.get-version.outputs.r-version }}-${{inputs.cache-version }}-Ruby - Bundler

Caching gems with Bundler correctly is not trivial and just using actions/cache is

not enough

.

Instead, it is recommended to use ruby/setup-ruby's

bundler-cache: true option

whenever possible:

- uses: ruby/setup-ruby@v1with: ruby-version: ...bundler-cache: trueRust - Cargo

- uses: actions/cache@v6with: path: | ~/.cargo/bin/ ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}Scala - SBT

- name: Cache SBTuses: actions/cache@v6with: path: | ~/.ivy2/cache ~/.sbtkey: ${{ runner.os }}-sbt-${{ hashFiles('**/build.sbt') }}Swift, Objective-C - Carthage

- uses: actions/cache@v6with: path: Carthagekey: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}restore-keys: | ${{ runner.os }}-carthage-Swift, Objective-C - CocoaPods

- uses: actions/cache@v6with: path: Podskey: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}restore-keys: | ${{ runner.os }}-pods-Swift - Swift Package Manager

- uses: actions/cache@v6with: path: .buildkey: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}restore-keys: | ${{ runner.os }}-spm-Swift - Mint

env: MINT_PATH: .mint/libMINT_LINK_PATH: .mint/binsteps: - uses: actions/cache@v6with: path: .mintkey: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}restore-keys: | ${{ runner.os }}-mint-* - Bazel

bazelisk

does not have be to separately downloaded and installed because it's already included in GitHub's ubuntu-latest and macos-latest base images.

Linux

- name: Cache Bazeluses: actions/cache@v6with: path: | ~/.cache/bazelkey: ${{ runner.os }}-bazel-${{ hashFiles('.bazelversion', '.bazelrc', 'WORKSPACE', 'WORKSPACE.bazel', 'MODULE.bazel') }}restore-keys: | ${{ runner.os }}-bazel-- run: bazelisk test //...macOS

- name: Cache Bazeluses: actions/cache@v6with: path: | /private/var/tmp/_bazel_runner/key: ${{ runner.os }}-bazel-${{ hashFiles('.bazelversion', '.bazelrc', 'WORKSPACE', 'WORKSPACE.bazel', 'MODULE.bazel') }}restore-keys: | ${{ runner.os }}-bazel-- run: bazelisk test //...