Files
flyer-crawler.projectium.com/docs/adr/0017-ci-cd-and-branching-strategy.md

6.7 KiB

ADR-017: CI/CD and Branching Strategy

Date: 2025-12-12

Status: Accepted

Implemented: 2026-01-09

Context

The project has Gitea workflows but lacks a documented standard for how code moves from a developer's machine to production. This can lead to inconsistent deployment processes and uncertainty about code quality.

Decision

We will formalize the end-to-end CI/CD process using:

  1. Trunk-Based Development: All work is merged to main branch.
  2. Automated Test Deployment: Every push to main triggers deployment to test environment.
  3. Manual Production Deployment: Production deployments require explicit confirmation.
  4. Semantic Versioning: Automated version bumping on deployments.

Consequences

  • Positive: Automates quality control and creates a safe, repeatable path to production. Increases development velocity and reduces deployment-related errors.
  • Negative: Initial setup effort for the CI/CD pipeline. May slightly increase the time to merge code due to mandatory checks.

Implementation Details

Branching Strategy

Trunk-Based Development:

main ─────●─────●─────●─────●─────●─────▶
          │     │     │     │     │
          │     │     │     │     └── Deploy to Prod (manual)
          │     │     │     └── v0.9.70 (patch bump)
          │     │     └── Deploy to Test (auto)
          │     └── v0.9.69 (patch bump)
          └── Feature complete
  • All development happens on main branch
  • Feature branches are short-lived (< 1 day)
  • Every merge to main triggers test deployment
  • Production deploys are manual with confirmation

Pipeline Stages

Deploy to Test (Automatic on push to main):

jobs:
  deploy-to-test:
    steps:
      - Checkout code
      - Setup Node.js 20
      - Install dependencies (npm ci)
      - Bump patch version (npm version patch)
      - TypeScript type-check
      - Prettier check
      - ESLint check
      - Run unit tests with coverage
      - Run integration tests with coverage
      - Run E2E tests with coverage
      - Merge coverage reports
      - Check database schema hash
      - Build React application
      - Deploy to test server (rsync)
      - Install production dependencies
      - Reload PM2 processes
      - Update schema hash in database

Deploy to Production (Manual trigger):

on:
  workflow_dispatch:
    inputs:
      confirmation:
        description: 'Type "deploy-to-prod" to confirm'
        required: true

jobs:
  deploy-production:
    steps:
      - Verify confirmation phrase
      - Checkout main branch
      - Install dependencies
      - Bump minor version (npm version minor)
      - Check production schema hash
      - Build React application
      - Deploy to production server
      - Reload PM2 processes
      - Update schema hash

Version Bumping Strategy

Trigger Version Change Example
Push to main (test deploy) Patch bump 0.9.69 → 0.9.70
Production deploy Minor bump 0.9.70 → 0.10.0
Major release Manual 0.10.0 → 1.0.0

Commit Message Format:

ci: Bump version to 0.9.70 [skip ci]

The [skip ci] tag prevents version bump commits from triggering another workflow.

Database Schema Management

Schema changes are tracked via SHA-256 hash:

CREATE TABLE public.schema_info (
  environment VARCHAR(50) PRIMARY KEY,
  schema_hash VARCHAR(64) NOT NULL,
  deployed_at TIMESTAMP DEFAULT NOW()
);

Deployment Checks:

  1. Calculate hash of sql/master_schema_rollup.sql
  2. Compare with hash in target database
  3. If mismatch: FAIL deployment (manual migration required)
  4. If match: Continue deployment
  5. After deploy: Update hash in database

Quality Gates

Check Required Blocking
TypeScript type-check No (continue-on-error)
Prettier formatting No
ESLint No
Unit tests No
Integration tests No
E2E tests No
Schema hash check Yes
Build Yes

Environment Variables

Secrets are injected from Gitea repository settings:

Secret Test Production
DB_DATABASE_TEST / DB_DATABASE_PROD flyer-crawler-test flyer-crawler
REDIS_PASSWORD_TEST / REDIS_PASSWORD_PROD *** ***
VITE_GOOGLE_GENAI_API_KEY_TEST / VITE_GOOGLE_GENAI_API_KEY *** ***

Coverage Reporting

Coverage reports are generated and published:

https://flyer-crawler-test.projectium.com/coverage/

Coverage merging combines:

  • Unit test coverage (Vitest)
  • Integration test coverage (Vitest)
  • E2E test coverage (Vitest)
  • Server V8 coverage (c8)

Gitea Workflows

Workflow Trigger Purpose
deploy-to-test.yml Push to main Automated test deployment
deploy-to-prod.yml Manual Production deployment
manual-db-backup.yml Manual Create database backup
manual-db-restore.yml Manual Restore from backup
manual-db-reset-test.yml Manual Reset test database
manual-db-reset-prod.yml Manual Reset production database
manual-deploy-major.yml Manual Major version release
manual-redis-flush-prod.yml Manual Flush Redis cache

Key Files

  • .gitea/workflows/deploy-to-test.yml - Test deployment pipeline
  • .gitea/workflows/deploy-to-prod.yml - Production deployment pipeline
  • .gitea/workflows/manual-db-backup.yml - Database backup workflow
  • ecosystem.config.cjs - PM2 configuration