2

What is the correct placement of caching in a GitHub Action? Specifically is in correct to place it before or after running setup of tools using another Action?

For example if I'm using something like haskell/actions/setup should my use of actions/cache precede or follow that? Put another way: if setup subsequently installs updated components on a future run of my Action, will the corresponding parts of the cache be invalidated?

6
  • The example workflow shows that it is placed before your action. Commented Jul 18, 2021 at 7:09
  • @DannyB That example doesn’t show where caching goes wrt tools installation. Especially tools installation using another action. That’s the question. Commented Jul 18, 2021 at 10:35
  • The caching action is just copying a folder to a permanent place, based on the key. If you are using another action that creates/consumes cache, the cache action needs to either be integrated with it (like the ruby setup action is doing), or configured as explained in the linked example (or my answer). Commented Jul 18, 2021 at 11:54
  • @DannyB So in the case of something like haskell/actions/setup which is installing tools, caching goes after? Commented Jul 19, 2021 at 15:38
  • No, caching will always go before - the "after" part is happening automatically. Ideally, the authors of the haskell action can implement caching in their action, but if they don't, then all you need to do is understand which folder(s) you want to cache, and set up that caching action with that folder and appropriate key (probably one that uses the hashing function I mentioned on the haskell file that represents the list of dependencies). Commented Jul 19, 2021 at 15:48

1 Answer 1

4

The cache action should be placed before any step that consumes or creates that cache. This step is responsible for:

  1. defining cache parameters.
  2. restoring the cache, if it was cached in the past.

GitHub Actions will then run a "Post *" step after all the steps, which will store the cache for future calls.

See the example workflow from the documentation.

For example, consider this sample workflow:

name: Caching Test on: push jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Enable Cache id: cache-action uses: actions/cache@v2 with: path: cache-folder key: ${{ runner.os }}-cache-key - name: Use or generate the cache if: steps.cache-action.outputs.cache-hit != 'true' run: mkdir cache-folder && touch cache-folder/hello - name: Verify we have our cached file run: ls cache-folder 

This is how it looks on the first run: enter image description here

And this is how it looks on the second run: enter image description here

GitHub will not invalidate the cache. Instead, it is the responsibility of the developer to ensure that the cache key is unique to the content it represents.

On common way to do this, is to set the cache key so that it contains a hash of a file that lives in the repository, so that changes to this file, will yield a different cache key. A good example for such a behavior, is when you have lock files that list all your repository's dependencies (requirements.txt for pyrhon, Gemfile.lock for ruby, etc).

This is achieved by a syntax similar to this:

key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} 

as described in the Creating a cache key section of the documentation.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.