GitHub Actions
CI that lives next to the code, with one workflow file and no second service to sign up for.
Why GitHub Actions
The repo is on GitHub, so GitHub Actions runs checks where the pull requests already are. There's no second account, and results show on the pull request itself. The whole pipeline is one file, .github/workflows/ci.yml.
How it's shaped
- Parallel jobs, not one long pipeline. Lint finishes in under a minute and reports a formatting slip without waiting on Postgres or Chromium.
- A change filter first. The first job lists which checks the pull request's files affect, and every other job reads that list. It counts a workspace's dependencies too, so a
shared-uichange reruns the web-app build. - Real services, not mocks. The backend tests start their own Postgres with Testcontainers. The ZAP job runs Postgres, Mailpit, and RustFS beside the backend.
- Shared setup.
.github/actions/setuprestoresnode_modulesand Playwright's Chromium from cache and installs only on a miss. A second workflow,cache.yml, refreshes that cache from main, so every pull request can use it.