Continuous Integration and CI/CD
CI/CD automates testing and deployment. This article covers pipeline setup and best practices.
Introduction
CI/CD provides:
- Automated testing
- Automated deployment
- Quality gates
- Faster feedback
- Reduced manual work
Understanding CI/CD helps you:
- Automate workflows
- Catch issues early
- Deploy safely
- Reduce errors
- Improve velocity
GitHub Actions
Workflow Setup
# โ
Good: GitHub Actions workflow
name: CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Push to registry
run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker push myapp:${{ github.sha }}
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to production
run: |
kubectl set image deployment/app app=myapp:${{ github.sha }}
GitLab CI
Pipeline Configuration
# โ
Good: GitLab CI pipeline
stages:
- test
- build
- deploy
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
test:
stage: test
image: node:18
script:
- npm ci
- npm run lint
- npm test -- --coverage
coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE
only:
- main
Jenkins Pipeline
Jenkinsfile
// โ
Good: Jenkins pipeline
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Lint') {
steps {
sh 'npm run lint'
}
}
stage('Test') {
steps {
sh 'npm test -- --coverage'
}
}
stage('Build') {
steps {
sh 'docker build -t myapp:${BUILD_NUMBER} .'
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh 'kubectl set image deployment/app app=myapp:${BUILD_NUMBER}'
}
}
}
post {
always {
junit 'test-results.xml'
publishHTML([
reportDir: 'coverage',
reportFiles: 'index.html',
reportName: 'Coverage Report'
])
}
}
}
Quality Gates
Code Quality Checks
# โ
Good: Quality gates
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: SonarQube scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Check quality gate
run: |
if [ "$SONAR_QUALITY_GATE" != "PASSED" ]; then
echo "Quality gate failed"
exit 1
fi
Best Practices
-
Fail fast:
# โ Good: Run fast checks first stages: - lint # Fast - test # Medium - build # Slow - deploy # Slowest # โ Bad: Run slow checks first stages: - build - deploy - test - lint -
Cache dependencies:
# โ Good: Cache dependencies cache: paths: - node_modules/ # โ Bad: No caching -
Use secrets:
# โ Good: Use secrets - name: Deploy env: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: docker login -u user -p $DOCKER_PASSWORD # โ Bad: Hardcode credentials - name: Deploy run: docker login -u user -p password123
Summary
CI/CD is essential. Key takeaways:
- Automate testing
- Automate deployment
- Implement quality gates
- Cache dependencies
- Use secrets
- Fail fast
- Monitor pipelines
- Improve continuously
Related Resources
Next Steps
- Learn about Test Automation
- Explore Performance Testing
- Study Monitoring
- Practice CI/CD setup
- Automate workflows
Comments