Skip to content

Continuous Integration & Deployment

Danei1 edited this page May 12, 2025 · 1 revision

CI / CD – how we keep the project healthy

This page explains what runs in GitHub Actions, why we built it that way, and what it checks.

1. The four workflows we use

File When it fires What it does (short version)
ci-backend.yml every push / PR installs Node 22 in backend/, runs npm ci.
ci-frontend.yml every push / PR installs deps in frontend/, lints the code, builds the static bundle, runs Jest tests.
ci-docker-compose.yml merge to master starts the full Docker-Compose stack, , then runs mocha integration tests inside the running backend container.
cd-demo.yml merge to master (or manual dispatch) starts the same compose stack on our self-hosted runner and opens a Cloudflare quick-tunnel so reviewers get a public HTTPS link.

2. What gets checked on every push

Phase Backend Frontend Integration
Dependency install npm ci (uses package-lock.json) same Docker Buildx layers
Static analysis — ESLint (auto-fix) —
Unit / component tests (todo) Jest + React Testing Library —
Integration tests mocha + chai against live services — mocha again, but this time through Docker Compose
Smoke probe — — curl /api-docs so we fail fast if backend never boots

If one of those steps goes red, the workflow stops and GitHub blocks the merge. It’s a simple gate but it already caught missing env-vars, broken imports and a typo in a route.


3. Why we didn’t emulate EC2 in LocalStack Pro

We tried three options for “how do we show a running site”:

  1. LocalStack Pro EC2 emulation
    Needs a paid licence. It boots each “EC2” instance as a nested Docker container with no public IP. We’d still have to expose it with a tunnel.

  2. Real AWS (ECS / App Runner / a t3.micro EC2)
    Works fine, but we’d have to burn personal credits.

  3. Cloudflare quick-tunnel ⇦ we chose this
    Free, one command, URL is live in ~5 seconds. Only downside is that the tunnel dies when the workflow ends, so we only have ephemeral servers, which for demoing is ok.


4. How the demo workflow works (step-by-step)

  1. Checkout the repo.
  2. docker compose up --build -d – starts backend, frontend, Redis, LocalStack, MailDev.
  3. cloudflared tunnel --url http://localhost:5173 – Cloudflare prints something like
    https://purple-fox-42.trycloudflare.com.
  4. The workflow keeps running in the foreground, so the tunnel stays alive.
  5. When we’re done showing the site we hit Cancel workflow; GitHub kills the tunnel and the containers. No cleanup scripts needed.

5. Keeping local dev and CI identical

  • Everything – Redis, LocalStack, MailDev, frontend, backend – lives in the same docker-compose.yml.
  • Env vars are in .env.example; CI just exports them inline.
  • Vite dev-server is configured with allowedHosts: '.trycloudflare.com so the Host header is accepted.

So “works on my machine” really does work in CI and in the tunnel.


6. Stuff we still want to add

  • Code-coverage gate (fail if Jest < 80 %).
  • Dependabot + npm audit for CVE noise.
  • Playwright E2E tests for the React UI.
  • Maybe move the demo step to AWS App Runner once the free-trial credits are sorted.

In one sentence

Every push is linted, built, and tested; every merge to master is online behind a free Cloudflare URL within three minutes – no paid AWS, no localstack pro license needed.