Preskoči na sadržaj

Lokalni CI parity — puna komanda

TL;DR

Prije push-a pokreni potpuni lokalni gate (bandit + markdownlint + sve ostalo). ruff/pylint/pytest zelen ≠ pipeline zelen — Lint & Security step u pipeline-u radi ceo repo (uključujući tests/ + .md), ne samo changed fajlove.

Puna komanda

ci/syntax/validate.py &&
  ci/shellcheck/lint.py . &&
  ci/ruff/lint.py . &&
  CI_PYLINT_JOBS=8 ci/pylint/lint.py ci/ tests/ --changed &&
  ci/bandit/scan.py . &&
  ci/docker/compose_validate.py deploy/schemas-mirror/docker-compose.yml &&
  ci/hadolint/lint.py deploy/schemas-mirror/Dockerfile &&
  ci/markdownlint/lint.py . --exclude .claude/ --exclude .planning/ &&
  ci/pyright/lint.py &&
  ci/pytest/test.py tests/ -n auto --dist worksteal &&
  ci/bats/test.py tests/

Šta svaki alat radi (ukratko)

Alat Šta Zašto
syntax/validate.py py_compile + bash -n Statički syntax check, ne radi analizu
shellcheck/lint.py Shell lint Shell skripte (consumer .sh)
ruff/lint.py Python lint (FATAL only) Brz, hvata očigledne greške
pylint/lint.py Python analiza PR-strict: FAIL_UNDER=9.5 --changed
bandit/scan.py Python security B310 suppressed, medium+ severity
compose_validate.py Docker Compose schema Inode-pinning regression guard
hadolint/lint.py Dockerfile lint dockerized (no host binary)
markdownlint/lint.py Markdown lint CI ceo repo, ne samo docs/bible/
pyright/lint.py Type check Deploy verb family, pinned npx
pytest/test.py Python testovi -n auto --dist worksteal
bats/test.py Shell testovi test_ci_download_scripts.bats

Tri najčešća "lokalno zeleno, pipeline crveno" uzroka

1. Bandit B108 (hardcoded /tmp)

# Ovo FAIL-a bandit B108 u pipeline, lokalno možda neće:
with open("/tmp/myfile.json") as f:
    data = json.load(f)

bandit radi ceo repo, uključujući test data. Čak i u fixtures, /tmp literal pali B108. Fix: koristi tempfile.mkdtemp() ili tmp_path pytest fixture.

2. markdownlint MD004 / MD038

# MD004: lista sa početkom `+` pa `*`
- item 1
* item 2

# MD038: unutrašnji backticks u postojećem code-span
Use the `\`ls\`` command.

markdownlint lintuje ceo .md tree. Locally može proći jer editor ne prijavljuje.

3. Pylint PR-strict gate

Lokalni default threshold je 9.0. PR-strict je 9.5 + --changed.

# Lokalno:
ci/pylint/lint.py ci/ tests/

# PR-strict (šta pipeline radi):
CI_PYLINT_FAIL_UNDER=9.5 ci/pylint/lint.py ci/ tests/ --changed

Razlika od 0.5 izgleda mala, ali je dovoljna da te pipka.

Kada preskočiti (i zašto NE)

Ne postoji legitimno "preskoči gate". Ako misliš da treba:

  1. Ako alati imaju bug → file issue, fix alat, NE preskači.
  2. Ako test fajl baca false-positive# pylint: disable=... sa dokumentovanim razlogom inline. Bez razloga = "scope creep", review fail.
  3. Ako je hitan hotfix → push, monitor, fix posle. Ali NE preskači lokalni gate (trenutno traje <5 min).

Vidi i