Skip to content

Support for Read Only Cache / Configurable Cache Saving #334

@bflad

Description

@bflad

Version

actions/cache@v2

Description

We have a repository with multiple workflows that could benefit from shared caching across all of them. We would like to avoid trying to create and conditionalize one large workflow.

e.g. caching the download of all Go Modules:

# Workflow 1
name: Code Checks

on:
  push:
    branches:
      - master
  pull_request:
    paths:
      - go.sum
      - src/**

jobs:
  go_mod_download:
    name: go mod download
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-go@v2
      with:
        go-version: "1.14"
    - uses: actions/cache@v2
      id: cache-go-pkg-mod
      with:
        path: ~/go/pkg/mod
        key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }}
    - if: steps.cache-go-pkg-mod.outputs.cache-hit != 'true' || steps.cache-go-pkg-mod.outcome == 'failure'
      run: go mod download
  # ... much more ...

# Workflow 2

name: CHANGELOG Checks
on:
  push:
    branches:
      - master
  pull_request:
    paths:
      - CHANGELOG.md

jobs:
  misspell:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: "1.14"
      - uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }}
      - run: go install github.com/client9/misspell/cmd/misspell
      - run: misspell -error -source text CHANGELOG.md

Currently there can be race conditions between these workflows, where the first one that completes will save the cache, while other jobs will see the post-action hit on the cache key and prevent overwriting it. If the latter workflow completes first, the Go Modules download would contain only the download of the Go Modules relevant to the installed package, rather than all Go Modules for the project.

As a simple workaround, we could run the go mod download in every workflow:

jobs:
  misspell:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: "1.14"
      - uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }}
      - run: |
          go mod download
          go install github.com/client9/misspell/cmd/misspell
      - run: misspell -error -source text CHANGELOG.md

This could needlessly waste time/bandwidth, fail for unrelated networking reasons, and seems easy to miss though.

As a more complex workaround, we could add the go_mod_download job to every workflow:

jobs:
  go_mod_download:
    name: go mod download
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-go@v2
      with:
        go-version: "1.14"
    - uses: actions/cache@v2
      id: cache-go-pkg-mod
      with:
        path: ~/go/pkg/mod
        key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }}
    - if: steps.cache-go-pkg-mod.outputs.cache-hit != 'true' || steps.cache-go-pkg-mod.outcome == 'failure'
      run: go mod download
  misspell:
    needs: [go_mod_download]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: "1.14"
      - uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }}
      - run: go install github.com/client9/misspell/cmd/misspell
      - run: misspell -error -source text CHANGELOG.md

But this feels like a lot of overhead and maintenance for each workflow. It would be great if we could tell this action to skip the post save action, effectively making the cache best effort and read-only, while preventing it from missing contents.

Proposals

Adding a read-only input:

jobs:
  misspell:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: "1.14"
      - uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }}
          read-only: true
      - run: go install github.com/client9/misspell/cmd/misspell
      - run: misspell -error -source text CHANGELOG.md

Or maybe adding a save input (see references for why this may be beneficial):

jobs:
  misspell:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: "1.14"
      - uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }}
          save: never # or "always", defaults to current "when missing"
      - run: go install github.com/client9/misspell/cmd/misspell
      - run: misspell -error -source text CHANGELOG.md

Thank you for the consideration! Please reach out if I'm missing something and this is already possible or if this would be acceptable as an enhancement.

References

Metadata

Metadata

Labels

area:granular-controlIssues related to granular control in saving or restoring cache

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions