Skip to content

Refactor static into separate tox environments & dedicated fast-checks workflow #2041

@danceratopz

Description

@danceratopz

Split the monolithic static tox environment into granular, single-purpose environments and move them to a dedicated fast-checks workflow. This makes CI failures immediately obvious (the failing job name tells you what broke) and ensures these checks always run as a prerequisite for other workflows.

Motivation

The current static tox environment bundles multiple unrelated checks into a single job:

  • codespell (spelling).
  • ruff check / ruff format (linting/formatting).
  • mypy (type checking).
  • ethereum-spec-lint (custom linting).
  • uv lock --check (dependency lock validation).
  • actionlint (GitHub Actions linting).

Splitting the static checks will:

  1. Reduce debugging friction. When static fails, developers must dig through logs to find which check failed and why. Separate environments provide immediate visibility - the job name itself tells you what broke.
  2. Enable always-on checks. With paths-ignore being introduced (chore(ci): skip redundant checks in workflows #2038), doc-only PRs may skip the test.yaml workflow entirely. A dedicated fast-checks workflow ensures checks like spellcheck are never skipped.

Proposal

1. Split tox environments

Create separate tox environments for each check category:

New Environment Command(s)
lint ruff check, ruff format --check
typecheck mypy
spellcheck codespell
spec-lint ethereum-spec-lint
lockcheck uv lock --check
actionlint actionlint

This is similar to the execution-spec-tests pattern.

Additionally, create a fast-checks alias environment that runs all split checks without code duplication. See lean-ethereum's tox.ini for this pattern:

[testenv:fast-checks]
description = Run all fast checks (lint, typecheck, spellcheck, spec-lint, lockcheck, actionlint)
commands =
    {[testenv:lint]commands}
    {[testenv:typecheck]commands}
    {[testenv:spellcheck]commands}
    {[testenv:spec-lint]commands}
    {[testenv:lockcheck]commands}
    {[testenv:actionlint]commands}

This enables both the aggregate command (tox -e fast-checks) and granular runs (tox -e spellcheck).

Consider aliasing a static tox env, too for backwards compatibility.

2. Create dedicated workflow

Create .github/workflows/fast-checks.yaml:

  • Triggers on all pushes and PRs (no paths-ignore).
  • Runs fast (~2 min total).
  • Executes tox -e fast-checks (the alias) or runs individual envs in parallel jobs.

3. Maintain fast-checks as a prerequisite

The current test.yaml already uses static as a prerequisite for all other jobs (needs: static). This proposal maintains that behavior while extracting it into a reusable workflow:

jobs:
  fast-checks:
    uses: ./.github/workflows/fast-checks.yaml

  py3:
    needs: [fast-checks]
    # ...

Benefits of extraction:

  • Decoupled triggers - fast-checks.yaml has no paths-ignore and always runs. Other workflows (test.yaml, benchmark.yaml, hive-consume.yaml) keep their paths-ignore for expensive tests but call fast-checks.yaml as a prerequisite.
  • Single source of truth - Fast checks are defined once, reused across all workflows via uses:.
  • Clearer CI view - "fast-checks" appears as a separate workflow in GitHub Actions UI.

Alternatively, use workflow_run trigger or repository rulesets to enforce this.

Related

Metadata

Metadata

Assignees

Labels

A-ciArea: Continuous IntegrationA-toolingArea: Improvements or changes to auxiliary tooling such as uv, ruff, mypy, ...C-refactorCategory: refactor

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions