Skip to content

feat(ci): make ruff check and mypy hard CI gates#48

Merged
gumptionthomas merged 2 commits into
mainfrom
feat/ci-strict-gates
May 25, 2026
Merged

feat(ci): make ruff check and mypy hard CI gates#48
gumptionthomas merged 2 commits into
mainfrom
feat/ci-strict-gates

Conversation

@gumptionthomas
Copy link
Copy Markdown
Owner

Summary

  • Removes continue-on-error: true from ruff check and mypy in .github/workflows/tests.yml.
  • Sets [tool.mypy] strict = true in pyproject.toml.
  • Updates CLAUDE.md Style section prose.

PRs 1-7 (+ PR-7.5 fix) cleared the underlying debt; this is the gate flip.

Phase 3 / PR 8 of 9.

Test plan

  • uv run ruff check src tests exits 0.
  • uv run ruff format --check src tests exits 0.
  • uv run mypy src exits 0 under strict = true (24 files).
  • uv run pytest passes (177 passed, 1 skipped).
  • CI green on 3.12 and 3.13 (both as hard gates now).

🤖 Generated with Claude Code

Phase 3 PRs 1-7 (plus the PR-7.5 follow-up fix) cleaned the codebase
to where `ruff check` and `mypy --strict src` both exit 0. This PR
flips the corresponding CI steps to hard gates.

- `.github/workflows/tests.yml`: drop `continue-on-error: true` on both
  `ruff check` and `mypy` steps; remove the now-stale comment blocks
  above them.
- `pyproject.toml [tool.mypy]`: set `strict = true`; remove
  `strict_optional` (implied).
- `src/cancelchain/wallet.py`: restore proper `type: ignore[no-any-return]`
  comments for Crypto library calls that strict mode catches; these are
  legitimate (library has incomplete stubs).
- `CLAUDE.md`: update Style section prose.

Phase 3 / PR 8 of 9.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 17:51
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR flips CI enforcement so ruff check and mypy failures now fail the build, aligning CI with the now-clean lint/type baseline for the cancelchain codebase.

Changes:

  • Removes continue-on-error: true so uv run ruff check … and uv run mypy … are hard CI gates.
  • Updates [tool.mypy] configuration to enable strict = true.
  • Refreshes CLAUDE.md Style section to reflect the new CI gating posture.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
pyproject.toml Enables strict mypy mode and adjusts mypy target configuration.
CLAUDE.md Updates contributor guidance about ruff/mypy gating (but still contains a few now-incorrect statements; see comments).
.github/workflows/tests.yml Makes ruff check and mypy blocking steps by removing continue-on-error.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CLAUDE.md Outdated
## Style

- `ruff` config in `pyproject.toml`: `[tool.ruff]` holds top-level settings (target Python 3.12, `line-length = 80`), `[tool.ruff.lint]` holds the rule selection — large rule set enabled (`A,B,C,DTZ,E,EM,F,FBT,I,ICN,ISC,N,PLC,PLE,PLR,PLW,Q,RUF,S,SIM,T,TID,UP,W,YTT`). Several rules are ignored project-wide — notably `Q000` (single-quote convention enforced via `[tool.ruff.format] quote-style = "single"`) and `S101` (assert allowed in tests). In Phase 1 CI, `ruff check` is `continue-on-error: true` to allow incremental cleanup of pre-existing debt; only `ruff format --check` is a hard gate. Phase 3 removes the `continue-on-error` once the existing lint is cleaned up.
- `ruff` config in `pyproject.toml`: `[tool.ruff]` holds top-level settings (target Python 3.12, `line-length = 80`), `[tool.ruff.lint]` holds the rule selection — large rule set enabled (`A,B,C,DTZ,E,EM,F,FBT,I,ICN,ISC,N,PLC,PLE,PLR,PLW,Q,RUF,S,SIM,T,TID,UP,W,YTT`). Several rules are ignored project-wide — notably `Q000` (single-quote convention enforced via `[tool.ruff.format] quote-style = "single"`) and `S101` (assert allowed in tests). Both `ruff check` and `ruff format --check` are hard CI gates as of Phase 3 / PR 8.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 16f21ed. The Q000 ignore was dropped back in PR-1 of Phase 3 when we added the [tool.ruff.lint.flake8-quotes] inline-quotes = "single" config to match the formatter. Updated the Style section to describe the current enforcement mechanism rather than the stale ignore claim.

Comment thread CLAUDE.md Outdated

