Skip to main content

CI / CD pipeline

GreekManage uses GitHub Actions for CI. Five workflows currently live in .github/workflows/.

Overview

ci.yml — main CI gate

Trigger: push or PR to main

Jobs:

  1. changes — path filter detects which areas of code changed. Drives later jobs to skip unaffected work.
  2. backendpytest (scoped to changed Django apps if filter matched, else full). Postgres + Redis services in the runner.
  3. frontendnpm test (Vitest) + npm run build (production Vite build).
  4. android-buildnpx cap sync android + ./gradlew assembleDebug. Generates a dummy google-services.json for CI.
  5. security:
    • Bandit — Python SAST, fail on HIGH+
    • Semgrep — multi-language SAST with custom rules in .semgrep.yml
    • pip-audit — Python CVE scan
    • npm audit — JS CVE scan (high severity blocks)
    • Trivy — filesystem scan
  6. e2e (in e2e.yml, runs in parallel via reusable workflow):
    • Backend migrations + seed data
    • python manage.py runserver + frontend dev server
    • Playwright @smoke tagged tests (gate; full suite is overnight)
    • ZAP API scan (credentialed) — verifies API surface against vulns
    • ZAP baseline scan (frontend) — passive only
    • Artifacts uploaded for any failures (Playwright traces, ZAP reports)

All required checks must pass before merge.

e2e.yml — end-to-end tests + DAST

Trigger: push or PR; also reusable from ci.yml

What it does:

  • Spins up the full stack via docker-compose.e2e.yml
  • Runs Playwright tests (~132 tests) — @smoke tag for gate, full suite optional
  • Runs OWASP ZAP active scan against the API with valid credentials
  • Runs ZAP baseline (passive) against the frontend
  • Captures traces, screenshots, video on failure

Testing guide

security-nightly.yml — nightly DAST

Trigger: cron at 0 11 * * * (06:00 ET)

What it does:

  • Spins up a clean stack
  • Runs full ZAP active scan (more aggressive than baseline) against API + frontend
  • Opens a GitHub issue with findings if any are HIGH+ severity
  • Issues are deduplicated by date (groups multiple findings into one issue per day)
  • 60-minute timeout

claude-code-review.yml — AI code review

Trigger: PR opened, ready-for-review, or reopened

What it does:

  • Runs anthropics/claude-code-action@v1 against the PR diff
  • Posts review comments inline
  • continue-on-error: true — never blocks merge; advisory only

docs-site.yml — documentation site

Trigger: push or PR touching docs-site/** or the workflow itself

What it does (current):

  • Builds the Docusaurus site
  • Verifies zero broken links / MDX errors
  • Uploads build artifact

What it does (when deploy steps are uncommented):

  • On push to main only: deploy the build to GitHub Pages
  • Cloudflare Pages alternative also commented in

→ See the workflow file

Quality gate (SonarQube)

sonar-project.properties defines the SonarQube project. The CI pipeline reports coverage + code quality to SonarQube; the quality gate enforces:

  • Coverage on new code ≥ 80%
  • No new HIGH or CRITICAL issues
  • No duplications above threshold

A failing quality gate blocks merge.

Required vs optional checks

CheckRequired to merge?
Backend tests✅ Required
Frontend tests✅ Required
Frontend build✅ Required
Android build✅ Required (catches Capacitor sync issues)
Bandit / Semgrep / pip-audit / npm audit / Trivy✅ Required (blocking on HIGH+)
SonarQube quality gate✅ Required
E2E @smoke✅ Required
ZAP API + ZAP baseline✅ Required (no HIGH findings)
Claude Code Review❌ Advisory
Nightly full ZAP❌ Async — failures open an issue

Caching

GitHub Actions caches:

  • ~/.cache/pip keyed by requirements.txt hash
  • node_modules keyed by package-lock.json hash
  • ~/.gradle/caches for Android builds

Drops cache hit ratio noticeably when lockfiles change — expected.

Secrets

Required repository secrets (configure in repo Settings → Secrets):

SecretUsed by
SONAR_TOKENSonarQube quality gate
CLAUDE_CODE_OAUTH_TOKENClaude code review action
E2E_ADMIN_PASSWORDE2E test fixture (creates a known admin user)
GITHUB_TOKENAuto-provided; used for issue creation in nightly scan

For deployment workflows (when you wire them up):

SecretUsed by
KUBECONFIG (base64)Production deploy
GHCR_TOKENImage registry push
CLOUDFLARE_API_TOKEN (optional)Cloudflare Pages docs deploy

Local CI parity

To run the full security suite locally before pushing:

npm run security:full

This wraps Bandit + Semgrep + pip-audit + npm audit + Trivy + secret scanning. Faster than waiting for CI.

For backend tests:

docker compose exec backend pytest

For E2E:

cd e2e && npm test

Adding a new workflow

  1. Create .github/workflows/<name>.yml
  2. Use path filtering to avoid running on unrelated changes:
    on:
    push:
    paths: ['<directory>/**', '.github/workflows/<name>.yml']
  3. If it's a check that should block merge, add it to the required status checks in repo Settings → Branches → main
  4. Document it here

When CI is red

FailureCommon causeFix
Backend tests failMigration not runAdd migration to PR
Frontend build failsTypeScript errorRun npm run typecheck locally
Android build failsCapacitor sync failednpx cap sync android locally
Semgrep new findingNew code matches a ruleFix the issue or add a comment-suppression with a TODO + ticket
pip-audit / npm auditNew CVE in a depUpdate the dep, or pin a known-good version with a justification
ZAP HIGHNew endpoint without auth, or missing CSRFAudit the endpoint
SonarQube quality gateCoverage dropAdd tests for new code