name: "Compile cache key" description: > Resolve the compiler-input fingerprint a pattern compile byte cache is keyed on, as the `fingerprint` output. Needs Deno on PATH and the dependencies installed, so it goes after the deno-setup and deno-install actions. outputs: fingerprint: description: > The compiler-input fingerprint: base64url, moving with every input that can change what the compiler emits. value: ${{ steps.fingerprint.outputs.value }} runs: using: "composite" steps: # `actions/cache` evaluates its key again during the post-job save, so a # `hashFiles()` call written into the key walks the fingerprinted trees # twice. Resolving the value here also keys the cache on the one value # `tasks/compile-cache-key.ts` defines rather than on a second hash over # the same files. It is the compiler-input fingerprint on purpose: the # runtime's own cache version is minted from what the compiler emits and # stays put across compiler changes, while a byte cache has to change # with the compiler that filled it. - name: 🧮 Resolve the compiler fingerprint id: fingerprint shell: bash run: | set -euo pipefail value="$(deno run --allow-read "$GITHUB_WORKSPACE/tasks/compile-cache-key.ts")" # An empty output would leave every cache key equal to its constant # prefix, so entries compiled from different sources would collide. if [ -z "$value" ]; then echo "::error::tasks/compile-cache-key.ts printed no fingerprint." exit 1 fi printf 'value=%s\n' "$value" >> "$GITHUB_OUTPUT"