Skip to content

actions/cache key is not only about exact match #14145

Closed
@Totktonada

Description

@Totktonada

Code of Conduct

What article on docs.github.com is affected?

https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows#matching-a-cache-key

What part(s) of the article would you like to see updated?

The documentation provides description of key and restore-keys fields. The actual behaviour is the following:

  1. If key match existing cache entry exactly, the cache is restored and cache-hit output value is set to 'true'.
  2. If key match a prefix of an existing cache entry, the cache is restored and cache-hit output value is set to ''.

The latter is not obvious from the documentation. To be honest, I would even say that the article reads like it works in the opposite way.

The reason why I misunderstood the documentation is the following. The description of the key does not say anything about exact/prefix match. It also say that match is called 'cache hit', so, I guess, it is when cache-hit is set to 'true': exact match.

Next, restore-keys description differentiates 'exact match' and 'partial match' (prefix match in fact). So my guess was that if key would behave this way, it would be described as the common behaviour of both fields. Now it looks like a highlight that restore-keys works differenctly from key, but that's not so.

I would also highlight that cache-hit value is not described. It is quite non-obvious that a cache may be restored, but the output value will give '', because it is not exact match.

Additional information

One can verify the behaviour youself. Let's create a workflow file with the following content and push it to a branch:

name: Test cache

on: [push]

jobs:
  test_cache:
    env:
      CACHE_KEY: my-cache-key-v1-draft
    runs-on: ubuntu-latest
    steps:
      - name: Cache file
        uses: actions/cache@v2
        id: cache
        with:
          path: cached_file
          key: ${{ env.CACHE_KEY }}

      - name: Generate file
        run: |
          [ ! -f cached_file ]  # should never give an error
          printf 'CACHE_KEY: %s\n' "${{ env.CACHE_KEY }}" > cached_file
        if: steps.cache.outputs.cache-hit != 'true'

      - name: Show file
        run: |
          cat cached_file

Next, change the cache key:

diff --git a/.github/workflows/test_cache.yml b/.github/workflows/test_cache.yml
index 5a0f6d4..a3d448e 100644
--- a/.github/workflows/test_cache.yml
+++ b/.github/workflows/test_cache.yml
@@ -5,7 +5,7 @@ on: [push]
 jobs:
   test_cache:
     env:
-      CACHE_KEY: my-cache-key-v1-draft
+      CACHE_KEY: my-cache-key-v1
     runs-on: ubuntu-latest
     steps:
       - name: Cache file

And push it to a branch. What will occur? The cache will be restored from my-cache-key-v1-draft, steps.cache.outputs.cache-hit will be '', so we'll run the 'Generate file' step and get a failure.

In fact, we made two mistakes here:

  1. Assume that key is about exact match.
  2. Assume that if cache restore occurs it means that cache-hit will be 'true'.

Those pitfalls should at least be highlighted in the documentation. However, to be honest, those are good candidates to revisit in a next major version of the action.


Content Plan

Guidance here

Metadata

Metadata

Assignees

No one assigned

    Labels

    actionsThis issue or pull request should be reviewed by the docs actions teamcontentThis issue or pull request belongs to the Docs Content teamhelp wantedAnyone is welcome to open a pull request to fix this issuepumpkin-spiceSpecifically tracked Hacktoberfest issue - internal purposes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions