CI Cache Strategy
How Lithosphere CI pipelines use caching to keep PR times under 10-15 minutes.
Cache Layers
pnpm store
actions/cache
os-pnpm-store-{lockfile hash}
7 days (LRU)
ci.yaml
node_modules
actions/cache
os-node-modules-{lockfile hash}
7 days (LRU)
ci.yaml
Turborepo local
actions/cache
os-turbo-{sha}
7 days (LRU)
ci.yaml
Docker layers
BuildKit GHA cache
type=gha
repo-scoped
publish-images.yaml
Hardhat cache
pnpm store (includes hardhat cache dir)
lockfile-based
per-install
ci-contracts.yaml
Foundry cache
Not cached in CI (fast enough)
N/A
N/A
ci-contracts.yaml
How It Works
pnpm Store Cache
The pnpm content-addressable store is cached between runs. On cache hit, pnpm install --frozen-lockfile resolves in ~3 seconds instead of 30+.
- name: Get pnpm store directory
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-pnpm-store-Turborepo Cache
Turbo hashes each task's inputs (source files, dependencies, env vars) and skips unchanged packages. The .turbo directory is cached between CI runs so even cross-PR builds benefit from prior results.
Docker Layer Cache
docker/build-push-action uses GitHub Actions cache backend (type=gha) for BuildKit layer caching. This makes incremental image builds 2-5x faster.
Hardhat Compilation Cache
Hardhat's cache/ directory stores compilation results. When source files haven't changed, hardhat compile is a no-op. This is included in the pnpm workspace install and cached via node_modules.
Cache Invalidation
pnpm store: Invalidated when any
pnpm-lock.yamlchanges (new deps)node_modules: Same as pnpm store
Turbo: Keyed by commit SHA;
restore-keysprefix allows partial hits from prior commitsDocker: Invalidated per-layer when Dockerfile or COPY sources change
Parallelization Strategy
The CI is split into independent parallel jobs:
Flaky Test Quarantine
When a test is identified as flaky:
Add
skipannotation with a tracking issue linkMove to a
__flaky__/directory (excluded from CI by default)Run flaky tests in a separate non-blocking job
Fix and re-enable within one sprint
Turbo's inputs config means only changed packages re-run tests, which naturally reduces flake exposure.
Target CI Times
Contracts (PR)
< 10 min
Parallel compile/test/lint/slither
Services (PR)
< 15 min
Turbo cache + parallel jobs
SDK (PR)
< 5 min
Fast tsup build, small test suite
Last updated