CI/CD Pipeline¶
Last Updated: 2025-01-22
Automated Continuous Integration and Continuous Deployment pipeline for AccessALI using GitHub Actions.
Overview¶
The CI/CD pipeline automates:
- Code quality - Linting and type checking
- Testing - Unit, integration, and E2E tests
- Building - Docker image creation
- Deployment - Automated deployment to environments
Workflow¶
graph LR
Push[Push to GitHub] --> Lint[Lint & Type Check]
Lint --> Test[Run Tests]
Test --> Build[Build Docker Image]
Build --> Deploy[Deploy to Environment]
GitHub Actions Workflow¶
Main Workflow¶
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
env:
NODE_VERSION: '20'
jobs:
lint:
name: Lint and Type Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: |
corepack enable
pnpm install
- name: Run type check
run: cd src && pnpm type-check
- name: Run linter
run: cd src && pnpm lint
test:
name: Run Tests
runs-on: ubuntu-latest
needs: lint
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: accessali
POSTGRES_PASSWORD: postgres
POSTGRES_DB: accessali_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: |
corepack enable
pnpm install
- name: Run migrations
run: cd src && pnpm db:migrate
env:
DATABASE_URL: postgresql://accessali:postgres@localhost:5432/accessali_test
- name: Run unit tests
run: cd src && pnpm test
env:
DATABASE_URL: postgresql://accessali:postgres@localhost:5432/accessali_test
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
build:
name: Build Docker Image
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/accessali:latest
${{ secrets.DOCKER_USERNAME }}/accessali:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
environment:
name: staging
url: https://staging.accessali.example.com
steps:
- name: Deploy to staging
run: |
# Deploy using kubectl, helm, or deployment script
echo "Deploying to staging environment"
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://accessali.example.com
steps:
- name: Deploy to production
run: |
# Deploy to production
echo "Deploying to production environment"
E2E Testing¶
# .github/workflows/e2e.yml
name: E2E Tests
on:
pull_request:
branches: [main, develop]
jobs:
e2e:
name: Playwright E2E Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: |
corepack enable
pnpm install
pnpm exec playwright install --with-deps
- name: Run E2E tests
run: cd src && pnpm test:e2e
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: src/playwright-report/
Deployment Strategies¶
1. Vercel (Recommended for Next.js)¶
# .github/workflows/vercel.yml
name: Deploy to Vercel
on:
push:
branches: [main, develop]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: ${{ github.ref == 'refs/heads/main' && '--prod' || '' }}
2. Docker Registry + Kubernetes¶
# Build and push
docker build -t registry.example.com/accessali:$VERSION .
docker push registry.example.com/accessali:$VERSION
# Deploy to Kubernetes
kubectl set image deployment/accessali-app \
app=registry.example.com/accessali:$VERSION \
-n accessali
3. AWS ECS¶
# .github/workflows/ecs.yml
- name: Deploy to Amazon ECS
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: task-definition.json
service: accessali-service
cluster: accessali-cluster
Environment Secrets¶
Configure in GitHub repository settings:
Required Secrets¶
# Docker
DOCKER_USERNAME=your-username
DOCKER_PASSWORD=your-password
# Vercel (if using Vercel)
VERCEL_TOKEN=your-vercel-token
VERCEL_ORG_ID=your-org-id
VERCEL_PROJECT_ID=your-project-id
# Database
DATABASE_URL=postgresql://...
# NextAuth
NEXTAUTH_SECRET=production-secret
# OAuth (if using)
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
Branch Strategy¶
graph LR
Feature[feature/*] -->|PR| Develop[develop]
Develop -->|PR| Main[main]
Feature -->|CI: Lint, Test| CI1[CI Checks]
Develop -->|Deploy| Staging[Staging Environment]
Main -->|Deploy| Production[Production Environment]
Environments¶
- feature/* - Local development only
- develop - Auto-deploy to staging
- main - Auto-deploy to production (with approval)
Best Practices¶
- Run CI on all pull requests
- Require passing CI before merge
- Use branch protection rules
- Implement environment-specific deployments
- Store secrets in GitHub Secrets or vault
- Tag releases with semantic versioning
- Implement rollback procedures
- Monitor deployment success
- Use deployment approvals for production
- Keep workflows DRY with reusable workflows
Related Documentation¶
Next Steps¶
- Configure GitHub Actions workflows
- Set up environment secrets
- Configure deployment environments
- Review Production Checklist