Duncan Lukkenaer
Duncan Lukkenaer

Reputation: 13924

Saving cache on job failure in GitHub Actions

I am using the GitHub cache action, but I noticed that the no cache will be created if the job fails. From the docs:

If the job completes successfully, the action creates a new cache with the contents of the path directory.

A stripped down version of my workflow YAML file:

name: Build

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Setup Node.js
        uses: actions/setup-node@master
        with:
          node-version: '10.x'

      - name: Get yarn cache path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn cache dir)"

      - name: Restore yarn cache
        uses: actions/cache@v1
        id: yarn-cache
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

      - name: Install yarn dependencies
        run: yarn install

      - name: Build
        run: yarn build

I noticed that if my Build step fails the cache post-step will be skipped unnecessarily, which causes the installed dependencies to not be cached. This requires subsequent runs to download dependencies again, slowing down the job.

Is there a way to always cache the dependencies, even when the build step fails?

Upvotes: 27

Views: 8645

Answers (3)

leiropi
leiropi

Reputation: 474

With v4 there now is a new save-always flag to save the cache even if a prior step fails (see https://github.com/actions/cache?tab=readme-ov-file#v4). To use this, you need to use continue-on-error: true on steps that might fail.

  - name: Build
    continue-on-error: true
    run: /build.sh

  - name: Cache Always
    uses: actions/cache@v4
    with:
      save-always: true

Upvotes: 4

user7610
user7610

Reputation: 28811

You can now use the actions/cache/save action to save the cache right after it is populated, and before any tests (or anything that might fail the job) runs. This is how issue actions/cache#92 was resolved in the end.

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') }}

https://github.com/actions/cache/tree/main/save#always-save-cache

cache@v4 added save-always parameter

This functionality however appears to be broken, currently.

Upvotes: 27

Patrick Quirk
Patrick Quirk

Reputation: 23747

In the official version of the action, no it's not possible to cache dependencies if the build fails. See this line in the cache action's manifest:

runs:
  using: 'node12'
  main: 'dist/restore/index.js'
  post: 'dist/save/index.js'
  post-if: 'success()'

It will only run the post-step if the job succeeds. I don't know the original reasoning for this, but there are a few issues opened around this idea. In this issue a user forked the action to change the post-if to always(), which may be what you're after, assuming you're willing to run an unofficial action.

Upvotes: 22

Related Questions