Skip to content

ci: 100% enforcement — mypy + format-check + every pre-commit hook#22

Merged
fede-kamel merged 16 commits into
mainfrom
ci/100-percent-enforcement
May 1, 2026
Merged

ci: 100% enforcement — mypy + format-check + every pre-commit hook#22
fede-kamel merged 16 commits into
mainfrom
ci/100-percent-enforcement

Conversation

@fede-kamel
Copy link
Copy Markdown
Contributor

The previous CI ran `ruff lint` + tests across the Python matrix but left mypy, ruff format, gitleaks, doc8, markdownlint, codespell, and the rest of the pre-commit suite unchecked at PR time. Recent runs also failed at `startup_failure` because of a brittle ternary in `ci-success`.

This PR makes CI 100% match the local pre-commit + check pipeline.

Workflow changes

  • _lint.yml now runs hatch run check (format-check + ruff + mypy) across Python 3.11 and 3.14.
  • _precommit.yml (new) runs pre-commit run --all-files against every hook in .pre-commit-config.yaml: gitleaks, EOL, whitespace, ruff lint, ruff format, doc8, markdownlint, YAML format, large-file guard, etc. Skips mypy (covered in _lint.yml across the matrix) and the manual-only poetry-check.
  • ci.yml wires precommit into the orchestrator alongside lint / test / codespell / dco. Replaces the broken complex ternary in ci-success with a simple grep over the needs.*.result JSON blob — that ternary was the source of every recent startup_failure.
  • _test.yml unchanged — already runs hatch run test on Python 3.11 / 3.12 / 3.13 / 3.14.

pyproject.toml

  • hatch run test is now scoped to tests/unit/ so CI on a fresh runner doesn't try to spin up Oracle / Qdrant / OPENAI fixtures. hatch run test-integration and hatch run test-all still run the broader suites when credentials are available.
  • hatch run check is the new combined gate — format-check + lint + typecheck — so contributors and CI run identical checks.
  • Lint scope expanded from src tests to src tests examples so pre-commit's ruff (which runs on every .py) and the hatch scripts agree on what's covered. examples/ gets a small per-file-ignore allowance for tutorial-flavour rules.

Validation

  • hatch run check clean — format-check + ruff + mypy across 313 files in src/tests + 55 in examples.
  • hatch run test3193 unit tests pass in 5.2s.
  • pre-commit run --all-files --hook-stage pre-commit clean — every hook green.
  • All workflow YAML parses cleanly.

What CI now enforces on every PR

Check Tool Where
Format ruff format --check _lint.yml × 2 Python versions
Lint ruff check _lint.yml × 2 Python versions
Type-check mypy _lint.yml × 2 Python versions
Unit tests pytest tests/unit _test.yml × 4 Python versions (3.11 / 3.12 / 3.13 / 3.14)
Spellcheck codespell _codespell.yml
Pre-commit gitleaks, EOL, whitespace, large-file guard, doc8, markdownlint, YAML format, TOML/JSON/YAML syntax, merge-conflict markers, private-key detection, BOM, mixed-line-ending, ruff lint+format _precommit.yml
DCO sign-off tisonkun/actions-dco ci.yml (PR-only)

Test plan

  • CI passes on this PR (the merge gate is ci-success aggregating all jobs).
  • Future PRs run all 7 checks above.

@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Apr 30, 2026
The previous CI ran ruff lint + tests across the Python matrix but
left mypy, ruff format, gitleaks, doc8, markdownlint, codespell, and
the rest of the pre-commit suite unchecked at PR time. This run also
silently failed (`startup_failure`) because of a brittle ternary
expression in the `ci-success` job.

Workflow changes
----------------
- ``_lint.yml`` now runs ``hatch run check`` (format-check + ruff +
  mypy) across Python 3.11 and 3.14.
- New ``_precommit.yml`` runs ``pre-commit run --all-files`` against
  every hook in ``.pre-commit-config.yaml`` (gitleaks, EOL,
  whitespace, ruff lint, ruff format, doc8, markdownlint, YAML
  format, large-file guard, etc.). Skips ``mypy`` and ``poetry-check``
  — the former is already covered by ``_lint.yml`` across the matrix,
  the latter is manual-only.
- ``ci.yml`` now wires precommit into the orchestrator alongside
  lint / test / codespell / dco. Replaces the broken complex ternary
  in ``ci-success`` with a simple grep over the JSON ``needs.*.result``
  blob — that ternary was the source of every recent
  ``startup_failure``.
