diff --git a/.github/actions/setup-lui-ocaml/action.yml b/.github/actions/setup-lui-ocaml/action.yml index b5b488a8..7ae721e5 100644 --- a/.github/actions/setup-lui-ocaml/action.yml +++ b/.github/actions/setup-lui-ocaml/action.yml @@ -26,7 +26,7 @@ runs: # exist and is skipped with a warning. # v4: v1-v3 Windows entries cached ~/.opam, which is never the real # root — restores there leave an uninitialised opam. - key: lui-ocaml-v4-${{ runner.os }}-${{ runner.arch }}-${{ steps.epoch.outputs.image }}-5.5.1-${{ inputs.scope }}-${{ hashFiles('*.opam*', 'dune-project') }}-${{ steps.epoch.outputs.week }} + key: lui-ocaml-v4-${{ runner.os }}-${{ runner.arch }}-${{ steps.epoch.outputs.image }}-5.5.1-${{ inputs.scope }}-${{ hashFiles('*.opam*', 'dune-project') }} # The opam hash makes every dependency change a full miss (~20 min # of compiler build on Windows); fall back to the newest switch # from this image (then any image) and let the top-up step below @@ -89,7 +89,10 @@ runs: mkdir -p _opam/.ci/bin cp -L "$(command -v opam)" _opam/.ci/bin/opam - name: Save OCaml environment - if: steps.environment.outputs.cache-hit != 'true' + # Stable key (no weekly epoch) so the ~20 min Windows switch stays + # resident; only base-branch pushes save, PR-scoped copies are never + # restorable elsewhere and only push the repo over its 10GB cap. + if: steps.environment.outputs.cache-hit != 'true' && github.event_name != 'pull_request' uses: actions/cache/save@v4 with: # C:/.opam must be saved alongside _opam: it holds the opam root diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86547894..55a1b26b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,8 +25,10 @@ jobs: with: node-version: 22 - uses: ./.github/actions/setup-lui-ocaml - - name: Cache dune - uses: actions/cache@v4 + # PRs restore read-only; only base-branch pushes save (repo cache is + # capped at 10GB and per-PR dune caches were evicting the Windows opam switch). + - name: Restore dune cache + uses: actions/cache/restore@v4 with: path: ~/.cache/dune key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} @@ -56,6 +58,15 @@ jobs: run: opam exec -- dune build --action-stderr-on-success=must-be-empty @runtest - name: Runtime performance qualification run: bash tooling/performance/qualify_runtime.sh + - name: Trim dune cache + if: github.event_name == 'push' + run: opam exec -- dune cache trim --size=400MB + - name: Save dune cache + if: github.event_name == 'push' + uses: actions/cache/save@v4 + with: + path: ~/.cache/dune + key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} web-tests: runs-on: ubuntu-latest @@ -68,8 +79,10 @@ jobs: cache: npm cache-dependency-path: platform/web/package-lock.json - uses: ./.github/actions/setup-lui-ocaml - - name: Cache dune - uses: actions/cache@v4 + # PRs restore read-only; only base-branch pushes save (repo cache is + # capped at 10GB and per-PR dune caches were evicting the Windows opam switch). + - name: Restore dune cache + uses: actions/cache/restore@v4 with: path: ~/.cache/dune key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} @@ -125,6 +138,15 @@ jobs: # Hot reload edits shared sources and starts Dune, so it runs alone. - name: Hot reload regression run: node --test platform/web/test/hot-reload.e2e.mjs + - name: Trim dune cache + if: github.event_name == 'push' + run: opam exec -- dune cache trim --size=400MB + - name: Save dune cache + if: github.event_name == 'push' + uses: actions/cache/save@v4 + with: + path: ~/.cache/dune + key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} apple-tests: # Package.swift requires swift-tools-version 6.2 (Xcode 26). @@ -165,8 +187,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup-lui-ocaml - - name: Cache dune - uses: actions/cache@v4 + # PRs restore read-only; only base-branch pushes save (repo cache is + # capped at 10GB and per-PR dune caches were evicting the Windows opam switch). + - name: Restore dune cache + uses: actions/cache/restore@v4 with: path: ~/.cache/dune key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} @@ -375,3 +399,13 @@ jobs: opam exec -- dune runtest platform/native/ -f fi shell: bash + - name: Trim dune cache + if: github.event_name == 'push' + run: opam exec -- dune cache trim --size=400MB + - name: Save dune cache + if: github.event_name == 'push' + uses: actions/cache/save@v4 + with: + path: ~/.cache/dune + key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} + diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 3dc449d8..7ca5f08b 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -29,8 +29,10 @@ jobs: cache: npm cache-dependency-path: platform/web/package-lock.json - uses: ./.github/actions/setup-lui-ocaml - - name: Cache dune - uses: actions/cache@v4 + # PRs restore read-only; only base-branch pushes save (repo cache is + # capped at 10GB and per-PR dune caches were evicting the Windows opam switch). + - name: Restore dune cache + uses: actions/cache/restore@v4 with: path: ~/.cache/dune key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} @@ -55,3 +57,13 @@ jobs: path: _build/web-release - id: deployment uses: actions/deploy-pages@v4 + - name: Trim dune cache + if: github.event_name == 'push' + run: opam exec -- dune cache trim --size=400MB + - name: Save dune cache + if: github.event_name == 'push' + uses: actions/cache/save@v4 + with: + path: ~/.cache/dune + key: dune-${{ runner.os }}-${{ github.job }}-${{ github.sha }} + diff --git a/.github/workflows/warm-cache.yml b/.github/workflows/warm-cache.yml index cb41406b..c4d9c8a6 100644 --- a/.github/workflows/warm-cache.yml +++ b/.github/workflows/warm-cache.yml @@ -6,8 +6,8 @@ name: Warm OCaml cache # saves, so no base-branch cache existed and every PR paid the cold # setup (and raced to save a PR-scoped copy nobody else can read). # This workflow is never cancelled: it only builds and saves the -# environment on the base branches, and refreshes it when the weekly -# epoch in the cache key rolls over. +# environment on the base branches, and refreshes it when the runner +# image in the cache key changes. on: push: branches: [main, feat/ml-backend] @@ -18,7 +18,7 @@ on: - '.github/actions/setup-lui-ocaml/**' - '.github/workflows/warm-cache.yml' schedule: - # Monday 00:10 UTC: just after the ISO week (cache epoch) rolls. + # Weekly: re-warm after runner image updates. - cron: '10 0 * * 1' workflow_dispatch: