From 53c1a34a92c702ad8f44460d567106c4c8e2b828 Mon Sep 17 00:00:00 2001 From: Jonny Spicer Date: Tue, 11 Aug 2026 01:14:20 +0000 Subject: [PATCH 1/2] Standardise ruff configuration Adopt the shared offworldlabs ruff standard (E,W,F,I,B,UP,S,SIM at 120 columns, with the documented ignore list from Tower-Finder, which had the most considered config in the org). Apply ruff's auto-fixes and resolve the remainder by hand. Pinned to ruff==0.16.2: an unpinned ruff picks up new rules on release and turns a green branch red without anything in the repo changing. --- .github/workflows/lint.yml | 22 +++++++++++++++++++ ruff.toml | 44 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 .github/workflows/lint.yml create mode 100644 ruff.toml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..96d6a1d --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,22 @@ +name: lint + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + # Pinned deliberately: an unpinned ruff picks up new rules on release and + # turns a green branch red without anything in this repo changing. + - run: pip install ruff==0.16.2 + + - run: ruff check . diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..c82d4f7 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,44 @@ +# Shared ruff standard for offworldlabs Python repos. +# Keep in sync across repos; see offworldlabs/ops for the canonical copy. + +line-length = 120 +target-version = "py311" + +[lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "UP", # pyupgrade + "S", # flake8-bandit (security) + "SIM", # flake8-simplify +] +ignore = [ + "E501", # line too long — handled by formatter + "E402", # module-level import not at top — env setup before imports is intentional + "S101", # assert in tests is fine + "S104", # binding to 0.0.0.0 is intentional (Docker) + "S105", # hardcoded password false positives on dev defaults + "S106", # hardcoded password false positives + "S110", # try-except-pass is used intentionally + "S112", # try-except-continue is intentional in iteration + "S310", # URL open audit — URLs are constructed internally + "S311", # pseudo-random is fine for non-crypto uses + "S501", # requests without verify — internal calls + "S603", # subprocess calls are in controlled scripts + "S607", # partial executable path is fine for scripts + "B008", # function call in default arg — Depends() is FastAPI pattern + "B905", # zip strict — not needed everywhere + "SIM102", # nested if — readability preference + "SIM105", # contextlib.suppress — try/except is more explicit + "SIM108", # ternary operator — readability preference + "SIM117", # combine with statements — readability preference + "UP017", # datetime.UTC — cosmetic, timezone.utc is fine + "UP028", # yield from — explicit loop is clearer +] + +[lint.per-file-ignores] +"tests/*" = ["S", "B"] +"scripts/*" = ["S", "E"] From 156eada1113087a55fec548d21e8a63a1e79ea50 Mon Sep 17 00:00:00 2001 From: Jonny Spicer Date: Tue, 11 Aug 2026 01:22:57 +0000 Subject: [PATCH 2/2] Scope lint push trigger to main Bare 'on: push' alongside 'pull_request' runs the job twice on every PR commit. Matches the convention in the repos that already had CI. --- .github/workflows/lint.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 96d6a1d..6ba65c8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,6 +2,7 @@ name: lint on: push: + branches: [main] pull_request: workflow_dispatch: