CI pipeline
A home-grown CI runner. No GitHub Actions, no CircleCI — just scripts/ci.sh.
Run
cd /var/www/krowforge
scripts/ci.sh # full
scripts/ci.sh --quick # subset (~37s)
The quick subset runs 22 jobs in ~37 seconds. The full pipeline adds slow jobs (full unit suite, browser smoke, lighthouse).
What's checked
| Job | What it does |
|---|---|
py-syntax | Compile every .py with python -m compileall. |
js-syntax | Parse every .js with Node --check. |
css-hex-audit | Find raw hex colors not behind a CSS variable. |
theme-contrast | Computes contrast ratios for theme combinations; fails below threshold. |
keydown-handlers | Static check for keydown listeners that don't call preventDefault correctly. |
secrets-scan | regex scan for committed secrets. |
brief-present | build_brief.md must exist and not have shrunk. |
app-import | import app must succeed; prints registered route count. |
unit-tests | pytest -q. |
usability-walkthrough | Asserts the Tier-3 walkthrough recipe is present in the brief. |
xterm-frontend | Asserts PTY default-on is wired correctly. |
| _and more_ | … |
Each job reports its latency. Total under 60s for the full pipeline.
Pre-push hook
Install once:
scripts/install_git_hooks.sh
Adds a pre-push hook that runs ci.sh --quick. Push fails if any job fails.
To bypass (don't): git push --no-verify. Reviewable in the receipt log.
Adding a job
ci/jobs.py defines each job as a function returning a JobResult. To add:
def job_my_check():
# do something
return JobResult(name="my-check", ok=True, message="…", elapsed=0.1)
Register in JOBS list. Pick --quick membership (cheap fast jobs only).
CI in CI
For people running KrowForge on remote CI (GitHub Actions, etc.), scripts/ci.sh is designed to run cleanly in any Linux environment with Python + Node available. Set NO_COLOR=1 to disable ANSI codes in logs.
Output format
Plain text by default. --json for machine-readable. Each job line:
[ ✓ ] py-syntax 0.42s
[ ✓ ] js-syntax 0.18s
[ ✗ ] secrets-scan 0.05s 2 findings — see report.json
…
PASS 21/22 in 37.69s
Exit code: 0 if all green, 1 otherwise.