6.7 KiB
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:
- Trunk-Based Development: All work is merged to
mainbranch. - Automated Test Deployment: Every push to
maintriggers deployment to test environment. - Manual Production Deployment: Production deployments require explicit confirmation.
- 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
mainbranch - Feature branches are short-lived (< 1 day)
- Every merge to
maintriggers 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:
- Calculate hash of
sql/master_schema_rollup.sql - Compare with hash in target database
- If mismatch: FAIL deployment (manual migration required)
- If match: Continue deployment
- 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 workflowecosystem.config.cjs- PM2 configuration