mirror of
https://github.com/julia-actions/cache.git
synced 2026-02-12 17:36:53 +08:00
* URL encode any invalid key characters * Test we handle invalid chars * Job matrices must match * Empty commit * Empty commit
156 lines
6.7 KiB
YAML
156 lines
6.7 KiB
YAML
name: 'Cache Julia artifacts, packages and registry'
|
|
description: 'Cache Julia using actions/cache'
|
|
author: 'Sascha Mann, Rik Huijzer, and contributors'
|
|
|
|
branding:
|
|
icon: 'archive'
|
|
color: 'purple'
|
|
|
|
inputs:
|
|
cache-name:
|
|
description: >-
|
|
The cache key prefix. The key body automatically includes the OS and, unless disabled, the matrix vars.
|
|
Include any other parameters/details in this prefix to ensure one unique cache key per concurrent job type.
|
|
default: julia-cache;workflow=${{ github.workflow }};job=${{ github.job }}
|
|
include-matrix:
|
|
description: Whether to include the matrix values when constructing the cache key.
|
|
default: 'true'
|
|
depot:
|
|
description: Path to a Julia depot directory where cached data will be saved to and restored from.
|
|
default: ''
|
|
cache-artifacts:
|
|
description: Whether to cache the depot's `artifacts` directory.
|
|
default: 'true'
|
|
cache-packages:
|
|
description: Whether to cache the depot's `packages` directory.
|
|
default: 'true'
|
|
cache-registries:
|
|
description: Whether to cache the depot's `registries` directory.
|
|
default: 'true'
|
|
cache-compiled:
|
|
description: Whether to cache the depot's `compiled` directory.
|
|
default: 'true'
|
|
cache-scratchspaces:
|
|
description: Whether to cache the depot's `scratchspaces` directory.
|
|
default: 'true'
|
|
cache-logs:
|
|
description: Whether to cache the depot's `logs` directory. 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:
|
|
description: A boolean value to indicate an exact match was found for the primary key. Returns "" when the key is new. Forwarded from actions/cache.
|
|
value: ${{ steps.hit.outputs.cache-hit }}
|
|
|
|
runs:
|
|
using: 'composite'
|
|
steps:
|
|
- name: Install jq
|
|
# Skip installation on GitHub-hosted runners:
|
|
# https://github.com/orgs/community/discussions/48359#discussioncomment-5323864
|
|
if: ${{ !startsWith(runner.name, 'GitHub Actions') }}
|
|
uses: dcarbone/install-jq-action@v2.1.0
|
|
with:
|
|
force: false # Skip install when an existing `jq` is present
|
|
|
|
- id: paths
|
|
run: |
|
|
if [ -n "${{ inputs.depot }}" ]; then
|
|
depot="${{ inputs.depot }}"
|
|
elif [ -n "$JULIA_DEPOT_PATH" ]; then
|
|
# Use the first depot path
|
|
depot=$(echo $JULIA_DEPOT_PATH | cut -d$PATH_DELIMITER -f1)
|
|
else
|
|
depot="~/.julia"
|
|
fi
|
|
echo "depot=$depot" >> $GITHUB_OUTPUT
|
|
[ "${{ inputs.cache-artifacts }}" = "true" ] && A_PATH="${depot}/artifacts"
|
|
echo "artifacts-path=$A_PATH" >> $GITHUB_OUTPUT
|
|
[ "${{ inputs.cache-packages }}" = "true" ] && P_PATH="${depot}/packages"
|
|
echo "packages-path=$P_PATH" >> $GITHUB_OUTPUT
|
|
[ "${{ inputs.cache-registries }}" = "true" ] && R_PATH="${depot}/registries"
|
|
echo "registries-path=$R_PATH" >> $GITHUB_OUTPUT
|
|
[ "${{ inputs.cache-compiled }}" = "true" ] && PCC_PATH="${depot}/compiled"
|
|
echo "compiled-path=$PCC_PATH" >> $GITHUB_OUTPUT
|
|
[ "${{ inputs.cache-scratchspaces }}" = "true" ] && S_PATH="${depot}/scratchspaces"
|
|
echo "scratchspaces-path=$S_PATH" >> $GITHUB_OUTPUT
|
|
[ "${{ inputs.cache-logs }}" = "true" ] && L_PATH="${depot}/logs"
|
|
echo "logs-path=$L_PATH" >> $GITHUB_OUTPUT
|
|
shell: bash
|
|
env:
|
|
PATH_DELIMITER: ${{ runner.OS == 'Windows' && ';' || ':' }}
|
|
|
|
- name: Generate Keys
|
|
id: keys
|
|
run: |
|
|
# `matrix_key` joins all of matrix keys/values (including nested objects) to ensure that concurrent runs each use a unique cache key.
|
|
# When `matrix` isn't set for the job then `MATRIX_JSON=null`.
|
|
if [ "${{ inputs.include-matrix }}" == "true" ] && [ "$MATRIX_JSON" != "null" ]; then
|
|
matrix_key=$(echo "$MATRIX_JSON" | jq 'paths(type != "object") as $p | ($p | join("-")) + "=" + (getpath($p) | tostring)' | jq -rs 'join(";") | . + ";"')
|
|
fi
|
|
restore_key="${{ inputs.cache-name }};os=${{ runner.os }};${matrix_key}"
|
|
# URL encode any restricted characters:
|
|
# https://github.com/actions/toolkit/blob/5430c5d84832076372990c7c27f900878ff66dc9/packages/cache/src/cache.ts#L38-L43
|
|
restore_key=$(sed 's/,/%2C/g' <<<"${restore_key}")
|
|
key="${restore_key}run_id=${{ github.run_id }};run_attempt=${{ github.run_attempt }}"
|
|
echo "restore-key=${restore_key}" >> $GITHUB_OUTPUT
|
|
echo "key=${key}" >> $GITHUB_OUTPUT
|
|
shell: bash
|
|
env:
|
|
MATRIX_JSON: ${{ toJSON(matrix) }}
|
|
|
|
- uses: actions/cache@4d4ae6ae148a43d0fd1eda1800170683e9882738
|
|
id: cache
|
|
with:
|
|
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
|
|
if: ${{ steps.cache.outputs.cache-hit == 'true' }}
|
|
run: du -shc ${{ steps.paths.outputs.depot }}/* || 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
|
|
env:
|
|
CACHE_HIT: ${{ steps.cache.outputs.cache-hit }}
|
|
shell: bash
|