This commit is contained in:
Ian Butterworth
2023-11-27 10:05:33 -05:00
committed by GitHub
parent 3466649946
commit 67f1f75048
4 changed files with 59 additions and 9 deletions

View File

@@ -14,6 +14,11 @@ on:
- 'handle_caches.jl'
- '.github/**'
# needed to allow julia-actions/cache to delete old caches that it has created
permissions:
actions: write
contents: read
jobs:
generate-key:
runs-on: ubuntu-latest

View File

@@ -11,6 +11,11 @@ name: CI
on: [push, pull_request]
# needed to allow julia-actions/cache to delete old caches that it has created
permissions:
actions: write
contents: read
jobs:
test:
runs-on: ubuntu-latest
@@ -34,7 +39,7 @@ However note that caching the registries may mean that the registry will not be
### Optional Inputs
- `cache-name` - The cache key prefix. Defaults to `julia-cache`. The key body automatically includes matrix vars and the OS. Include any other parameters/details in this prefix to ensure one unique cache key per concurrent job type.
- `cache-name` - The cache key prefix. Defaults to `julia-cache-${{ github.workflow }}-${{ github.job }}`. The key body automatically includes matrix vars and the OS. Include any other parameters/details in this prefix to ensure one unique cache key per concurrent job type.
- `include-matrix` - Whether to include the matrix values when constructing the cache key. Defaults to `true`.
- `cache-artifacts` - Whether to cache `~/.julia/artifacts/`. Defaults to `true`.
- `cache-packages` - Whether to cache `~/.julia/packages/`. Defaults to `true`.
@@ -43,6 +48,7 @@ However note that caching the registries may mean that the registry will not be
- `cache-scratchspaces` - Whether to cache `~/.julia/scratchspaces/`. Defaults to `true`.
- `cache-log` - Whether to cache `~/.julia/logs/`. Defaults to `true`. Helps auto-`Pkg.gc()` keep the cache small.
- `delete-old-caches` - Whether to delete old caches for the given key. Defaults to `true`
- `token` - A github PAT. Defaults to `github.token`. Requires `repo` scope to enable the deletion of old caches.
### Outputs
@@ -79,6 +85,18 @@ This action automatically deletes old caches that match the first 4 fields of th
Which means your caches files will not grow needlessly. Github also deletes cache files after
[90 days which can be increased in private repos to up to 400 days](https://docs.github.com/en/organizations/managing-organization-settings/configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-organization)
> [!NOTE]
> To allow deletion of caches you will likely need to grant the following to the default
> `GITHUB_TOKEN` by adding this to your yml:
> ```
> permissions:
> actions: write
> contents: read
> ```
> (Note this won't work for fork PRs but should once merged)
> Or provide a token with `repo` scope via the `token` input option.
> See https://cli.github.com/manual/gh_cache_delete
To disable deletion set input `delete-old-caches: 'false'`.
### Cache Garbage Collection

View File

@@ -9,7 +9,7 @@ branding:
inputs:
cache-name:
description: 'The cache key prefix. Unless disabled the key body automatically includes matrix vars, and the OS. Include any other parameters/details in this prefix to ensure one unique cache key per concurrent job type.'
default: 'julia-cache'
default: 'julia-cache-${{ github.workflow }}-${{ github.job }}'
include-matrix:
description: 'Whether to include the matrix values when constructing the cache key'
default: 'true'
@@ -34,6 +34,9 @@ inputs:
delete-old-caches:
description: 'Whether to delete old caches for the given key'
default: 'true'
token:
description: 'A github PAT. Requires `repo` scope to enable the deletion of old caches'
default: '${{ github.token }}'
outputs:
cache-hit:
@@ -65,7 +68,7 @@ runs:
# with a matrix.
- id: keys
run: |
MATRIX_STRING="${{ join(matrix.*, '-') }}"
[ "${{ inputs.include-matrix }}" == "true" ] && MATRIX_STRING="${{ join(matrix.*, '-') }}"
[ -n "$MATRIX_STRING" ] && MATRIX_STRING="-${MATRIX_STRING}"
RESTORE_KEY="${{ inputs.cache-name }}-${{ runner.os }}${MATRIX_STRING}_"
echo "restore-key=${RESTORE_KEY}" >> $GITHUB_OUTPUT
@@ -87,6 +90,10 @@ runs:
restore-keys: ${{ steps.keys.outputs.restore-key }}
enableCrossOsArchive: false
- name: list restored depot directory sizes
run: du -shc ~/.julia/* || true
shell: bash
# github and actions/cache doesn't provide a way to update a cache at a given key, so we delete any
# that match the restore key just before saving the new cache
- uses: pyTooling/Actions/with-post-step@adef08d3bdef092282614f3b683897cefae82ee3
@@ -94,10 +101,10 @@ runs:
with:
# seems like there has to be a `main` step in this action. Could list caches for info if we wanted
# main: julia ${{ github.action_path }}/handle_caches.jl "${{ github.repository }}" "list"
main: du -shc ~/.julia/* || true
main: echo ""
post: julia ${{ github.action_path }}/handle_caches.jl "${{ github.repository }}" "rm" "${{ steps.keys.outputs.restore-key }}"
env:
GH_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ inputs.token }}
- id: hit
run: echo "cache-hit=$CACHE_HIT" >> $GITHUB_OUTPUT

View File

@@ -9,6 +9,7 @@ function handle_caches()
run(`gh cache list --limit 100 --repo $repo`)
elseif func == "rm"
caches = String[]
failed = String[]
for _ in 1:5 # limit to avoid accidental rate limiting
hits = split(strip(read(`gh cache list --limit 100 --repo $repo`, String)), keepempty=false)
search_again = length(hits) == 100
@@ -18,18 +19,37 @@ function handle_caches()
for c in hits
try
run(`gh cache delete $(split(c)[1]) --repo $repo`)
push!(caches, c)
catch e
@error e
push!(failed, c)
end
end
append!(caches, hits)
search_again || break
end
if isempty(caches)
if isempty(failed) && isempty(caches)
println("No existing caches found for restore key `$restore_key`")
else
println("$(length(caches)) existing caches deleted that match restore key `$restore_key`:")
println.(caches)
if !isempty(failed)
println("Failed to delete $(length(failed)) existing caches for restore key `$restore_key`")
println.(failed)
@info """
To delete caches you need to grant the following to the default `GITHUB_TOKEN` by adding
this to your yml:
```
permissions:
actions: write
contents: read
```
(Note this won't work for fork PRs but should once merged)
Or provide a token with `repo` scope via the `token` input option.
See https://cli.github.com/manual/gh_cache_delete
"""
end
if !isempty(caches)
println("$(length(caches)) existing caches deleted that match restore key `$restore_key`:")
println.(caches)
end
end
else
throw(ArgumentError("Unexpected second argument: $func"))