diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90bc1d7..75e6b3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,22 +61,41 @@ jobs: npm install -g "markdownlint-cli@${MARKDOWNLINT_VERSION}" "prettier@${PRETTIER_VERSION}" # check.sh runs every tool through `uv run` / `uv build` for a locked, - # reproducible env, so only uv must be on PATH (installed from PyPI to match - # the repo's pip-based, no-new-action posture). `uv run` itself syncs the - # project + dev group into .venv, so no `pip install -e .` is needed here. - - name: Install - run: python -m pip install uv + # reproducible env, so only uv must be on PATH. setup-uv caches the uv + # download cache (~/.cache/uv) keyed on uv.lock, so the locked env — incl. + # the Rust-backed sdists (pydantic-core/jiter/cryptography) — isn't + # re-downloaded/rebuilt every run. `uv run` itself syncs the project + dev + # group into .venv, so no `pip install -e .` is needed here. + - name: Install uv (cached) + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + enable-cache: true + cache-dependency-glob: uv.lock # actionlint and gitleaks are Go binaries (no PyPI wheel), so check.sh self-skips # them locally like shellcheck. Build them here with the runner's preinstalled Go, # pinned via scripts/gate_tool_pins.sh (shared with the web session-start hook), # and put GOPATH/bin on PATH so check.sh enforces them. # (gitleaks v8's Go module path is still github.com/zricethezav/gitleaks/v8.) + # Cache the built binaries keyed on the pin file so a cache hit skips the + # from-source `go install` compile entirely. + - name: Cache Go gate binaries (actionlint, gitleaks) + id: cache-go-bin + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/go/bin + key: go-gate-bins-${{ runner.os }}-${{ hashFiles('scripts/gate_tool_pins.sh') }} - name: Workflow + secret scanners (actionlint, gitleaks) + env: + # Map the cache-hit output to an env var rather than expanding the + # `${{ }}` directly into the script (zizmor template-injection rule). + CACHE_HIT: ${{ steps.cache-go-bin.outputs.cache-hit }} run: | source scripts/gate_tool_pins.sh - go install "$ACTIONLINT_MODULE" - go install "$GITLEAKS_MODULE" + if [ "$CACHE_HIT" != "true" ]; then + go install "$ACTIONLINT_MODULE" + go install "$GITLEAKS_MODULE" + fi echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - name: Lint, typecheck, test @@ -155,8 +174,11 @@ jobs: } ffmpeg -version - - name: Install uv - run: python -m pip install uv + - name: Install uv (cached) + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + enable-cache: true + cache-dependency-glob: uv.lock # `uv run` syncs the locked project + dev group into .venv, then runs the default # suite (e2e/install excluded via addopts). @@ -225,10 +247,13 @@ jobs: # resolve the LOCKED dependency versions (uv.lock) rather than the newest # release `pip install` would pull — which is what keeps the byte-exact # `--help` snapshots stable. Install uv and materialize the frozen env here. - - name: Install - run: | - python -m pip install --upgrade pip uv - uv sync --frozen + - name: Install uv (cached) + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + enable-cache: true + cache-dependency-glob: uv.lock + - name: Sync frozen env + run: uv sync --frozen - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1