DDevArchive
Đăng nhập

CI/CD: tự động hoá bằng GitHub Actions

CI (Continuous Integration) chạy test mỗi lần push. CD (Continuous Delivery) tự đưa code lên server. GitHub Actions cho phép bạn định nghĩa pipeline bằng một file YAML — không cần hạ tầng riêng.

Workflow, job, step

Một workflow chạy khi sự kiện xảy ra (push, PR, lịch). Workflow gồm các job (có thể song song), mỗi job gồm các step (lệnh chạy tuần tự).

// File: ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build
💡 Lợi ích thật của CI

Không phải “có badge xanh”. Mà là: merge code mà không sợ làm hỏng — máy tính đã chạy test thay bạn. Pull request nào có CI đỏ nghĩa là chưa sẵn sàng merge.

Chạy cơ sở dữ liệu trong CI

Test integration cần PostgreSQL. GitHub Actions có service container — khởi động DB thật trong pipeline để test y như production.

// File: ci-db.yml
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd "pg_isready"
          --health-interval 5s
          --health-retries 5
        ports: ["5432:5432"]
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
        env:
          DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres

CD: tự deploy khi merge main

// File: cd.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t my-app .
      - name: Push lên registry
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
        run: docker push registry.example.com/my-app
      - name: SSH vào server và pull
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_KEY }}
          script: |
            docker compose pull web
            docker compose up -d --no-deps web

❓ Bạn vừa push một commit lên nhánh main. Với file CI ở trên, điều gì xảy ra?

  • Viết file YAML workflow CI
  • Kích hoạt theo push/PR đúng nhánh
  • Dùng service container cho PostgreSQL
  • Tách workflow CI và CD rõ ràng