- `ruff` config in `pyproject.toml`: `[tool.ruff]` holds top-level settings (target Python 3.12, `line-length = 80`), `[tool.ruff.lint]` holds the rule selection — large rule set enabled (`A,B,C,DTZ,E,EM,F,FBT,I,ICN,ISC,N,PLC,PLE,PLR,PLW,Q,RUF,S,SIM,T,TID,UP,W,YTT`). Several rules are ignored project-wide — notably `Q000` (single-quote convention enforced via `[tool.ruff.format] quote-style = "single"`) and `S101` (assert allowed in tests). In Phase 1 CI, `ruff check` is `continue-on-error: true` to allow incremental cleanup of pre-existing debt; only `ruff format --check` is a hard gate. Phase 3 removes the `continue-on-error` once the existing lint is cleaned up.
- `ruff` config in `pyproject.toml`: `[tool.ruff]` holds top-level settings (target Python 3.12, `line-length = 80`), `[tool.ruff.lint]` holds the rule selection — large rule set enabled (`A,B,C,DTZ,E,EM,F,FBT,I,ICN,ISC,N,PLC,PLE,PLR,PLW,Q,RUF,S,SIM,T,TID,UP,W,YTT`). Several rules are ignored project-wide — notably `Q000` (single-quote convention enforced via `[tool.ruff.format] quote-style = "single"`) and `S101` (assert allowed in tests). Both `ruff check` and `ruff format --check` are hard CI gates as of Phase 3 / PR 8.
- `mypy` runs under `[tool.mypy] strict = true` against `src/cancelchain/` and is a hard CI gate as of Phase 3.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 16f21ed alongside the pyproject.toml drift. Aligned by changing the CI step from uv run mypy src to uv run mypy (no positional args) so the files = ["src/cancelchain"] config controls. Updated the CLAUDE.md line to call out the contract: "invoke with uv run mypy (no positional args) so config and CI agree."

Comment thread pyproject.toml
# MYPY
[tool.mypy]
python_version = "3.12"
files = ["src/cancelchain"]
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same fix in 16f21ed — went with option (a): CI step changed to uv run mypy with no positional args, so the files = ["src/cancelchain"] setting drives the target set everywhere (local + CI). files stays in the config; the explicit-target drift is gone.

Comment thread CLAUDE.md Outdated
Comment on lines 111 to 112
- SQLAlchemy is pinned `<2.0`; don't import from 2.0-only namespaces. Flask-SQLAlchemy is 3.x (uses `db.Model`, `db.session`, classic `Model.query` style).
- pymerkle is pinned `>=4,<5` (block Merkle tree). v5 has breaking changes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 16f21ed. Both lines were leftover from before Phase 2's library upgrades. Updated:

  • SQLAlchemy line now says >=2.0 with Mapped[] annotations on every DAO in models.py, notes Flask-SQLAlchemy 3.1 still preserves the legacy Model.query API, and flags query-style modernization to db.session.execute(db.select(...)) as Phase 6.
  • pymerkle line now says >=5 (currently 6.1.0) with the v5/v6 InmemoryTree API in block.py.

Both reconcile with the actual pyproject.toml constraints.

Addresses Copilot review on PR #48.

1. **\`Q000\` ignore claim was stale.** PR-1 of Phase 3 dropped \`Q000\`
   from the ignore list once the \`[tool.ruff.lint.flake8-quotes]
   inline-quotes = "single"\` config was added. Updated the Style
   section to describe the current quote-style enforcement
   mechanism rather than a no-longer-present ignore.

2. **\`mypy src\` CI invocation drifts from \`files=\` config.** When
   mypy is given an explicit positional target, the \`[tool.mypy] files\`
   setting is ignored. Aligned by:
   - Changing CI step from \`uv run mypy src\` to \`uv run mypy\`
     (no args, so \`files = ["src/cancelchain"]\` controls).
   - Updating the CLAUDE.md mypy line to call this out:
     "invoke with \`uv run mypy\` (no positional args) so config and
     CI agree."

3. **SQLAlchemy/pymerkle pin claims were stale** from Phase 2 — they
   said \`<2.0\` and \`>=4,<5\` but Phase 2 upgraded to \`>=2.0\` and
   \`>=5\` (with \`Mapped[]\` in models.py and InmemoryTree in
   block.py). Updated both lines to reflect current state and point
   at the right next-phase modernization milestones.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gumptionthomas gumptionthomas merged commit 1102dcc into main May 25, 2026
5 checks passed
@gumptionthomas gumptionthomas deleted the feat/ci-strict-gates branch May 25, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants