CI/CD Best Practices
1. Commit Frequently
# Small, focused commits
git add src/user.service.ts
git commit -m "feat: add user creation endpoint"
git push origin feature/user-service
# Avoid large commits
# ❌ git commit -m "update everything"2. Automate Everything
# Automated pipeline
name: Complete Automation
on: [push]
jobs:
build:
steps:
- run: npm ci
- run: npm run build
test:
steps:
- run: npm test
- run: npm run lint
security:
steps:
- run: npm audit
- run: trivy scan
deploy:
steps:
- run: ./deploy.sh3. Keep Builds Fast
# Use caching
jobs:
build:
steps:
- uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- run: npm ci # Faster than npm install
- run: npm run build
# Parallel execution
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- run: npm run test:unit
integration-tests:
runs-on: ubuntu-latest
steps:
- run: npm run test:integration4. Fail Fast
jobs:
lint:
runs-on: ubuntu-latest
steps:
- run: npm run lint
test:
needs: lint # Don't test if lint fails
runs-on: ubuntu-latest
steps:
- run: npm test
deploy:
needs: test # Don't deploy if tests fail
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh5. Test in Production-Like Environment
services:
postgres:
image: postgres:15 # Same version as production
env:
POSTGRES_PASSWORD: postgres
redis:
image: redis:7 # Same version as production6. Implement Proper Branching
# Git Flow
main (production)
develop (integration)
feature/* (features)
hotfix/* (urgent fixes)
release/* (releases)
# Trunk-Based Development
main (always deployable)
feature/* (short-lived, < 2 days)7. Use Semantic Versioning
# Version format: MAJOR.MINOR.PATCH
v1.0.0 # Initial release
v1.0.1 # Bug fix
v1.1.0 # New feature
v2.0.0 # Breaking change
# Tag releases
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.08. Secure Secrets
# Never hardcode secrets
# ❌ Bad
env:
API_KEY: "abc123"
# ✅ Good
env:
API_KEY: ${{ secrets.API_KEY }}9. Monitor Deployments
// Health checks
app.get('/health', async (req, res) => {
try {
await db.ping();
res.status(200).json({ status: 'healthy' });
} catch (error) {
res.status(503).json({ status: 'unhealthy' });
}
});
// Metrics
const prometheus = require('prom-client');
const httpRequestDuration = new prometheus.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds'
});10. Implement Rollback Strategy
jobs:
deploy:
steps:
- name: Deploy
run: kubectl apply -f k8s/
- name: Wait for rollout
run: kubectl rollout status deployment/myapp
- name: Run smoke tests
run: ./smoke-tests.sh
- name: Rollback on failure
if: failure()
run: kubectl rollout undo deployment/myapp11. Use Infrastructure as Code
# Terraform
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
# Version controlled
git add terraform/
git commit -m "Add web server infrastructure"12. Implement Code Review
# Require PR reviews
on:
pull_request:
branches: [main]
jobs:
review:
steps:
- name: Check approvals
run: |
APPROVALS=$(gh pr view ${{ github.event.pull_request.number }} --json reviews -q '.reviews | length')
if [ $APPROVALS -lt 2 ]; then
echo "Need at least 2 approvals"
exit 1
fi13. Maintain Clean Code
// Use linters
// .eslintrc.js
module.exports = {
extends: ['eslint:recommended'],
rules: {
'no-console': 'error',
'no-unused-vars': 'error'
}
};
// Format code
// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2
}14. Document Everything
# README.md
## Setup
npm install
## Development
npm run dev
## Testing
npm test
## Deployment
npm run deploy
## Environment Variables
- DATABASE_URL: PostgreSQL connection string
- API_KEY: External API key15. Use Feature Flags
class FeatureFlags {
constructor() {
this.flags = {
'new-checkout': false,
'beta-dashboard': true
};
}
isEnabled(feature) {
return this.flags[feature] || false;
}
}
// Deploy code with flag disabled
// Enable after deployment16. Implement Observability
# Three pillars: Logs, Metrics, Traces
logging:
- ELK Stack
- CloudWatch
metrics:
- Prometheus
- Grafana
tracing:
- Jaeger
- OpenTelemetry17. Practice Continuous Improvement
# Retrospectives
- What went well?
- What didn't go well?
- What can we improve?
# Metrics to track
- Deployment frequency
- Lead time for changes
- Mean time to recovery
- Change failure rateInterview Tips
- Explain automation: Automate build, test, deploy
- Show speed: Caching, parallel execution
- Demonstrate security: Secrets management
- Discuss monitoring: Health checks, metrics
- Mention rollback: Quick recovery
- Show documentation: Clear README
Summary
CI/CD best practices include frequent commits, automation, fast builds, fail-fast approach, production-like testing, proper branching, semantic versioning, secure secrets, deployment monitoring, rollback strategies, infrastructure as code, code reviews, clean code, documentation, feature flags, observability, and continuous improvement. Essential for successful DevOps implementation.
Test Your Knowledge
Take a quick quiz to test your understanding of this topic.