- ``_test.yml`` unchanged — already runs the full ``hatch run test``
  matrix on 3.11 / 3.12 / 3.13 / 3.14.

pyproject.toml
--------------
- ``hatch run test`` is now scoped to ``tests/unit/`` so CI on a fresh
  runner doesn't try to spin up Oracle / Qdrant / OPENAI fixtures.
  ``hatch run test-integration`` and ``hatch run test-all`` still run
  the broader suites when credentials / services are available.
- ``hatch run check`` is the new combined gate — format-check + lint +
  typecheck — so contributors and CI run identical checks.
- Lint scope expanded from ``src tests`` to ``src tests examples`` so
  pre-commit's ruff (which runs on every ``.py``) and the hatch
  scripts agree on what's covered. ``examples/`` gets a small
  per-file-ignore allowance for tutorial-flavour rules (``F841``
  unused-local for inspectable demo APIs, ``S108`` for ``/tmp/``
  paths in checkpointer demos, ``PTH118``/``PTH208`` for
  pedagogical readability over ``Path / "x"``).

Validation
----------
- ``hatch run check`` clean (format-check + ruff + mypy across 313
  files in src/tests + 55 in examples).
- ``hatch run test`` 3193 unit tests pass in 5.2s.
- ``pre-commit run --all-files --hook-stage pre-commit`` clean
  (mypy + poetry-check skipped per the SKIP env, every other hook
  green).
- All workflow YAML parses cleanly via ``python -c "import yaml; ..."``.

Drive-by tutorial reformats
---------------------------
``examples/tutorial_*.py`` had ``i+1`` patterns that ruff format
0.15.0 wants as ``i + 1`` (PEP 8 binary-operator spacing). Pre-commit
auto-fixed them when the lint scope was widened. No semantic change.

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Hatch 1.14.0 broke at runtime in CI with:

  Environment `default` is incompatible: module
  'virtualenv.discovery.builtin' has no attribute
  'propose_interpreters'

— a known incompatibility with newer ``virtualenv`` releases that
hatch 1.14.0 hadn't been updated to handle. Fixed in hatch 1.16.x.

Pin ``HATCH_VERSION: "1.16.5"`` (latest stable, 2026-02-27) across
``_lint.yml`` / ``_test.yml`` / ``_release.yml``. This was the
actual root cause of every recent CI ``startup_failure`` —
``hatch run`` couldn't bootstrap the env, the lint job crashed at
the first hatch invocation, and the workflow exited 1 before the
ci-success aggregator could even run.

Also restores ``ci.yml`` to its full multi-job orchestrator (lint
+ test + precommit + codespell + dco + ci-success aggregate gate)
after the bisect commits reduced it to a single smoke job.

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
The 2-reusable bisect ran but hit ModuleNotFoundError for ``oci`` /
``openai`` / ``fastmcp`` etc. — ``hatch run test`` uses the default
env which only carries ``[dev]`` deps. Switch ``_test.yml`` to a
direct ``pip install -e ".[dev,all]"`` so every optional dep is
available, and run ``pytest tests/unit/`` directly. Bypassing hatch
here also avoids spinning up four per-matrix-slot virtualenvs.

Restore ``ci.yml`` to the full orchestrator (lint + test + precommit
+ codespell + dco + ci-success) now that the 2-reusable bisect
proved the multi-job structure works.

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
`tisonkun/actions-dco` was last updated 2022-07-30 and uses Node 16,
which GitHub Actions deprecated. Any workflow that includes it now
fails with `startup_failure` before any job runs. **This was the
root cause of every recent CI failure** — earlier bisects pointed
to "the dco job" without me realizing the action itself was the
deprecated piece.

Replace with a 20-line inline bash check: walk every commit between
``pull_request.base.sha`` and ``pull_request.head.sha``, ensure each
matches ``^Signed-off-by: .+ <.+@.+>$``, fail with a clear message
listing offending commits + the fix command.

Also restore the ``ci-success`` aggregator now that the dco job is
fixed; that job depends on ``[lint, test, precommit, dco]`` and uses
a simple grep over ``toJSON(needs)`` to require zero failures while
allowing skipped (DCO is skipped on push events).

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
@fede-kamel fede-kamel force-pushed the ci/100-percent-enforcement branch from 21d8b2f to 72f25d5 Compare May 1, 2026 01:18
@fede-kamel fede-kamel merged commit 1a8cf70 into main May 1, 2026
10 checks passed
@fede-kamel fede-kamel deleted the ci/100-percent-enforcement branch May 13, 2026 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant