Compare commits

..

15 Commits
v1.2.2 ... v1.4

Author SHA1 Message Date
Christian Proud
ff08d7d467 Fix incorrect GitHub actions path on containers (#78)
Co-authored-by: Ian Butterworth <i.r.butterworth@gmail.com>
2023-11-28 11:06:28 -05:00
Ian Butterworth
b4528cf39e fix readme typo (#76) 2023-11-27 20:52:22 -05:00
Ian Butterworth
67f1f75048 Fixup #71 (#75) 2023-11-27 10:05:33 -05:00
Ian Butterworth
3466649946 Update cache every run. Add /compiled and /logs. Make key sensitive to matrix. (#71)
Co-authored-by: Rik Huijzer <github@huijzer.xyz>
Co-authored-by: Sascha Mann <git@mail.saschamann.eu>
2023-11-25 00:08:21 -05:00
dependabot[bot]
b606b82bd0 Bump actions/checkout from 4.1.0 to 4.1.1 (#70)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8ade135a41...b4ffde65f4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-02 12:18:25 +01:00
Ian Butterworth
8ef8d3313f add cache-scratchspaces and default enabled (#63) 2023-11-02 12:12:59 +01:00
dependabot[bot]
5867e4d730 Bump actions/checkout from 4.0.0 to 4.1.0 (#68)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](3df4ab11eb...8ade135a41)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-26 09:29:52 +02:00
dependabot[bot]
2d9095b561 Bump actions/checkout from 3.5.2 to 4.0.0 (#65)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 4.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8e5e7e5ab8...3df4ab11eb)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-09 12:49:50 +02:00
dependabot[bot]
4616a55a79 Bump actions/cache from 3.3.1 to 3.3.2 (#67)
Bumps [actions/cache](https://github.com/actions/cache) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](88522ab9f3...704facf57e)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-09 12:49:20 +02:00
Fons van der Plas
ec00ba5d20 remove "test" from cache name (#66) 2023-09-09 12:48:52 +02:00
Sascha Mann
75868c023d Use step outputs instead of env vars (#50)
fixes #48

* Use step outputs instead of env vars

* Change case of outputs to match standard conventions
2023-07-26 22:27:05 -04:00
dependabot[bot]
d006556bca Bump actions/checkout from 3.5.1 to 3.5.2 (#60)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](83b7061638...8e5e7e5ab8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-14 12:05:13 +02:00
dependabot[bot]
adbfa18f98 Bump actions/checkout from 3.5.0 to 3.5.1 (#59)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8f4b7f8486...83b7061638)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-13 13:18:41 +02:00
dependabot[bot]
ed93024b72 Bump actions/checkout from 3.4.0 to 3.5.0 (#58)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](24cb908017...8f4b7f8486)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-24 10:47:28 +01:00
dependabot[bot]
3ea06f8ffc Bump actions/checkout from 3.3.0 to 3.4.0 (#57)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](ac59398561...24cb908017)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-16 11:05:49 +01:00
4 changed files with 279 additions and 35 deletions

View File

@@ -6,12 +6,19 @@ on:
- main
paths:
- 'action.yml'
- 'handle_caches.jl'
- '.github/**'
pull_request:
paths:
- 'action.yml'
- '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
@@ -33,7 +40,27 @@ jobs:
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Save cache
id: cache
uses: ./
with:
cache-name: ${{ needs.generate-key.outputs.cache-name }}
- name: Check no artifacts dir
shell: 'julia --color=yes {0}'
run: |
dir = joinpath(first(DEPOT_PATH), "artifacts")
@assert !isdir(dir)
- name: Install a small binary
shell: 'julia --color=yes {0}'
run: 'using Pkg; Pkg.add("pandoc_jll")'
# Do tests with no matrix also given the matrix is auto-included in cache key
test-save-nomatrix:
needs: generate-key
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Save cache
id: cache
uses: ./
@@ -56,7 +83,7 @@ jobs:
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Restore cache
id: cache
uses: ./
@@ -72,13 +99,47 @@ jobs:
- name: Check existance or emptiness of affected dirs
shell: 'julia --color=yes {0}'
run: |
# Artifacts and Packages should exist as they've been cached
# These dirs should exist as they've been cached
artifacts_dir = joinpath(first(DEPOT_PATH), "artifacts")
@assert !isempty(readdir(artifacts_dir))
packages_dir = joinpath(first(DEPOT_PATH), "packages")
@assert !isempty(readdir(packages_dir))
# Caching the compiled dir is disabled by default and should not exist after restoring a cache
compiled_dir = joinpath(first(DEPOT_PATH), "compiled")
@assert !isdir(compiled_dir) || isempty(readdir(compiled_dir))
@assert !isempty(readdir(compiled_dir))
scratchspaces_dir = joinpath(first(DEPOT_PATH), "scratchspaces")
@assert !isempty(readdir(scratchspaces_dir))
logs_dir = joinpath(first(DEPOT_PATH), "logs")
@assert !isempty(readdir(logs_dir))
test-restore-nomatrix:
needs: [generate-key, test-save-nomatrix]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Restore cache
id: cache
uses: ./
with:
cache-name: ${{ needs.generate-key.outputs.cache-name }}
- name: Test cache-hit output
shell: 'julia --color=yes {0}'
run: |
@show ENV["cache-hit"]
@assert ENV["cache-hit"] == "true"
env:
cache-hit: ${{ steps.cache.outputs.cache-hit }}
- name: Check existance or emptiness of affected dirs
shell: 'julia --color=yes {0}'
run: |
# These dirs should exist as they've been cached
artifacts_dir = joinpath(first(DEPOT_PATH), "artifacts")
@assert !isempty(readdir(artifacts_dir))
packages_dir = joinpath(first(DEPOT_PATH), "packages")
@assert !isempty(readdir(packages_dir))
compiled_dir = joinpath(first(DEPOT_PATH), "compiled")
@assert !isempty(readdir(compiled_dir))
scratchspaces_dir = joinpath(first(DEPOT_PATH), "scratchspaces")
@assert !isempty(readdir(scratchspaces_dir))
logs_dir = joinpath(first(DEPOT_PATH), "logs")
@assert !isempty(readdir(logs_dir))

View File

@@ -1,6 +1,6 @@
# julia-actions/cache Action
A shortcut action to cache Julia artifacts, packages and (optionally) registries to reduce GitHub Actions running time.
A shortcut action to cache Julia depot contents to reduce GitHub Actions running time.
## Usage
@@ -11,19 +11,23 @@ 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
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
```
By default, this caches the files in `~/.julia/artifacts/` and `~/.julia/packages/`.
To also cache `~/.julia/registries/`, use
By default the majority of the depot is cached. To also cache `~/.julia/registries/`, use
```yaml
- uses: julia-actions/cache@v1
@@ -31,27 +35,75 @@ To also cache `~/.julia/registries/`, use
cache-registries: "true"
```
Note that caching the registries may actually slow down the workflow running time on Windows runners.
That is why caching the registries is disabled by default.
However note that caching the registries may mean that the registry will not be updated each run.
### Inputs
### Optional Inputs
- `cache-name` - Name used as part of the cache keys
- `cache-artifacts` - Whether to cache `~/.julia/artifacts/`. Enabled by default.
- `cache-packages` - Whether to cache `~/.julia/packages/`. Enabled by default.
- `cache-registries` - Whether to cache `~/.julia/registries/`. Disabled by default.
- `cache-compiled` - Whether to cache `~/.julia/compiled/`. Disabled by default. **USE ONLY IF YOU KNOW WHAT YOU'RE DOING!** See [#11](https://github.com/julia-actions/cache/issues/11).
- `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`.
- `cache-registries` - Whether to cache `~/.julia/registries/`. Defaults to `false`. Disabled to ensure CI gets latest versions.
- `cache-compiled` - Whether to cache `~/.julia/compiled/`. Defaults to `true`.
- `cache-scratchspaces` - Whether to cache `~/.julia/scratchspaces/`. Defaults to `true`.
- `cache-logs` - 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
- `cache-hit` - A boolean value to indicate an exact match was found for the primary key. Returns \"\" when the key is new. Forwarded from actions/cache.
## How it works
## How It Works
This action is a wrapper around <https://github.com/actions/cache>.
In summary, this action stores the files in the aforementioned paths in one compressed file when running for the first time.
This cached file is then restored upon the second run.
The benefit of this is that downloading one big file is quicker than downloading many different files from many different locations.
This cached file is then restored upon the second run, and afterwards resaved under a new key, and the previous cache deleted.
The benefit of caching is that downloading one big file is quicker than downloading many different files from many different locations
and precompiling them.
### Cache keys
The cache key that the cache will be saved as is based on:
- The `cache-name` input
- All variables in the `matrix` (unless disabled via `include-matrix: 'false'`)
- The `runner.os` (may be in the matrix too, but included for safety)
- The run id
- The run attempt number
> [!NOTE]
> If in your workflow if you do not use a matrix for concurrency you should make `cache-name` such that it is unique for
> concurrent jobs, otherwise caching may not be effective.
### Cache Retention
This action automatically deletes old caches that match the first 4 fields of the above key:
- The `cache-name` input
- All variables in the `matrix` (unless disabled via `include-matrix: 'false'`)
- The `runner.os` (may be in the matrix too, but included for safety)
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
Caches are restored and re-saved after every run, retaining the state of the depot throughout runs.
Their size will be regulated like a local depot automatically by the automatic `Pkg.gc()` functionality that
clears out old content, which is made possible because the `/log` contents are cached.
## Third Party Notice

View File

@@ -8,8 +8,11 @@ branding:
inputs:
cache-name:
description: 'Name used as part of the cache keys'
default: 'julia-cache'
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-${{ github.workflow }}-${{ github.job }}'
include-matrix:
description: 'Whether to include the matrix values when constructing the cache key'
default: 'true'
cache-artifacts:
description: 'Whether to cache ~/.julia/artifacts/'
default: 'true'
@@ -17,11 +20,23 @@ inputs:
description: 'Whether to cache ~/.julia/packages/'
default: 'true'
cache-registries:
description: 'Whether to cache ~/.julia/registries/'
description: 'Whether to cache ~/.julia/registries/. This is off by default to ensure CI gets latest versions'
default: 'false'
cache-compiled:
description: 'Whether to cache ~/.julia/compiled. USE WITH CAUTION! See https://github.com/julia-actions/cache/issues/11 for caveats.'
default: 'false'
description: 'Whether to cache ~/.julia/compiled/'
default: 'true'
cache-scratchspaces:
description: 'Whether to cache ~/.julia/scratchspaces/'
default: 'true'
cache-logs:
description: 'Whether to cache ~/.julia/logs/. This helps automatic Pkg.gc() keep the cache size down'
default: 'true'
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:
@@ -34,22 +49,73 @@ runs:
- id: paths
run: |
[ "${{ inputs.cache-artifacts }}" = "true" ] && A_PATH="~/.julia/artifacts"
echo "ARTIFACTS_PATH=$A_PATH" >> $GITHUB_ENV
echo "artifacts-path=$A_PATH" >> $GITHUB_OUTPUT
[ "${{ inputs.cache-packages }}" = "true" ] && P_PATH="~/.julia/packages"
echo "PACKAGES_PATH=$P_PATH" >> $GITHUB_ENV
echo "packages-path=$P_PATH" >> $GITHUB_OUTPUT
[ "${{ inputs.cache-registries }}" = "true" ] && R_PATH="~/.julia/registries"
echo "REGISTRIES_PATH=$R_PATH" >> $GITHUB_ENV
echo "registries-path=$R_PATH" >> $GITHUB_OUTPUT
[ "${{ inputs.cache-compiled }}" = "true" ] && PCC_PATH="~/.julia/compiled"
echo "PRECOMPILATION_CACHE_PATH=$PCC_PATH" >> $GITHUB_ENV
echo "compiled-path=$PCC_PATH" >> $GITHUB_OUTPUT
[ "${{ inputs.cache-scratchspaces }}" = "true" ] && S_PATH="~/.julia/scratchspaces"
echo "scratchspaces-path=$S_PATH" >> $GITHUB_OUTPUT
[ "${{ inputs.cache-logs }}" = "true" ] && L_PATH="~/.julia/logs"
echo "logs-path=$L_PATH" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
# MATRIX_STRING is a join of all matrix variables that helps concurrent runs have a unique cache key.
# The underscore at the end of the restore key demarks the end of the restore section. Without this
# a runner without a matrix has a restore key that will cause impropper clearing of caches from those
# with a matrix.
- id: keys
run: |
[ "${{ 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
echo "key=${RESTORE_KEY}${{ github.run_id }}-${{ github.run_attempt }}" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/cache@4d4ae6ae148a43d0fd1eda1800170683e9882738
id: cache
with:
path: "${{ format('{0}\n{1}\n{2}\n{3}', env.ARTIFACTS_PATH, env.PACKAGES_PATH, env.REGISTRIES_PATH, env.PRECOMPILATION_CACHE_PATH) }}"
key: ${{ runner.os }}-test-${{ inputs.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ inputs.cache-name }}-
path: |
${{ steps.paths.outputs.artifacts-path }}
${{ steps.paths.outputs.packages-path }}
${{ steps.paths.outputs.registries-path }}
${{ steps.paths.outputs.scratchspaces-path }}
${{ steps.paths.outputs.compiled-path }}
${{ steps.paths.outputs.logs-path }}
key: ${{ steps.keys.outputs.key }}
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
# Not windows
- uses: pyTooling/Actions/with-post-step@adef08d3bdef092282614f3b683897cefae82ee3
if: ${{ inputs.delete-old-caches == 'true' && runner.OS != 'Windows' }}
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: echo ""
post: julia $GITHUB_ACTION_PATH/handle_caches.jl "${{ github.repository }}" "rm" "${{ steps.keys.outputs.restore-key }}"
env:
GH_TOKEN: ${{ inputs.token }}
# Windows (because this action uses command prompt on windows)
- uses: pyTooling/Actions/with-post-step@adef08d3bdef092282614f3b683897cefae82ee3
if: ${{ inputs.delete-old-caches == 'true' && runner.OS == 'Windows' }}
with:
main: echo ""
post: cd %GITHUB_ACTION_PATH% && julia handle_caches.jl "${{ github.repository }}" "rm" "${{ steps.keys.outputs.restore-key }}"
env:
GH_TOKEN: ${{ inputs.token }}
- id: hit
run: echo "cache-hit=$CACHE_HIT" >> $GITHUB_OUTPUT

65
handle_caches.jl Normal file
View File

@@ -0,0 +1,65 @@
using Pkg, Dates
function handle_caches()
repo = ARGS[1]
func = ARGS[2]
restore_key = get(ARGS, 3, "")
if func == "list"
println("Listing existing 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
filter!(contains(restore_key), hits)
isempty(hits) && break
# We can delete everything that matches the restore key because the new cache is saved later.
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
search_again || break
end
if isempty(failed) && isempty(caches)
println("No existing caches found for restore key `$restore_key`")
else
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"))
end
end
try
# do a gc with the standard 7-day delay
Pkg.gc()
handle_caches()
catch e
@error "An error occurred while managing existing caches" e
end