Skip to content

Speed up CI feedback: add pip/dependency caching and concurrency cancellation #232

@dgenio

Description

@dgenio

Summary

The CI workflow has no dependency caching and no concurrency cancellation. Add cache: pip
to the Python setup and a concurrency group with cancel-in-progress, so the gate that
fronts every review runs faster and stops burning runner time on superseded pushes.

Why this matters

CI is the feedback loop that gates review here, and this repo has a high push cadence per PR
(many fix: address Copilot review … / address review feedback fix-up commits — e.g.
5f004af, b2be0e0, d252c9a, a03f631). Each push triggers a full matrix run, and:

  • No caching: pip install -e ".[dev]" reinstalls every dependency from scratch on each
    of the 3 matrix jobs (.github/workflows/ci.yml:18,28-29), on every push and PR. grep -nE "cache|concurrency" .github/workflows/ci.yml → no matches.
  • No concurrency cancellation: there is no top-level concurrency: block, so when a PR is
    pushed again (common, given the fix-up cadence) the now-stale run keeps executing to
    completion instead of being cancelled.

Together these slow the time-to-green and waste runner minutes, which lengthens review cycles.

Current evidence

  • .github/workflows/ci.ymlactions/setup-python@v5 is used with no cache: key;
    dependencies installed via pip install -e ".[dev]" (lines 23-29) with nothing cached
    across runs.
  • No concurrency: block anywhere in the workflow.

Scope / relationship to existing issues

This is complementary to and does not overlap:

Coordinate the final YAML with whichever of those lands first.

Proposed implementation

  1. Add caching to the Python setup step:
    - uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
        cache: pip
        cache-dependency-path: pyproject.toml
  2. Add a top-level concurrency group:
    concurrency:
      group: ci-${{ github.workflow }}-${{ github.ref }}
      cancel-in-progress: true
    (Use a github.ref-based group so pushes to a PR cancel the prior run while distinct
    branches/PRs remain independent.)

AI-agent execution notes

  • Inspect first: .github/workflows/ci.yml, .github/workflows/publish.yml, pyproject.toml.
  • Be careful applying cancel-in-progress to publish.yml — do not cancel in-progress
    release/publish runs. Limit the concurrency block to ci.yml (or scope publish's group to
    never cancel).
  • Cache key must invalidate when pyproject.toml deps change (cache-dependency-path).

Acceptance criteria

  • CI restores a pip cache on repeat runs (visible "Cache restored" in setup-python logs).
  • Pushing a new commit to an open PR cancels the prior in-progress CI run.
  • publish.yml release runs are never cancelled by the new concurrency rule.

Test plan

Open a trial PR, push twice in quick succession, and confirm the first run is cancelled and
the second restores a cache. Confirm publish workflow behavior is unchanged.

Documentation plan

No doc change required beyond an optional CHANGELOG Changed (CI) note. If #210 lands first,
fold the caching/concurrency keys into the make-target-based workflow.

Migration and compatibility notes

CI-only change; no impact on the package or its consumers.

Risks and tradeoffs

A stale or poisoned cache can mask dependency issues; keying on pyproject.toml and using
pip install -e (which still resolves) keeps risk low. cancel-in-progress could cancel a
run a maintainer wanted to watch — acceptable for a pre-merge gate.

Suggested labels

reliability, contributor-experience, performance

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions