Skip to content

[CI] Evaluate and reduce GitHub Actions test runtime #1085

Description

@mickaelbegon

Note

This issue is based on a preliminary evaluation performed by Codex using recent public GitHub Actions logs and the current workflow definitions.

The duration ranges and expected improvements below are estimates, not benchmark results. They must be confirmed with representative CI runs.

Context

The current pull-request CI runs:

  • 6 Linux test shards;
  • 12 macOS/Windows test shards;
  • one coverage merge job;
  • one Black lint job.

Recent complete runs typically take 35–42 minutes, partly because of runner availability and queueing.

A first-pass modernization prepared by Codex is available on mickaelbegon/codex/update-github-actions, currently at commit 0a47fd95.

The prototype:

  • updates the actions to Node 24-compatible versions;
  • cancels obsolete runs for the same pull request;
  • removes redundant Conda operations;
  • fixes action-level warnings;
  • improves dependency reproducibility;
  • reports the slowest tests in every shard.

Codex estimates that these initial changes could improve an isolated run by approximately 5–15%. A larger improvement is unlikely without changing environment caching, shard distribution, or the cross-platform execution policy.

Main limitations identified by Codex

Repeated environment creation

Each of the 18 test shards creates an independent Conda environment.

On Windows, environment setup and cleanup can take approximately 5–7 minutes per job. Complete Conda environments and downloaded packages are not currently cached.

Unbalanced shards

Observed test durations vary significantly:

  • Linux: approximately 6–14 minutes;
  • macOS: approximately 5–10 minutes;
  • Windows: approximately 7–10 minutes.

The slowest shard determines the effective critical path. The prototype adds pytest --durations reporting so that the distribution can be improved using test-level measurements.

Full cross-platform matrix on every pull request

Every pull request executes all six shards on Linux, macOS, and Windows.

This provides broad coverage, but consumes many runners and increases queueing when multiple pull requests are updated concurrently.

Limited reproducibility

Black is pinned in the prototype and Conda now uses strict channel priority. However, the environment still relies on:

  • miniforge-version: latest;
  • broad package version ranges;
  • unpinned pytest and coverage tooling.

Package resolution and CI performance can therefore change between runs.

Remaining dependency and test warnings

The prototype addresses action-level warnings, but the logs still contain warnings originating from dependencies and the test suite, including:

  • qhull-static, X11, and Qt file collisions;
  • Matplotlib pending deprecations and unclosed figures;
  • NumPy and SWIG deprecation warnings.

These are separate from GitHub Actions maintenance and may require dedicated issues.

Proposed follow-up

  1. Run the prototype on representative pull requests.
  2. Compare active runner time independently from queueing time.
  3. Collect the new slow-test reports and rebalance the shards.
  4. Evaluate caching Conda environments by OS, architecture, environment hash, and refresh date.
  5. Consider a reduced pull-request matrix while retaining the complete matrix on master, scheduled runs, or an explicit trigger.
  6. Evaluate a resolved environment or lockfile for more reliable caching.
  7. Track dependency and application warnings separately.

Success criteria

  • Establish a measured baseline and publish before/after results.
  • Reduce the slowest test critical path without silently removing coverage.
  • Demonstrate an improvement beyond the initial Codex estimate of 5–15%.
  • Keep the complete test matrix available through a documented trigger.
  • Document cache invalidation and the intended CI coverage policy.
  • Avoid deprecated GitHub Actions runtimes and spurious Conda activation warnings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions