PATH: docs/ci-cd.md
December 28, 2025 · View on GitHub
CI/CD Documentation
This document explains our GitHub Actions workflows, secrets management, and best practices for continuous integration and delivery of the Loventia application.
Ops docs (incidents / production operations)
These are the canonical operational docs used during incidents and production work:
- Ops Runbook (canonical):
./ops/runbook.md - Rollback Playbook (canonical):
./ops/rollback-playbook.md
Notes:
- These links are relative to
docs/(this file).- Keep ops docs canonical under
docs/ops/to avoid duplicate/conflicting playbooks.
1. Workflows Overview
All workflows are located in .github/workflows/.
This section is a high-level map – always check the actual YAML file if you need exact commands or triggers.
1.1 openapi-ci.yml
Purpose
- Validate and bundle the OpenAPI specification for the backend API.
Key responsibilities
- Run Spectral lint on
server/openapi/openapi.yamlusing.spectral.yaml. - Bundle the spec into a single dereferenced file (e.g.
openapi.bundle.yaml) using Redocly. - Upload the bundled spec as a CI artifact so it can be consumed by docs, testing, or tooling.
Typical triggers
push/pull_requestto main branches (e.g.main,dev, feature branches touchingserver/openapi/).- Manual trigger via Actions → openapi-ci → Run workflow.
When it fails
- The OpenAPI spec has lint errors (missing descriptions, invalid refs, schema issues).
- The bundle step cannot resolve references or the spec is syntactically invalid.
When this workflow fails, fix the spec and re-run the workflow before merging.
1.2 server-ci.yml
Purpose
- Run continuous integration checks for the Node.js/Express backend (
server/).
Key responsibilities (high level)
- Set up Node.js (current LTS in the workflow).
- Install backend dependencies (usually
npm ciinserver/). - Run backend tests (and optionally lint/build) via the configured npm scripts.
- Optionally archive test reports or coverage as artifacts.
Note: See
.github/workflows/server-ci.ymlfor the exact Node version, npm scripts, and paths used.
Typical triggers
pushand/orpull_requestto backend-related branches (e.g.main,dev, feature branches).- May also be used on release tags when building for deployment.
When it fails
- Tests or linting fail.
- The backend does not build or dependencies cannot be installed.
Resolve all failing tests/lint issues locally, re-run them (see section 4), and then push the fixes.
1.3 security-scans.yml
Purpose
- Run security scanning for the application:
- OWASP ZAP scan (dynamic application security testing for the frontend).
- Dependency vulnerability checks for server and client.
Jobs
-
zap-scan- Checks out the code.
- Runs OWASP ZAP from the official Docker image against
http://localhost:3000(or URL configured in the workflow). - Uses
security/zap-config.jsonto configure the scan. - Writes reports into
zap-report/and uploads them as artifacts (zap-report.html/.xml).
For accurate ZAP results, the target application (frontend) typically needs to be running.
If the target URL is not reachable, this step may fail and should be adjusted in the workflow. -
dependency-scan-
Checks out the code.
-
Sets up Node.js.
-
Installs dependencies for server (
server/) and client (client/). -
Runs:
# server npm audit --production --audit-level=high --json > ../audit-server.json # client npm audit --production --audit-level=high --json > ../audit-client.json -
Uploads
audit-server.jsonandaudit-client.jsonas artifacts.
-
Vulnerability policy
- The pipeline is configured to fail only on
highorcriticalvulnerabilities. lowandmoderatefindings are logged in the audit reports and should be reviewed regularly, but they do not break CI by default.- Any accepted risk (for example the current
fast-redact/pino/elastic-apm-nodelow-severity chain) should be:- documented in an issue or internal note, and
- revisited when upstream fixes become available.
Typical triggers
- Scheduled run:
cron: '0 3 * * 0'(Sundays at 03:00 UTC). - Manual trigger via Actions → Security Scans → Run workflow.
1.4 Other workflows
Depending on the repository, you may also see additional workflows such as:
client-ci.yml– CI for the React frontend (client/).- Deploy / release workflows – build and push Docker images or deploy to staging/production.
- Lint-only workflows – for ESLint or TypeScript checks.
These should follow the same conventions: clear purpose, explicit triggers, and fail only on issues that must block a merge.
2. Secrets Management
All sensitive values must be stored in GitHub Secrets (Repository or Organization level).
Never commit secrets to the repository.
2.1 Adding secrets
- Navigate to Settings → Secrets and variables → Actions.
- Click New repository secret.
- Add required secrets, for example:
Backend / Auth / Database
MONGO_URIJWT_SECRETREFRESH_TOKEN_SECRET
Stripe / Billing
STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETSTRIPE_PRICE_ID
CI / Tests / Tools
TEST_PASSWORDPERF_PASSWORDCYPRESS_TEST_PASSWORD- Any additional credentials used by external services (email providers, log services, etc.)
Reference secrets in workflows using:
env:
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
or per-step:
- name: Example step
run: echo "Using secret value"
env:
MY_SECRET: ${{ secrets.MY_SECRET }}
2.2 Best practices
-
Limit scope
-
Use separate secrets for development, staging, and production environments.
-
Prefer GitHub Environments:
stagingenvironment has staging-only secrets.productionenvironment has production-only secrets and protections.
-
-
Rotate regularly
- Rotate API keys, access tokens, and passwords periodically.
- Immediately rotate secrets if you suspect they may have been leaked.
-
Audit usage
- Review who can read or modify secrets.
- Clean up unused secrets when services are removed or replaced.
-
Never log secrets
- Do not
echosecrets directly in workflow logs. - Use masking (GitHub does this automatically for secrets) and avoid printing full URLs with embedded credentials.
- Do not
3. Branches, Triggers, and Policies
3.1 Typical branch flow
main– stable, production-ready branch.devor feature branches – active development.
Pull requests into main (and optionally dev) should:
- run all relevant CI workflows (
server-ci,client-ci,openapi-ci), - run security scanning (
security-scanseither on schedule or on demand), - be merged only when all required checks are green.
3.2 Required checks (recommended)
For higher safety, mark at least the following as required checks before merging into main:
- Backend CI (
server-ci.yml) - Client CI (
client-ci.yml, if present) - OpenAPI CI (
openapi-ci.yml) - Security Scans (
security-scans.yml)
This ensures that:
- the backend builds and tests pass,
- the frontend builds and tests pass,
- the API documentation is valid,
- there are no high/critical security issues.
4. Local Preflight Before Pushing
Running a lightweight set of checks locally before pushing reduces CI churn and makes debugging easier.
4.1 Backend preflight (server)
From C:\Loventia.app-new\server:
npm ci
npm test
npm audit --production --audit-level=high
4.2 Frontend preflight (client)
From C:\Loventia.app-new\client:
npm ci
npm test
npm audit --production --audit-level=high
5. Reading and Handling CI Failures
When a workflow fails:
- Go to GitHub → Actions.
- Select the failing workflow run.
- Open the job and step with the red ❌ icon.
- Read the logs from top to bottom and identify the first real error (not just the final summary).
Common cases:
-
OpenAPI CI fails
- Check
server/openapi/openapi.yamland.spectral.yaml. - Fix lint errors (missing
description, broken$ref, invalid types). - Re-run the workflow.
- Check
-
Server CI fails
- Run
npm ciandnpm testlocally inserver/. - Fix failing tests or linting, then push again.
- Run
-
Client CI fails
- Run
npm ciandnpm testlocally inclient/. - Fix React/JS/TS issues reported by tests or ESLint.
- Run
-
Security Scans fail
-
If the failure is due to
npm audit:-
Check the
audit-server.json/audit-client.jsonartifacts. -
For high/critical vulnerabilities:
- try
npm audit fix, - or upgrade offending dependencies in
package.json, - avoid
npm audit fix --forceunless you understand and accept breaking changes.
- try
-
For low/moderate findings:
- document accepted risks,
- track upgrades over time.
-
-
If the failure is in the
zap-scan:- Ensure the target URL is correct and reachable.
- Adjust the ZAP config or disable certain rules only with good reason.
-
Resolve the root cause, commit the fix, and re-run the workflow.
6. Future Improvements
Planned improvements for the CI/CD setup include:
- Enforcing ESLint in CI for both server and client (B-phase).
- Adding Docker build and smoke tests to CI for backend (and optionally frontend).
- Adding Lighthouse / performance budgets to the frontend build pipeline.
- Documenting deployment and rollback steps in more detail (
docs/env.md, deployment runbooks).
Last updated: November 18, 2025