actions/cache

repository·main·Indexed 26 days ago

https://github.com/actions/cache

GitHub Action to cache dependencies and build outputs to reduce workflow execution time. Supports a primary cache action for combined restore and save operations, as well as granular actions/cache/restore and actions/cache/save for precise control. Features include support for hashFiles in keys, cross-OS caching on self-hosted Windows runners, and configurable eviction policies with a 10GB repository capacity limit.

Tokens
13.9K
Snippets
46
Records
63
Agent score
90%

What's inside actions/cache

  1. Fail the workflow on a cache miss

    main

    To restrict a workflow so that it only runs when a cache is successfully found, set fail-on-cache-miss: true. To ensure it only succeeds on an exact match for the primary key (and not a partial match), leave restore-keys empty.

    steps:
      - uses: actions/checkout@v6
    
      - uses: actions/cache/restore@v5
        id: cache
        with:
          path: path/to/dependencies
          key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
          fail-on-cache-miss: true
    
      - name: Build
        run: /build.sh
  2. Save cache with a re-evaluated key

    main

    If your build process generates new lockfiles, you should explicitly re-compute the key during the actions/cache/save step rather than reusing the restore key, to ensure the new state is captured correctly.

    # Case where the user re-evaluates the key during save
    uses: actions/cache/save@v6
    with:
        key: npm-cache-${{hashfiles(package-lock.json)}}
  3. Include arbitrary command output in a cache key

    main

    You can use the output of a previous step in your cache key. This is useful for incorporating dates or software versions into the key to manage cache rotation or specific environment states.

      # http://man7.org/linux/man-pages/man1/date.1.html
      - name: Get Date
        id: get-date
        run: |
          echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
        shell: bash
    
      - uses: actions/cache@v6
        with:
          path: path/to/dependencies
          key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/lockfiles') }}
  4. Always save cache even if workflow fails

    main

    To ensure caches are saved even when a workflow fails (e.g., due to flaky tests), use the always() condition in conjunction with actions/cache/save.

    To prevent overwriting an existing cache, you should also check that the cache-hit output from your restore step is not 'true'. It is recommended to use cache-primary-key from the restore step to ensure the key remains consistent if it was calculated based on file contents.

        - name: Always Save Prime Numbers
          id: cache-prime-numbers-save
          if: always() && steps.cache-prime-numbers-restore.outputs.cache-hit != 'true'
          uses: actions/cache/save@v5
          with:
            key: ${{ steps.cache-prime-numbers-restore.outputs.cache-primary-key }}
            path: |
              path/to/dependencies
              some/other/dependencies
  5. Configure paths for Windows environments

    main

    When using Windows runners, actions/cache does not expand Windows environment variables like %LocalAppData%. Instead, use the tilde ~ to expand to the HOME directory.

    Example: Use ~\AppData\Local instead of %LocalAppData%.

  6. Save intermediate private build artifacts

    main

    In multi-module projects, you can use actions/cache/save to store a built parent module artifact and actions/cache/restore to reuse it across child module builds. This prevents redundant rebuilding of the parent module.

    #### Step 1 - Build the parent module and save it
    
    ```yaml
    steps:
      - uses: actions/checkout@v6
    
      - name: Build
        run: /build-parent-module.sh
    
      - uses: actions/cache/save@v5
        id: cache
        with:
          path: path/to/dependencies
          key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}

    Step 2 - Restore the built artifact from cache

    steps:
      - uses: actions/checkout@v6
    
      - uses: actions/cache/restore@v5
        id: cache
        with:
          path: path/to/dependencies
          key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
    
      - name: Install Dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: /install.sh
    
      - name: Build
        run: /build-child-module.sh
    
      - name: Publish package to public
        run: /publish.sh
  7. Use restore-keys to download the closest matching cache

    main

    If an exact match for the key is not found, you can provide restore-keys to download the most recent cache that shares a common prefix. This allows the build process to fetch a partial cache and only download the incremental changes, saving significant time.

      - uses: actions/cache@v6
        with:
          path: |
            path/to/dependencies
            some/other/dependencies
          key: cache-npm-${{ hashFiles('**/lockfiles') }}
          restore-keys: |
            cache-npm-
  8. Create specialized or short-lived caches

    main

    You can scope caches to specific environments or workflow instances using GitHub Context variables:

    • By Operating System: Use ${{ runner.os }} to prevent cross-OS cache contamination.
    • By Workflow Run: Use ${{ github.run_id }}-${{ github.run_attempt }} for caches that only need to exist for a single run.
    • By Commit: Use ${{ github.sha }} for a highly specialized cache tied to a specific commit.
  9. Skip steps based on cache-hit

    main

    Use the cache-hit output to conditionally run steps. If a cache hit occurs, you can skip expensive operations like dependency installation.

    Important: The id assigned to actions/cache must match the ID used in the if condition (e.g., steps.[ID].outputs.cache-hit).

    steps:
      - uses: actions/checkout@v6
    
      - uses: actions/cache@v6
        id: cache
        with:
          path: path/to/dependencies
          key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
    
      - name: Install Dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: /install.sh
  10. Use the Save action to cache files

    main

    The actions/cache/save action allows you to save a cache at any stage of a workflow job, rather than waiting for the post-run phase. Unlike the main cache action, it does not attempt to restore a cache first; it only performs the upload. This is useful for granular control or when using separate jobs for artifact generation.

    steps:
      - uses: actions/checkout@v6
    
      - name: Install Dependencies
        run: /install.sh
    
      - name: Build artifacts
        run: /build.sh
    
      - uses: actions/cache/save@v5
        id: cache
        with:
          path: path/to/dependencies
          key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
  11. Configure cache keys for dependency updates

    main

    To ensure the cache is automatically updated whenever dependencies change, use a hash of your lockfile as part of the key. This ensures that a change in the lockfile results in a new cache key, triggering a fresh cache save.

      - uses: actions/cache@v6
        with:
          path: |
            path/to/dependencies
            some/other/dependencies
          key: cache-${{ hashFiles('**/lockfiles') }}
  12. Re-evaluate cache keys during saving

    main

    When using actions/cache/save, you can choose how the key is determined:

    1. Reuse the restored key: Use the output from a previous actions/cache/restore step to ensure the key remains identical to the one used for the restore attempt.

      • Use: key: ${{ steps.<restore-step-id>.outputs.cache-primary-key }}
    2. Re-evaluate the key: If lockfiles are generated during the build process, you can provide a new expression to re-calculate the key based on the new file contents.

      • Example: key: npm-cache-${{hashfiles(package-lock.json)}}