Skip to content

maintenance: select ruff rules explicitly so CI is deterministic - #892

Merged
adbar merged 1 commit into
adbar:masterfrom
igorsaevets:ci/deterministic-ruff-rule-selection
Jul 28, 2026
Merged

maintenance: select ruff rules explicitly so CI is deterministic#892
adbar merged 1 commit into
adbar:masterfrom
igorsaevets:ci/deterministic-ruff-rule-selection

Conversation

@igorsaevets

Copy link
Copy Markdown
Contributor

CI is currently red on every pull request, and the cause is outside the changed code.

What happened

ruff 0.16.0 (released 2026-07-25) widened its default rule selection from 59 rules to 413. pyproject.toml asks for ruff >= 0.15 with no upper bound and does not configure [tool.ruff.lint] select, so CI installs whatever is newest and lints against the new defaults.

Reproduced against unmodified master at 3d89493, no other changes in the tree:

ruff ruff check .
0.15.4 All checks passed!
0.16.0 Found 103 errors.

The 103 findings are spread over 31 files and come from rule families that were not previously on by default: BLE001 (22), I001 (18), FURB167 (12), UP031 (11), SIM102 (5), plus RUF, DTZ, S, PL, B, PIE, FLY and C4. None of them are new code.

Confirming it is only the selection and nothing else in the release:

ruff 0.16.0, master, --select E4,E7,E9,F  ->  All checks passed!

The change

One block in pyproject.toml selecting E4, E7, E9, F explicitly. Those are ruff's pre-0.16 defaults, so linting behaviour is unchanged from what the repository has been enforcing, and it no longer moves when ruff changes its mind about defaults.

This is the same reasoning already written down a few lines below for mypy in that file:

# explicit strictness — stable across mypy upgrades, unlike 'strict = true'

Verified after the change:

ruff 0.15.4  ruff check .                          ->  All checks passed!
ruff 0.16.0  ruff check .                          ->  All checks passed!
ruff 0.16.0  ruff format --check trafilatura tests ->  41 files already formatted

ruff format was never affected; only the lint step was.

Not included on purpose

Adopting any of the newly-default rules is a separate judgement call, and 103 mechanical edits do not belong in the same change as a CI repair. Roughly 43 are auto-fixable if you want them. Happy to open a follow-up per rule family, or to add an upper bound like ruff >= 0.15, < 0.17 instead if you prefer pinning the tool over pinning the selection. Your call and I will match whatever you pick.

Found this while checking why #891 was red. That PR touches only htmlprocessing.py, xml.py and tests/unit_tests.py and contributes none of the 103 findings.

ruff 0.16.0 widened its default rule selection from 59 rules to 413. The dev
extra requests an unpinned `ruff >= 0.15`, so `ruff check .` started reporting
103 errors on unmodified code and every open pull request went red.

Verified on 3d89493 with no other changes:

  ruff 0.15.4  ->  All checks passed!
  ruff 0.16.0  ->  Found 103 errors.

Selecting E4/E7/E9/F, ruff's pre-0.16 defaults, restores the previous behaviour
and makes it immune to the next default change. This mirrors the reasoning
already recorded for mypy in the same file: explicit options are stable across
tool upgrades. `ruff format --check` was unaffected and still passes.

Adopting parts of the new rule set is a separate decision and can be done rule
by rule from here.
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.68%. Comparing base (3d89493) to head (ec98b36).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #892   +/-   ##
=======================================
  Coverage   99.68%   99.68%           
=======================================
  Files          21       21           
  Lines        4099     4099           
=======================================
  Hits         4086     4086           
  Misses         13       13           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@adbar

adbar commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Nice, thanks!

@adbar
adbar merged commit 078f9ac into adbar:master Jul 28, 2026
13 checks passed
adbar pushed a commit that referenced this pull request Jul 29, 2026
…ed on Windows (#893)

The 'Lint and format check' step runs two commands in one run: block. With no
shell: key GitHub uses pwsh on Windows, where the step's exit status comes from
$LASTEXITCODE of the last command only. 'ruff format --check' passes, so a
preceding 'ruff check' failure is discarded and the job reports success. On
Linux and macOS the same block runs under 'bash -e' and aborts on the first
failure.

Observed in run 30165454624 (2026-07-25, before #892): every ubuntu and macos
job failed at this step, while build (windows-latest, 3.11) reported success.
Its log contains 'Found 103 errors.' immediately followed by '41 files already
formatted'.

Setting shell: bash gives all three runners the same behaviour.

Co-authored-by: Igor Saevets <igorsaevets@gmail.com>
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.

3 participants