blog.dopana

Back

CI/CD (Continuous Integration / Continuous Deployment) là xương sống của quy trình phát triển hiện đại. Mỗi lần push code — tự động kiểm tra, build, và deploy.

CI vs CD#

CI (Continuous Integration)CD (Continuous Deployment/Delivery)
Lint, test, build khi pushDeploy lên staging/production
Đảm bảo code mới không hỏngĐảm bảo luôn sẵn sàng release
Chạy trên mỗi PRChạy khi merge vào main

GitHub Actions — Cấu Trúc Cơ Bản#

Pipeline Hoàn Chỉnh#

1. Lint & Type Check#

lint:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 20
        cache: 'npm'
    - run: npm ci
    - run: npm run lint
    - run: npm run typecheck
yaml

2. Unit Test + Coverage#

test:
  needs: lint
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 20
    - run: npm ci
    - run: npm run test:cov
    - uses: actions/upload-artifact@v4
      with:
        name: coverage
        path: coverage/
yaml

3. Build & Push Docker Image#

build:
  needs: test
  if: github.ref == 'refs/heads/main'
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - name: Build Docker image
      run: docker build -t myapp:${{ github.sha }} .
    - name: Push to registry
      run: |
        docker tag myapp:${{ github.sha }} registry.example.com/myapp:${{ github.sha }}
        docker push registry.example.com/myapp:${{ github.sha }}
yaml

4. Deploy#

Matrix Build — Test Nhiều Phiên Bản#

test:
  strategy:
    matrix:
      node-version: [18, 20, 22]
      os: [ubuntu-latest, windows-latest]

  runs-on: ${{ matrix.os }}
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - run: npm test
yaml

Caching — Tăng Tốc Pipeline#

- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-
yaml

Secrets — Không Hardcode#

Trong GitHub:

Settings > Secrets and variables > Actions
plaintext

Thêm: SERVER_HOST, DB_PASSWORD, API_KEY, SSH_KEY

Dùng trong workflow:

- run: echo "${{ secrets.SSH_KEY }}" > ssh_key
yaml

Docker Compose Cho Test Integration#

Auto Deploy — Vercel / Cloudflare Pages#

deploy:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - run: npm ci && npm run build
    - name: Deploy to Cloudflare Pages
      uses: cloudflare/wrangler-action@v3
      with:
        apiToken: ${{ secrets.CF_API_TOKEN }}
        command: pages deploy dist/
yaml

GitOps — Deploy Bằng Git#

Không ssh vào server — push config vào git repo, tool tự đồng bộ:

# ArgoCD + Kubernetes
# Push image tag mới vào Git repo config → ArgoCD tự deploy
yaml

Badges — Cho README#

[![CI](https://github.com/user/repo/actions/workflows/ci.yml/badge.svg)](https://github.com/user/repo/actions)
markdown

Checklist Pipeline#

  • Lint & type check
  • Unit test + coverage
  • Integration test (DB, cache)
  • Build Docker image
  • Push registry
  • Deploy staging
  • Smoke test
  • Deploy production
  • Rollback plan

Kết Luận#

CI/CD không phải công cụ — nó là văn hóa. Code push lên là code đã được kiểm tra, đóng gói, sẵn sàng deploy. Mất 1 ngày setup, tiết kiệm hàng trăm giờ debug “tại sao chạy được ở máy tôi?”.

Tài liệu tham khảo#