Developer Tools

GitHub Actions CI/CD: Xây dựng, Kiểm thử và Triển khai Workflow từ Đầu

Tìm hiểu cách thiết lập GitHub Actions cho tích hợp liên tục và triển khai liên tục. Bao gồm triggers, jobs, matrices, secrets, caching, Docker và các ví dụ workflow thực tế.

10 phút đọc

GitHub code collaboration on screen

GitHub Actions biến mỗi lần push, pull request và merge thành một pipeline tự động — chạy kiểm thử, build artifacts, quét lỗ hổng bảo mật và triển khai lên môi trường production. Đây là nền tảng CI/CD tích hợp ngay trong repository của bạn, không cần quản lý bất kỳ cơ sở hạ tầng nào.

GitHub Actions hoạt động như thế nào

Mỗi workflow là một file YAML nằm trong .github/workflows/. Khi một sự kiện trigger được kích hoạt, GitHub khởi động một máy ảo mới, chạy các jobs của bạn và báo cáo kết quả — tất cả chỉ trong vài giây.

Push to main
  ↓
Workflow triggered
  ↓
Job: Build & Test (ubuntu-latest)
  ├── Step 1: Checkout code
  ├── Step 2: Install Node.js
  ├── Step 3: npm ci
  ├── Step 4: npm test
  └── Step 5: npm run build
  ↓
✅ All checks passed

Workflow đầu tiên của bạn

Tạo file .github/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    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 test
      - run: npm run build

Vậy là xong. Mỗi lần push lên main và mỗi PR sẽ tự động chạy bộ kiểm thử của bạn.

Triggers: khi nào workflow chạy

Sự kiện liên quan đến code

on:
  push:
    branches: [main, develop]
    paths: ['src/**', 'package.json']  # Chỉ chạy khi những file này thay đổi
  pull_request:
    types: [opened, synchronize]

Lịch định kỳ (cron)

on:
  schedule:
    - cron: '0 6 * * 1'  # Mỗi thứ Hai lúc 6:00 UTC

Kích hoạt thủ công

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deploy target'
        required: true
        type: choice
        options: [staging, production]

Tính năng này thêm nút "Run workflow" vào giao diện GitHub, nơi bạn có thể chọn các tham số.

Reusable workflows

on:
  workflow_call:
    inputs:
      node-version:
        type: string
        default: '20'

Gọi nó từ workflow khác bằng uses: ./.github/workflows/reusable.yml.

Jobs và steps

Các jobs chạy song song

Mặc định các jobs chạy song song với nhau:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  build:
    runs-on: ubuntu-latest
    needs: [lint, test]  # Chờ cả hai hoàn thành
    steps:
      - uses: actions/checkout@v4
      - run: npm run build

Matrix strategy — kiểm thử trên nhiều phiên bản

Chạy cùng một job trên nhiều cấu hình khác nhau:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
        os: [ubuntu-latest, windows-latest]
      fail-fast: false
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

Cấu hình này tạo ra 6 jobs chạy song song (3 phiên bản × 2 hệ điều hành).

Secrets và biến môi trường

Sử dụng secrets

Lưu trữ các giá trị nhạy cảm trong Settings → Secrets and variables → Actions:

steps:
  - name: Deploy
    env:
      API_KEY: ${{ secrets.API_KEY }}
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
    run: ./deploy.sh

Secrets được ẩn trong logs và không bao giờ bị lộ ra với các fork.

Biến môi trường

# Cấp độ workflow
env:
  NODE_ENV: production

jobs:
  build:
    # Cấp độ job
    env:
      CI: true
    steps:
      - name: Build
        # Cấp độ step
        env:
          VITE_API_URL: https://api.example.com
        run: npm run build

Caching để tăng tốc độ build

Nếu không có caching, mỗi lần chạy sẽ tải lại toàn bộ dependencies từ đầu. Caching giúp giảm thời gian build từ 50-80%:

- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: npm  # Caching npm tích hợp sẵn

# Hoặc caching thủ công cho các công cụ khác
- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

Artifacts: chia sẻ dữ liệu giữa các jobs

Upload kết quả build từ một job và download ở job khác:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
      - run: ./deploy.sh

Ví dụ workflow thực tế

Build và push Docker

name: Docker

on:
  push:
    tags: ['v*']

permissions:
  packages: write

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Triển khai lên Cloudflare Pages

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci && npm run build
      - uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          command: pages deploy dist --project-name=my-site

Release kèm changelog

name: Release

on:
  push:
    tags: ['v*.*.*']

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Generate changelog
        run: |
          git log $(git describe --tags --abbrev=0 HEAD^)..HEAD \
            --pretty=format:"- %s" > CHANGELOG.md
      - uses: softprops/action-gh-release@v2
        with:
          body_path: CHANGELOG.md
          generate_release_notes: true

Thực thi có điều kiện

Kiểm soát thời điểm các steps và jobs được chạy:

steps:
  - name: Deploy to production
    if: github.ref == 'refs/heads/main'
    run: ./deploy-prod.sh

  - name: Deploy to staging
    if: github.event_name == 'pull_request'
    run: ./deploy-staging.sh

  - name: Notify on failure
    if: failure()
    run: curl -X POST ${{ secrets.SLACK_WEBHOOK }} -d '{"text":"Build failed!"}'

Các biện pháp bảo mật tốt nhất

1. Ghim phiên bản action theo SHA

# ❌ Tag có thể thay đổi — có thể bị xâm phạm
- uses: actions/checkout@v4

# ✅ Ghim vào SHA commit chính xác
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

2. Sử dụng quyền tối thiểu cần thiết

permissions:
  contents: read    # Chỉ những gì cần thiết
  packages: write

3. Không bao giờ in secrets ra màn hình

# ❌ KHÔNG BAO GIỜ làm điều này
- run: echo ${{ secrets.API_KEY }}

# ✅ Sử dụng biến môi trường
- env:
    API_KEY: ${{ secrets.API_KEY }}
  run: ./script-that-uses-api-key.sh

4. Giới hạn quyền cho PR từ fork

on:
  pull_request_target:  # Chạy trong ngữ cảnh của branch gốc
    types: [opened, synchronize]

Gỡ lỗi workflow thất bại

  1. Xem logs — Nhấp vào bất kỳ step nào bị lỗi để xem toàn bộ output
  2. Bật debug logging — Đặt secret ACTIONS_STEP_DEBUG thành true
  3. Dùng act ở máy local — Chạy workflows trên máy của bạn với nektos/act
  4. SSH vào runner — Dùng mxschmitt/action-tmate để debug tương tác

Xây dựng workflow bằng giao diện trực quan

Không muốn tự viết YAML? Hãy dùng GitHub Actions Generator của chúng tôi để xây dựng workflow bằng giao diện trực quan với các template cho Node.js, Python, Docker, triển khai và nhiều hơn nữa — sau đó tải về file YAML sẵn sàng cho môi trường production.

Tổng kết

GitHub Actions mang đến cho bạn CI/CD tích hợp ngay trong repository:

  1. Bắt đầu đơn giản — Một file workflow với build + test
  2. Thêm caching — Giảm thời gian build với actions/cache hoặc caching ngôn ngữ tích hợp sẵn
  3. Dùng matrix — Kiểm thử trên nhiều phiên bản và hệ điều hành
  4. Bảo vệ secrets — Không bao giờ hardcode, luôn dùng encrypted secrets
  5. Tự động hóa mọi thứ — Releases, triển khai, quét bảo mật, tác vụ định kỳ

Pipeline CI/CD tốt nhất là pipeline chạy trên mỗi commit mà bạn không cần phải nghĩ đến. Thiết lập một lần, và để GitHub lo phần còn lại.