Support for Read Only Cache / Configurable Cache Saving
See original GitHub issueVersion
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
- Configurable save cache on failure: https://github.com/actions/cache/issues/92
- Enable caching of dependencies even if builds fail with post-if modifier: https://github.com/actions/cache/issues/165
Issue Analytics
- State:
- Created 3 years ago
- Reactions:25
- Comments:6 (1 by maintainers)
Top GitHub Comments
Upvote! My use case is a giant gradle cache - 1.5GB out of the 5GB per-repo limit. Gradle caches are good about only updating what’s not matching, so a 90% cache is better than a complete cache miss.
And because I could have more than 2 PRs at a time, I would like the cache to be read-write by my default branch (
main
) and PRs would only attempt to restore the cache, not save it. The proposals above would both easily implement my use-case.Hey all, 👋🏽
We have created a discussion with a proposal that we feel will solve this problem, do let us know your feedback, thanks 😊