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. 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' cache-packages: description: 'Whether to cache ~/.julia/packages/' default: 'true' cache-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/' 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: 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: - id: paths run: | [ "${{ inputs.cache-artifacts }}" = "true" ] && A_PATH="~/.julia/artifacts" echo "artifacts-path=$A_PATH" >> $GITHUB_OUTPUT [ "${{ inputs.cache-packages }}" = "true" ] && P_PATH="~/.julia/packages" echo "packages-path=$P_PATH" >> $GITHUB_OUTPUT [ "${{ inputs.cache-registries }}" = "true" ] && R_PATH="~/.julia/registries" echo "registries-path=$R_PATH" >> $GITHUB_OUTPUT [ "${{ inputs.cache-compiled }}" = "true" ] && PCC_PATH="~/.julia/compiled" 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 # 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: | ${{ 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 env: CACHE_HIT: ${{ steps.cache.outputs.cache-hit }} shell: bash