make lint (wired to run flowsint-app prettier/eslint in 88828c5f) needs
Node/yarn, but the job calling it only set up uv — prettier was missing
from PATH. Add setup-node + yarn install. Also drop the now-redundant
frontend-lint job: it duplicated the same checkout/install/format/lint
steps that make lint already runs in python-lint.
lint-staged@17.3.0 requires node >=22.22.1; CI pinned node 20, so
yarn install failed outright on every frontend job (lint, typecheck,
tests) before any real check ran.
One tool instead of three, one config instead of four duplicated
blocks. black/isort/flake8 dropped from every package's dev deps,
ruff added once; .flake8 deleted, [tool.black]/[tool.isort] blocks
deleted from all 4 sub-package pyproject.toml files.
Config lives once, at the workspace root: ruff walks up from any file
it's checking until it finds a pyproject.toml with a [tool.ruff]
table (verified empirically — a package's own pyproject.toml lacking
that table doesn't stop the search), so the root-level [tool.ruff]
applies to all four packages without duplication. That's the one real
win over the old per-package black/isort blocks, which had to be
copy-pasted four times and kept in sync by hand.
Same rule surface as before, not more: select = E/F/W/I (pycodestyle
+ pyflakes + isort-equivalent), matching exactly what flake8 checked.
ruff has other rule groups (UP/pyupgrade, B/bugbear) that would
surface real things — deliberately left off. Turning those on finds
new debt and is a separate decision with its own diff to review, not
a side effect of swapping the tool underneath an unchanged rule set.
Same E501 exclusion carried over too, same reasoning: the formatter
is the sole authority on line length.
known-first-party carries over unchanged (same isort concern this
repo already fixed once — see "app" vs "flowsint_api" in the ratchet
history) and the wildcard-import per-file-ignore for
flowsint_core/__init__.py still applies, verified directly.
Six files reformatted by `ruff format` where it disagreed with black
on edge cases (import grouping, ternary line-breaking, blank lines
after a class statement) — all cosmetic, no behavior change, reviewed
diff by diff. One real ruff-check finding (an import block ruff's
isort-equivalent wanted sorted differently) — took ruff check --fix.
Verified: `make lint` clean, `make test` green (all 4 packages),
lint-staged tested with a real staged-file run (not just config
inspection) to confirm `uv run ruff format` / `uv run ruff check --fix`
actually execute, mypy ratchet target unaffected (still fires on its
own pre-existing backlog, unrelated to this change).
flake8/mypy/eslint were configured (or, for eslint, declared) but no CI
job and no pre-commit hook ever executed them — black/isort/flake8 had
no line-length agreement either (flake8 defaulted to 79, black to 88).
- .flake8: align max-line-length with black, ignore black-conflicting
codes, carve out the one file with an intentional wildcard-export API
- Makefile: `make lint` (black/isort/flake8, blocking — repo is clean),
`make typecheck` (mypy, ratcheted to files the branch touched — ~2200
pre-existing errors workspace-wide, not fixed blindly in one pass)
- .github/workflows/lint.yml: runs the above in CI, plus the frontend
equivalents (prettier/eslint blocking where clean, eslint/tsc
ratcheted where not)
- .github/workflows/tests.yml: add the vitest job that never existed
- flowsint-app/.eslintrc.cjs: parser was declared but never installed
(yarn lint threw immediately) — install @typescript-eslint/*, add
react-hooks/recommended; no-explicit-any set to warn (real backlog,
not fixed blindly)
- lint-staged + husky pre-commit: mirrors the CI checks that are
actually clean today (black/isort/flake8, prettier). eslint is left
out of pre-commit on purpose — its backlog would block unrelated
commits; it stays a CI-only ratchet until paid down.
workflow_dispatch button to bump version (patch/minor/major/custom),
update CHANGELOG.md, commit, tag and push to main via standard-version
— reusing the existing yarn release / sync-versions.js / .versionrc
setup instead of duplicating bump logic in YAML. The tag push then
triggers images.yml as-is.
Requires a GH_PAT secret: pushes made with the default GITHUB_TOKEN
don't trigger other workflows (GitHub anti-loop policy), so a plain
checkout token would silently skip the images.yml build.
sync-versions.js now also bumps the 4 workspace pyproject.toml files
(flowsint-api/core/enrichers/types) — previously only root
pyproject.toml and flowsint-app/package.json were kept in sync.
standard-version added as an explicit devDependency (was only
resolved transitively via yarn.lock before).
Single entrypoint: CI calls `make test`, same as local development,
so the two can't drift. uv handles Python (.python-version) and
dependency sync; cache keyed on uv.lock.
Also add flowsint-api to `make test` — its suite existed but was
never wired in.