Skip to content

CI/CD Pipeline

How It Works

Every deployment runs on a GitHub Actions ubuntu-latest runner and follows this sequence:

StepActionDetail
1CheckoutClones the repo at the triggering commit
2Setup Node 22Installs Node.js with npm cache enabled
3Install depsRuns npm ci — exact versions from package-lock.json
4BuildRuns npm run buildVITE_* secrets injected here from GitHub Environment secrets
5Extract commitReads last commit subject for the Slack message
6DeployUploads dist/ to Cloudflare Pages via cloudflare/pages-action@v1
7Notify SlackSends success (green) or failure (red) message

A full run takes 35–50 seconds.

How Secrets Are Injected

Vite replaces all import.meta.env.VITE_* references at build time with their literal values:

ts
// Source code
const client = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
})

// After build (staging)
const client = axios.create({
  baseURL: "https://staging-arc.semalink.africa",
})

GitHub supplies the values from the scoped Environment secrets. The workflow declares environment: staging (or test / prod), which loads that environment's secrets for the run. No secret from one environment is ever available to another.

Triggers

Each workflow triggers on:

  • Push to the corresponding branch (staging, test, prod)
  • Manual dispatch via GitHub → Actions → Run workflow

Production vs Preview Deployments

Cloudflare Pages has two deployment types:

  • Production — served on the custom domain (staging-app.semalink.africa)
  • Preview — served on a one-off *.pages.dev URL only

All three workflows use branch: main and each project has production_branch set to main via the Cloudflare API. This ensures every CI upload goes to production, not a preview.

Internal use only — Sema Link Engineering