Manual Deployment Is Dead
FTP-ing files to a server. SSH-ing to pull git changes. Manual migrations. CI/CD eliminates this human error and makes deployments stress-free.
CI vs CD
- CI (Continuous Integration): Auto-test every code change
- CD (Continuous Delivery): Auto-deploy passing code to staging
- Continuous Deployment: Auto-deploy to production
GitHub Actions CI Pipeline
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20.x
cache: "npm"
- run: npm ci
- run: npm run lint
- run: npm test
- run: npm run build
Adding Deployment
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /app
git pull origin main
npm ci && npm run build
pm2 restart app
Best Practices
- Run fast checks first (lint before tests)
- Cache dependencies to speed up builds
- Never store secrets in YAML – use repository secrets
- Notify team on failures (Slack, email)
- Deploy to staging before production
