Skip to content

chore(devex): Makefile with a uniform 'make check' (backend#1606) - #461

Open
LukasWodka wants to merge 3 commits into
developfrom
chore/1606-makefile-check
Open

chore(devex): Makefile with a uniform 'make check' (backend#1606)#461
LukasWodka wants to merge 3 commits into
developfrom
chore/1606-makefile-check

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

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.

Related

Step 1 of tracebloc/backend#1606 — a Makefile with a uniform check target in every active repo. One PR per repo; this is this repo's.

Type of change

  • Tech-debt / refactor (developer experience)

Test plan

make check run 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 be
reformatted), hence excluded.

make help and 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

  • Works from a clean checkout — .PHONY on every target, help is the default goal
  • No CI workflow modified
  • No pre-commit / pre-push hook installed
  • No secrets / credentials in the diff
  • Every command is copied from the workflow that already runs it — no new tool, no new config, no new rule
  • Portable to GNU Make 3.81 (the macOS system make)

Note

Low Risk
Developer-experience only: adds local Make targets without changing CI, application runtime, or auth/data paths.

Overview
Adds a root Makefile so local dev matches the org-wide backend#1606 contract: make setup, make check (ruff + fast unit tests), and make check-all (ruff + pytest with the 95% coverage gate). Commands are documented as thin mirrors of existing tests.yml, e2e.yml, and the shared ruff code-quality workflow—no CI workflow edits in this PR.

make test deliberately runs pytest tests/ only (not a bare pytest), so a machine with MySQL/env vars does not accidentally collect e2e/ during pre-push checks; make e2e remains the explicit path for real MySQL ingestion. Ruff is invoked via $(PYTHON) -m ruff with a pinned RUFF_VERSION aligned to CI; black is intentionally omitted from check because 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.

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>
@LukasWodka LukasWodka self-assigned this Aug 6, 2026
Comment thread Makefile
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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ 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.

Comment thread Makefile Outdated
Comment thread Makefile Outdated
…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>
@LukasWodka
LukasWodka requested a review from divyasinghds August 6, 2026 11:00
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.

1 participant