--- # .github/workflows/03-cache.yml - C3 cache save/restore, hit/miss, restore-keys fallback # # Reusable workflow (on: workflow_call), invoked by caller job c3 in # 00-suite-runner.yml. Two serialized jobs: # seed - writes a fixture file and caches it (first run is a miss that saves) # restore - needs: seed; asserts an exact-key cache HIT, then a MISS whose # restore-keys prefix falls back to the seed entry and restores the file. # # Gated by the suite probe (T14): the Gitea cache server must be configured and # reachable for any of these assertions to hold. No cache backend == no pass. name: C3 cache on: workflow_call: jobs: seed: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: source assert library and seed the cache fixture shell: bash run: | source lib/assert.sh echo "cache-content-v1" > cache-me.txt assert_exists cache-me.txt assert_eq "$(cat cache-me.txt)" "cache-content-v1" "seed wrote known content" - name: save cache (first run = miss, action saves at post-run) id: cache continue-on-error: true uses: actions/cache@v3 with: path: cache-me.txt key: "test-cache-${{ hashFiles('cache-me.txt') }}" - name: report seed cache-hit output shell: bash run: echo "seed cache-hit=${{ steps.cache.outputs.cache-hit }}" restore: needs: seed runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: source assert library and recreate fixture for a stable hashFiles key shell: bash run: | source lib/assert.sh # cache-me.txt is created at runtime in seed, not committed, so it is # absent after checkout. Recreate it with identical content so # hashFiles('cache-me.txt') yields the same digest as in seed and the # exact cache key matches. echo "cache-content-v1" > cache-me.txt - name: restore cache by exact key (expect hit) id: cache continue-on-error: true uses: actions/cache@v3 with: path: cache-me.txt key: "test-cache-${{ hashFiles('cache-me.txt') }}" - name: assert exact-key cache hit if: steps.cache.outputs.cache-hit != '' shell: bash run: | source lib/assert.sh assert_eq "${{ steps.cache.outputs.cache-hit }}" "true" "exact key cache hit" - name: cache unavailable (skip) if: steps.cache.outputs.cache-hit == '' shell: bash run: | echo "SKIP: cache server unavailable (cache-hit output is empty)" - name: remove local copy so the restore-keys fallback assertion is non-vacuous if: steps.cache.outputs.cache-hit != '' shell: bash run: rm -f cache-me.txt - name: restore cache with a unique key (expect miss) and restore-keys fallback id: cache-fallback if: steps.cache.outputs.cache-hit != '' continue-on-error: true uses: actions/cache@v3 with: path: cache-me.txt key: "test-cache-nonexistent-${{ github.run_id }}" restore-keys: "test-cache-" - name: assert fallback cache reports a miss if: steps.cache-fallback.outputs.cache-hit != '' shell: bash run: | source lib/assert.sh assert_eq "${{ steps.cache-fallback.outputs.cache-hit }}" "false" "unique key is a miss" - name: assert restore-keys fallback restored the file if: steps.cache-fallback.outputs.cache-hit != '' shell: bash run: | source lib/assert.sh assert_exists cache-me.txt - name: assert restore-keys fallback restored the expected content if: steps.cache-fallback.outputs.cache-hit != '' shell: bash run: | source lib/assert.sh assert_eq "$(cat cache-me.txt)" "cache-content-v1" "restore-keys fallback restored content"