chore(devex): Makefile with a uniform 'make check' (backend#1606) - #461
Open
LukasWodka wants to merge 3 commits into
Open
chore(devex): Makefile with a uniform 'make check' (backend#1606)#461LukasWodka wants to merge 3 commits into
LukasWodka wants to merge 3 commits into
Conversation
Today every repo in the org has a different incantation for "run your tests": `python manage.py test` here, `yarn test:coverage` there, `make ci` in cli, `pytest tests/ -m "not slow"` somewhere else. That makes "run your tests before you push" a rule you can only obey if you already know the repo — which means it is not really a rule, it is tribal knowledge with a rule's wording. The people most likely to break it are exactly the people least likely to know the incantation. backend#1606 fixes that by giving every active repo the same three targets: make check lint + fast tests. Budget: UNDER 60 SECONDS. make check-all everything CI runs, minus the CI-only heavy suites. make setup install what those targets need. The 60-second budget is not decoration. It is the property that decides whether anyone runs the thing: a `make check` that takes ten minutes is a rule people learn to skip, and skipping one rule teaches skipping others. So the split between `check` and `check-all` is drawn on measured wall-clock time, not on taste. The Makefile is a THIN WRAPPER. Every command in it was lifted from the workflow that already runs it. It adds no tool, no config, and no rule, and it changes no CI workflow — making CI call `make check` is a separate, later wave (decision 2 on backend#1606), deliberately kept out of this PR so that a Makefile bug cannot redden the pipeline. No pre-commit or pre-push hook is installed here either; that is step 4. In this repo ------------ `make check` — MEASURED 19 s warm (44 s on the very first cold run, which is filesystem cache, not work): ruff over the tree using this repo's own ruff.toml, then the 1918-test unit suite. The suite mocks both the database and the API, so it needs nothing running. `make check-all` swaps the plain pytest run for tests.yml's exact command, 95% coverage floor included. `make e2e` exists but is in neither target: e2e.yml drives real ingestion against a real MySQL, which CI provides as a service container and a laptop does not. NOT in `check`: black. The code-quality caller does set `format: true`, but the shared gate scans the PR DIFF, and the tree as a whole is not black-clean — 72 files would be reformatted at the time of writing. A whole-tree `black --check` in `check` would be red on a clean checkout, which is worse than not running it. ruff, measured the same way, IS clean tree-wide, so it is in. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cursor Bugbot raised this on the client-runtime PR of the same wave (tracebloc/client-runtime#283, medium severity) and it generalises to every repo here whose dev-dependency file does not already carry ruff: `make check` runs the linter, but `make setup` did not install it, so a developer who followed the advertised setup to the letter still hit `ruff: command not found` on their first `make check`. A setup target that leaves the check target broken is not a setup target. The version is pinned to what the org code-quality gate runs (tracebloc/.github code-quality.yml, `ruff-version` = 0.15.20). Unpinned, a local install and the PR gate can disagree about the same file — ruff's rule set moves between releases. Bump RUFF_VERSION with the workflow, not apart from it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5f6c654. Configure here.
…Bugbot, backend#1606) Two findings from Bugbot on #461. **The important one (medium).** `test` and `coverage` invoked pytest with no path, and this repo sets no `testpaths`, so collection reached `e2e/` as well as `tests/`. In CI that is harmless — nothing is listening on MYSQL_HOST/MYSQL_PORT, so `e2e/conftest.py` skips collection — but on a developer machine with a MySQL running, or with DB_NAME/DB_USER exported, `make check` would have quietly run REAL ingestion that creates and drops tables in that database. A pre-push check must not touch anyone's data, and it certainly must not do so while the help text promises a sub-60-second lint-and-unit-tests run. Both targets are now scoped to `tests/`; `make e2e` runs the e2e suite deliberately, which is the only way it should ever run. This is a deliberate, documented divergence from tests.yml's literal bare `pytest` — the effective set in CI is identical, because e2e/ skips there anyway. **The second one (low).** `lint` shelled out to a bare `ruff` while `setup` pins ruff into `$(PYTHON)`'s environment, so the version that ran need not have been the pinned one. Now `$(PYTHON) -m ruff`. Verified: a pip-installed `ruff==0.15.20` answers `python -m ruff --version` with 0.15.20 and lints identically. Applied across the wave. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
LukasWodka
added a commit
to tracebloc/model-zoo
that referenced
this pull request
Aug 6, 2026
…to (Bugbot, backend#1606) Raised by Cursor Bugbot on tracebloc/data-ingestors#461 (low severity) and applied across the wave rather than in one repo. The lint target shelled out to a bare `ruff` — whatever happened to be first on PATH — while the pinned ruff lives in `$(PYTHON)`'s environment. With a `PYTHON` override, a second virtualenv, or a system-wide homebrew ruff, the version that ran was not the version pinned to match CI, so local and CI could disagree about the same file in exactly the way the pin exists to prevent. `$(PYTHON) -m ruff` resolves to the interpreter's own install and nothing else. Verified: a pip-installed `ruff==0.15.20` answers `python -m ruff --version` with 0.15.20 and lints identically. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Today every repo in the org has a different incantation for "run your
tests":
python manage.py testhere,yarn test:coveragethere,make ciin cli,pytest tests/ -m "not slow"somewhere else. Thatmakes "run your tests before you push" a rule you can only obey if you
already know the repo — which means it is not really a rule, it is
tribal knowledge with a rule's wording. The people most likely to break
it are exactly the people least likely to know the incantation.
backend#1606 fixes that by giving every active repo the same three
targets:
make check lint + fast tests. Budget: UNDER 60 SECONDS.
make check-all everything CI runs, minus the CI-only heavy suites.
make setup install what those targets need.
The 60-second budget is not decoration. It is the property that decides
whether anyone runs the thing: a
make checkthat takes ten minutes isa rule people learn to skip, and skipping one rule teaches skipping
others. So the split between
checkandcheck-allis drawn onmeasured wall-clock time, not on taste.
The Makefile is a THIN WRAPPER. Every command in it was lifted from the
workflow that already runs it. It adds no tool, no config, and no rule,
and it changes no CI workflow — making CI call
make checkis aseparate, later wave (decision 2 on backend#1606), deliberately kept out
of this PR so that a Makefile bug cannot redden the pipeline. No
pre-commit or pre-push hook is installed here either; that is step 4.
In this repo
make check— MEASURED 19 s warm (44 s on the very first cold run,which is filesystem cache, not work): ruff over the tree using this
repo's own ruff.toml, then the 1918-test unit suite. The suite mocks
both the database and the API, so it needs nothing running.
make check-allswaps the plain pytest run for tests.yml's exactcommand, 95% coverage floor included.
make e2eexists but is in neither target: e2e.yml drives realingestion against a real MySQL, which CI provides as a service container
and a laptop does not.
NOT in
check: black. The code-quality caller does setformat: true,but the shared gate scans the PR DIFF, and the tree as a whole is not
black-clean — 72 files would be reformatted at the time of writing. A
whole-tree
black --checkincheckwould be red on a clean checkout,which is worse than not running it. ruff, measured the same way, IS
clean tree-wide, so it is in.
Related
Step 1 of tracebloc/backend#1606 — a
Makefilewith a uniformchecktarget in every active repo. One PR per repo; this is this repo's.Type of change
Test plan
make checkrun for real in a fresh venv: green in 19 s warm (1918 passed,1 xfailed). The very first cold run was 44 s — filesystem cache, not work.
ruff check .clean tree-wide;black --check .NOT clean (72 files would bereformatted), hence excluded.
make helpand the dry runs of every target parse clean.No CI workflow is touched in this PR. CI parity — making the workflows call
make check— is decision 2 on backend#1606 and lands as its own wave, deliberately after the Makefiles exist and are proven locally. No pre-commit or pre-push hook is installed here either; that is step 4.Checklist
.PHONYon every target,helpis the default goalNote
Low Risk
Developer-experience only: adds local Make targets without changing CI, application runtime, or auth/data paths.
Overview
Adds a root
Makefileso local dev matches the org-wide backend#1606 contract:make setup,make check(ruff + fast unit tests), andmake check-all(ruff + pytest with the 95% coverage gate). Commands are documented as thin mirrors of existingtests.yml,e2e.yml, and the shared ruff code-quality workflow—no CI workflow edits in this PR.make testdeliberately runspytest tests/only (not a barepytest), so a machine with MySQL/env vars does not accidentally collecte2e/during pre-push checks;make e2eremains the explicit path for real MySQL ingestion. Ruff is invoked via$(PYTHON) -m ruffwith a pinnedRUFF_VERSIONaligned to CI; black is intentionally omitted fromcheckbecause a whole-tree format check would fail on a clean checkout.Reviewed by Cursor Bugbot for commit e0b75a4. Bugbot is set up for automated code reviews on this repo. Configure here.