This guide explains the GitHub Actions CI/CD pipeline for dispatchCore and how to:
- Understand the workflow
- Debug failing builds
- Optimize pipeline performance
- Deploy to production
- Pipeline Architecture
- Workflow Stages
- Configuration
- Debugging Failed Builds
- Performance Optimization
- Deployment
- Monitoring
Location: .github/workflows/ci-cd.yml
Trigger Events:
pushtomainordevelopbranchespull_requesttomainordevelopbranches
┌─────────────────────────────────────────────────────────────┐
│ Code Push / PR Created │
└────────────────────────┬────────────────────────────────────┘
│
┌────────────────┴────────────────┐
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Backend Lint │ │ Frontend Lint │
│ - ESLint │ │ - ESLint │
│ - Prettier │ │ - TypeScript │
│ - Node 18.x, 20.x │ │ - Build check │
└──────┬───────────────┘ └──────┬───────────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Backend Tests │ │ Frontend Tests │
│ - Unit Tests │ │ - Unit Tests │
│ - Integration Tests │ │ - Component Tests │
│ - MySQL Service │ │ - Coverage Upload │
│ - Coverage Upload │ └──────┬───────────────┘
└──────┬───────────────┘ │
│ │
└────────────────┬──────────────┘
│
┌───────────────┴───────────────┐
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Security Audit │ │ Build Artifacts │
│ - npm audit │ │ (main only) │
│ - Continue on error │ │ - Create dist │
└──────────────────────┘ │ - Upload artifact │
└──────┬───────────────┘
│
▼
┌──────────────────────┐
│ Notify Status │
│ - Summary check │
│ - Pass/Fail result │
└──────────────────────┘
Purpose: Check code quality with multiple Node versions
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]Steps:
- Checkout code
- Setup Node.js with caching
- Install dependencies (
npm ci) - Run ESLint
- Check Prettier formatting
Success Criteria:
- No linting errors on all Node versions
- Code formatted correctly
- All dependencies resolve
Typical Duration: 30-45 seconds
Purpose: Test backend logic with real database
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: dispatchcore_testSteps:
- Wait for MySQL to be healthy
- Install dependencies
- Run unit tests
- Run integration tests
- Upload coverage to Codecov
Database Connection:
// Environment variables in workflow
DB_HOST: localhost
DB_PORT: 3306
DB_USER: root
DB_PASSWORD: root_password
DB_NAME: dispatchcore_testSuccess Criteria:
- All unit tests pass
- All integration tests pass
- Coverage meets thresholds (70%)
Typical Duration: 1-2 minutes
Purpose: Ensure TypeScript and build integrity
steps:
- npm run lint
- npx tsc --noEmit
- npm run buildSuccess Criteria:
- No ESLint errors
- TypeScript compiles without errors
- Production build succeeds
Typical Duration: 45-60 seconds
Purpose: Test React components and hooks
Steps:
- Install dependencies
- Run unit tests with Vitest
- Run component tests
- Upload coverage
Success Criteria:
- All component tests pass
- All hook tests pass
- Coverage meets thresholds (70%)
Typical Duration: 30-45 seconds
Purpose: Check for known vulnerabilities (non-blocking)
npm audit --audit-level=moderate
continue-on-error: trueReports:
- Moderate and high severity vulnerabilities
- Doesn't block merge (non-critical)
Action Items:
- Review GitHub Dependabot alerts
- Update packages as needed
Typical Duration: 20-30 seconds
Condition: if: github.ref == 'refs/heads/main' && github.event_name == 'push'
Purpose: Generate deployment artifacts
Steps:
- Build backend (lint check)
- Build frontend (dist folder)
- Upload dist as artifact (7-day retention)
- Generate release notes
Artifacts Available:
- GitHub Actions → Artifacts tab
- Download
frontend-build.zip
Typical Duration: 1-2 minutes
Purpose: Final status summary
Logic:
if any job failed:
exit 1 # Mark PR as failed
else:
success message # All checks passedAvailable in all jobs:
env:
NODE_VERSION: '18'Test-specific:
env:
DB_HOST: localhost
DB_PORT: 3306
NODE_ENV: testNPM Dependencies Cache:
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: backend/package-lock.jsonBenefits:
- 50-70% faster install time
- Cached on per-branch basis
- Automatically invalidated on package-lock.json change
Backend tests multiple Node versions:
strategy:
matrix:
node-version: [18.x, 20.x]Why?
- Ensures compatibility across versions
- Catches version-specific bugs early
- Production might run different versions
Cause: Package cache mismatch
# Local fix
rm package-lock.json
npm install
git commit package-lock.json
# Re-run workflowIssue: Long-running operations
// jest.config.js
testTimeout: 10000 // 10 seconds
// Or per test:
it('slow test', async () => {
// ...
}, 20000); // 20 secondsDebug:
- name: Check MySQL
run: |
mysql -h localhost -u root -proot_password -e "SELECT 1"Check: .nvmrc or package.json engines field
{
"engines": {
"node": ">=18.0.0"
}
}- GitHub UI: Actions → Workflow run → Job details
- Download logs: Click "Download logs" (zip file)
- Search logs: Use CTRL+F to find errors
GitHub UI → Re-run jobs → Select failed jobs
Or re-run entire workflow:
GitHub UI → Re-run all jobs
| Stage | Duration | Status |
|---|---|---|
| Backend Lint | 30-45s | ✅ Cached |
| Backend Tests | 60-90s | ✅ Parallel |
| Frontend Lint | 45-60s | ✅ Cached |
| Frontend Tests | 30-45s | ✅ Parallel |
| Security Audit | 20-30s | |
| Total (serial) | 3-4 min | ✅ Good |
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: 'backend/package-lock.json'Tips:
- Commit
package-lock.json - Use
npm ci(notnpm install) - Avoid
npm updatein CI
# Only run security audit on main
if: github.ref == 'refs/heads/main'Currently, most jobs run in parallel:
- Backend lint + Frontend lint (simultaneous)
- Backend tests + Frontend tests (after linting)
Cannot parallelize:
- Backend tests depend on Backend lint
- Frontend tests depend on Frontend lint
services:
mysql:
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3Waits for health check before tests start
Current: Manual deployment (not automated in CI/CD)
Future setup:
deploy:
needs: [build-artifacts]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: |
# Deploy script hereBefore merging to main:
- All checks pass (green checkmark)
- Code review approved
- Manual testing complete
- Release notes updated
# Manual steps (add to CI/CD when ready)
git checkout main
git pull
npm run build
# Deploy to Vercel, Render, AWS, etc.Navigate to:
Repository → Actions tab → ci-cd workflow
View:
- Build history
- Duration trends
- Failure patterns
- Branch-specific stats
GitHub:
Settings → Notifications → Actions
- Email on: all failures, or branch failures
Slack Integration (Optional):
- name: Notify Slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
if: always()Check trends:
- Actions tab → ci-cd workflow
- Scroll to "All runs"
- Note duration changes over time
Alert on: Consistent slowdowns (30%+ increase)
Codecov Dashboard:
https://codecov.io/gh/arsh342/dispatchCore
Track:
- Coverage % trends
- Per-file coverage
- Pull request comparisons
- ✅ Parallelize where possible
- ✅ Use caching aggressively
- ✅ Skip unnecessary checks on branches
- ❌ Don't run long E2E tests on every PR
# Stop on first error
bail: 1
# Fail CI if coverage drops
fail_ci_if_error: true# Good: specific error messages
echo "Database migration failed: table users not found"
# Bad: vague errors
echo "Error"# When modifying workflow:
# Update CICD_GUIDE.md with changes
# Explain why (performance? reliability?)# Good: specific version
uses: actions/setup-node@v4
# Avoid: @latest (unpredictable)
uses: actions/setup-node@latestCheck:
- Branch name matches trigger (
mainordevelop) - Event type matches (
pushorpull_request) - File path correct:
.github/workflows/ci-cd.yml
Solution:
- name: Free disk space
run: |
sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnetAdd to: Repository → Settings → Secrets → New repository secret
Use in workflow:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}