CI/CD
This document describes the Continuous Integration and Continuous Deployment (CI/CD) pipeline used in the My Dashboard project.
Overview
The project uses GitHub Actions for CI/CD automation. The pipeline ensures code quality, runs tests, and deploys to production automatically.
Pipeline Architecture
Workflows
1. PR Validation (pr-validation.yml)
Trigger: Pull requests to main or develop
Jobs:
- Basic Validation - Validates commits, PR title, detects changes
- Client Validation - Runs when client files change
- Server Validation - Runs when server files change
- Cron Validation - Runs when cron files change
- Packages Validation - Runs when package files change
- Tests Validation - Runs integration and E2E tests
- Validation Summary - Aggregates results
Example:
name: PR Validation
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- main
- develop
jobs:
basic-validation:
if: github.event.pull_request.draft == false
uses: ./.github/workflows/basic-validation.yml
with:
pr-title: ${{ github.event.pull_request.title }}
base-sha: ${{ github.event.pull_request.base.sha }}
head-sha: ${{ github.event.pull_request.head.sha }}
pr-number: ${{ github.event.pull_request.number }}
2. Basic Validation (basic-validation.yml)
Purpose: Validate commits, PR title, and detect file changes
Steps:
- Validate Commits - Check conventional commit format
- Validate PR Title - Check conventional commit format
- Detect Changes - Determine which files changed
- Check TODOs - Find TODO/FIXME comments
Change Detection:
- name: Detect changes
uses: dorny/paths-filter@v3
with:
filters: |
client:
- 'client/**'
server:
- 'server/**'
cron:
- 'cron/**'
packages-sdk:
- 'packages/sdk/**'
packages-types:
- 'packages/types/**'
3. Client Validation (validate-client.yml)
Trigger: When client files change
Steps:
- Setup - Checkout code, setup Node.js
- Build Dependencies - Build types and SDK packages
- Lint - Run ESLint
- Type Check - Run TypeScript compiler
- Build - Build client for production
- Test - Run unit tests
Example:
- name: Run ESLint
run: pnpm --filter=client run lint
- name: Type check
run: pnpm --filter=client run typecheck
- name: Build client
run: pnpm --filter=client run build
- name: Run unit tests
run: pnpm --filter=client run test
4. Server Validation (validate-server.yml)
Trigger: When server files change
Services:
- MySQL 8.0 (for testing)
Steps:
- Setup - Checkout code, setup Node.js, start MySQL
- Build Dependencies - Build types package
- Lint - Run ESLint
- Type Check - Run TypeScript compiler
- Build - Build server
- Migrate - Test database migrations
- Test - Run unit tests
Example:
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: test_password
MYSQL_DATABASE: test_db
ports:
- 3306:3306
steps:
- name: Test database migrations
env:
MYSQL_HOST: localhost
MYSQL_PORT: 3306
MYSQL_USER: root
MYSQL_PASSWORD: test_password
MYSQL_DATABASE: test_db
run: pnpm --filter=server run migrate
- name: Run unit tests
run: pnpm --filter=server run test
5. Cron Validation (validate-cron.yml)
Trigger: When cron files change
Steps:
- Setup - Checkout code, setup Node.js
- Build Dependencies - Build types and SDK packages
- Type Check - Run TypeScript compiler
- Lint - Run ESLint
- Build - Build cron jobs
- Test - Run unit tests
6. Integration Tests (run-integration-tests.yml)
Trigger: When integration test files change or manually
Services:
- MySQL 8.0
- Redis
Steps:
- Setup - Checkout code, setup Node.js
- Start Services - MySQL, Redis
- Build Dependencies - Build all required packages
- Start Server - Run server in background
- Run Tests - Execute integration tests
- Upload Results - Save test results on failure
Example:
- name: Run integration tests
run: |
cat > .env << EOF
NODE_ENV=test
SERVER_URL=http://localhost:3000
API_SECURITY_KEY=${{ secrets.API_SECURITY_KEY }}
MYSQL_HOST=localhost
MYSQL_PORT=3306
EOF
npm test -- --bail
7. E2E Tests (validate-tests-e2e.yml)
Trigger: When E2E test files change or manually
Steps:
- Setup - Checkout code, setup Node.js
- Install Dependencies - Install E2E test dependencies
- Lint - Run ESLint
- Type Check - Run TypeScript compiler
Note: Full E2E tests run separately with browser automation
8. Documentation Deployment (deploy-project-documentation.yml)
Trigger: Push to main branch
Steps:
- Setup - Checkout code, setup Node.js
- Install - Install documentation dependencies
- Build - Build Docusaurus site
- Upload - Upload build artifact
- Deploy - Deploy to GitHub Pages
Example:
- name: Build documentation
run: npm run build
working-directory: ./docs
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v4
Environment Variables
Client
VITE_API_BASE_URL=https://api.mydashboard.com
VITE_FIREBASE_API_KEY=...
VITE_FIREBASE_PROJECT_ID=...
VITE_FIREBASE_MESSAGING_SENDER_ID=...
VITE_FIREBASE_APP_ID=...
Server
NODE_ENV=production
PORT=3000
API_SECURITY_KEY=...
MYSQL_HOST=...
MYSQL_PORT=3306
MYSQL_USER=...
MYSQL_PASSWORD=...
MYSQL_DATABASE=...
REDIS_URL=...
GITHUB_TOKEN=...
JIRA_API_TOKEN=...
FIREBASE_PROJECT_ID=...
Cron
NODE_ENV=production
API_URL=https://api.mydashboard.com
API_SECURITY_KEY=...
REDIS_URL=...
E2E_REPORT_CRON_SCHEDULE=0 9 * * *
CLEAN_UP_OLD_REPORTS_CRON_SCHEDULE=0 3 * * 0
Secrets Management
Secrets are stored in GitHub Secrets and Railway environment variables.
GitHub Secrets:
API_SECURITY_KEY- API authentication keyRAILWAY_TOKEN- Railway deployment token (if needed)
Railway Environment Variables:
- All production environment variables
- Managed through Railway dashboard
- Separate variables per service
Deployment Process
Automatic Deployment
Trigger: Merge to main branch
Flow:
- GitHub Actions - Run all validation workflows
- Railway Webhook - Triggered on push to main
- Railway Build - Build each service
- Railway Deploy - Deploy services
- Health Checks - Verify deployment
Manual Deployment
Railway Dashboard:
- Navigate to service
- Click "Deploy"
- Select commit or branch
- Confirm deployment
Railway CLI:
# Install Railway CLI
npm install -g @railway/cli
# Login
railway login
# Link project
railway link
# Deploy
railway up
Health Checks
Server Health Check
app.get('/health', (req, res) => {
res.status(200).json({
status: 'healthy',
timestamp: new Date().toISOString(),
});
});
Railway Configuration:
{
"healthcheck": {
"path": "/health",
"interval": 30,
"timeout": 10
}
}
Client Health Check
Static files are served by Railway's CDN. Health is determined by successful HTTP responses.
Rollback Procedures
Railway Rollback
Dashboard:
- Go to service deployments
- Find previous successful deployment
- Click "Redeploy"
CLI:
# List deployments
railway deployments
# Rollback to specific deployment
railway rollback <deployment-id>
Git Rollback
# Revert last commit
git revert HEAD
# Push to main
git push origin main
# Railway will automatically deploy the reverted state
Monitoring and Logs
Railway Logs
Dashboard:
- Navigate to service
- Click "Logs" tab
- Filter by service, time, level
CLI:
# View logs
railway logs
# Follow logs
railway logs --follow
# Filter by service
railway logs --service server
GitHub Actions Logs
- Go to repository
- Click "Actions" tab
- Select workflow run
- View job logs
Best Practices
CI/CD
- Fast Feedback - Keep workflows fast (< 10 minutes)
- Fail Fast - Stop on first failure
- Parallel Jobs - Run independent jobs in parallel
- Cache Dependencies - Cache node_modules
- Minimal Secrets - Only store necessary secrets
Testing in CI
- Isolated Tests - Tests should not depend on each other
- Clean State - Reset database/state between tests
- Timeouts - Set reasonable timeouts
- Retry Logic - Retry flaky tests (sparingly)
Deployment
- Zero Downtime - Use health checks and rolling deployments
- Database Migrations - Run migrations before deployment
- Environment Parity - Keep dev/staging/prod similar
- Rollback Plan - Always have a rollback strategy
Troubleshooting
Workflow Failures
Check Logs:
# View workflow logs in GitHub Actions
# Look for error messages and stack traces
Common Issues:
- Dependency installation failures → Clear cache
- Test failures → Run tests locally
- Build failures → Check TypeScript errors
- Deployment failures → Check Railway logs
Deployment Issues
Railway Service Not Starting:
- Check environment variables
- Check health check endpoint
- Review build logs
- Check resource limits
Database Migration Failures:
- Check database connection
- Review migration files
- Check for conflicts
- Rollback and retry
Performance Issues
Slow Workflows:
- Enable caching
- Parallelize jobs
- Reduce test scope
- Optimize build process
Slow Deployments:
- Optimize Docker images
- Reduce build artifacts
- Use build caching
- Optimize dependencies
Next Steps
- Testing - Testing guidelines
- Deployment - Deployment architecture
- Troubleshooting - Common issues