70 phút
CI/CD Pipelines với GitHub Actions
Giới thiệu CI/CD
CI/CD (Continuous Integration/Continuous Deployment) là practice tự động hóa quá trình build, test và deploy ứng dụng.
GitHub Actions Basics
Workflow Structure
name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build application
run: npm run build
Environment Variables và Secrets
env:
NODE_ENV: production
REGISTRY: ghcr.io
jobs:
deploy:
environment: production
steps:
- name: Deploy to production
run: echo "Deploying..."
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
Advanced CI/CD Patterns
Matrix Builds
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16, 18, 20]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
Caching
- name: Cache node modules
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
Deployment Strategies
Blue-Green Deployment
deploy-blue:
runs-on: ubuntu-latest
steps:
- name: Deploy to blue environment
run: |
kubectl apply -f deployment-blue.yaml
kubectl rollout status deployment/my-app-blue
- name: Test blue deployment
run: |
# Run smoke tests
curl -f http://blue.myapp.com/health
- name: Switch traffic to blue
run: |
kubectl apply -f service-blue.yaml
Canary Deployment
deploy-canary:
runs-on: ubuntu-latest
steps:
- name: Deploy canary
run: |
kubectl apply -f deployment-canary.yaml
# Start with 10% traffic
kubectl set traffic deployment/my-app --weight=90,10
- name: Monitor canary
run: |
# Monitor metrics for 15 minutes
sleep 900
# Check error rate and performance
- name: Rollout to 100%
if: success()
run: |
kubectl set traffic deployment/my-app --weight=0,100
kubectl delete deployment/my-app-canary
Security Scanning
Code Security
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run SAST
uses: github/codeql-action/analyze@v2
with:
languages: javascript
- name: Dependency vulnerability scan
run: npm audit --audit-level moderate
- name: Run Snyk security scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
Container Security
container-scan:
runs-on: ubuntu-latest
steps:
- name: Build container
run: docker build -t my-app:${{ github.sha }} .
- name: Scan container
uses: aquasecurity/trivy-action@master
with:
image-ref: 'my-app:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
Monitoring và Notifications
Slack Notifications
- name: Notify Slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
channel: '#deployments'
text: 'Deployment ${{ job.status }} for ${{ github.ref }}'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
if: always()
Status Checks
health-check:
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Wait for deployment
run: sleep 30
- name: Health check
run: |
response=$(curl -s -o /dev/null -w "%{http_code}" https://myapp.com/health)
if [ $response -ne 200 ]; then
echo "Health check failed"
exit 1
fi