What Bones

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-ui change 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/setup restores node_modules and 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.

Used in

  • CI/CD — what runs.
  • CI/CD — the jobs, and how to add one.