Sổ tay kỹ thuật

GitHub Actions – cú pháp workflow hay dùng

cheatsheet#github-actions#ci· cập nhật 2026-11-06

Tra nhanh cú pháp workflow GitHub Actions, gồm trigger, matrix, cache, secrets, artifact, concurrency, output và reusable workflow.

Sửa trang này
Mục lục

Workflow đặt ở .github/workflows/*.yml. Biểu thức dùng ${{ ... }}. Tag version action trong ví dụ là major mới nhất tại thời điểm viết, nên chạy Dependabot để tự nâng.

Trigger (on:)

Mục đích Cú pháp
Push lên main, chỉ khi đổi file trong src/ on: { push: { branches: [main], paths: ['src/**'] } }
Bỏ qua khi chỉ sửa docs paths-ignore: ['docs/**', '**.md']
Pull request vào main on: { pull_request: { branches: [main] } }
Push tag release on: { push: { tags: ['v*'] } }
Theo lịch (giờ UTC) on: { schedule: [ { cron: '0 1 * * *' } ] }
Bấm tay trên UI / gh workflow run on: workflow_dispatch (thêm inputs: nếu cần tham số)
Cho workflow khác gọi on: workflow_call
Khi tạo release on: { release: { types: [published] } }

Job và step

Mục đích Cú pháp
Quyền tối thiểu cho GITHUB_TOKEN permissions: { contents: read }
Cho phép OIDC (AWS/GCP/Azure không cần key) permissions: { id-token: write, contents: read }
Job chạy sau job khác needs: [test]
Chỉ chạy trên main if: github.ref == 'refs/heads/main'
Step chạy kể cả khi step trước lỗi if: always() / chỉ khi lỗi: if: failure()
Giới hạn thời gian timeout-minutes: 15
Cho phép job lỗi mà không fail workflow continue-on-error: true
Thư mục làm việc mặc định defaults: { run: { working-directory: app } }
Gắn môi trường có approval/secret riêng environment: production

Matrix

Mục đích Cú pháp
Chạy nhiều version strategy: { matrix: { python: ['3.12', '3.13'] } } → ${{ matrix.python }}
Nhiều OS matrix: { os: [ubuntu-latest, macos-latest] } + runs-on: ${{ matrix.os }}
Không huỷ job khác khi một job lỗi strategy: { fail-fast: false }
Bớt / thêm tổ hợp exclude: [ { os: macos-latest, python: '3.12' } ] / include: [...]
Giới hạn số job song song strategy: { max-parallel: 2 }

Secrets, biến, output

Mục đích Cú pháp
Đọc secret (đặt dưới env: của step/job) NETBOX_TOKEN: ${{ secrets.NETBOX_TOKEN }}
Biến cấu hình không bí mật ${{ vars.NETBOX_URL }}
Tạo secret bằng CLI gh secret set NETBOX_TOKEN < token.txt
Ẩn một giá trị khỏi log echo "::add-mask::$VALUE"
Ghi output của step echo "ver=1.2.0" >> "$GITHUB_OUTPUT" → ${{ steps.<id>.outputs.ver }}
Đặt env cho các step sau echo "IMAGE_TAG=$GITHUB_SHA" >> "$GITHUB_ENV"
Ghi tóm tắt lên trang run echo "### Kết quả" >> "$GITHUB_STEP_SUMMARY"
Giá trị mặc định khi rỗng ${{ inputs.env || 'staging' }}
Context hay dùng github.sha, github.ref_name, github.event_name, github.actor, runner.os

Cache, artifact, concurrency

Mục đích Cú pháp
Cache có sẵn của setup-python uses: actions/setup-python@v7 + with: { python-version: '3.12', cache: pip }
Cache của setup-uv uses: astral-sh/setup-uv@v7 + with: { enable-cache: true }
Cache tuỳ ý uses: actions/cache@v6 + with: { path: ~/.cache/x, key: "${{ runner.os }}-x-${{ hashFiles('**/uv.lock') }}" }
Upload artifact uses: actions/upload-artifact@v7 + with: { name: report, path: out/, retention-days: 7 }
Download ở job sau uses: actions/download-artifact@v8 + with: { name: report, path: out/ }
Huỷ run cũ khi push mới cùng branch concurrency: { group: "${{ github.workflow }}-${{ github.ref }}", cancel-in-progress: true }

Workflow mẫu: test Python với uv

.github/workflows/ci.yml
name: ci
on:
  push:
    branches: [main]
  pull_request:
 
permissions:
  contents: read
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python: ["3.12", "3.13"]
    steps:
      - uses: actions/checkout@v7
      - uses: astral-sh/setup-uv@v7
        with:
          python-version: ${{ matrix.python }}
          enable-cache: true
      - run: uv sync --locked
      - run: uv run pytest -q --junitxml=out/junit.xml
      - uses: actions/upload-artifact@v7
        if: always()
        with:
          name: junit-${{ matrix.python }}
          path: out/

Reusable workflow

.github/workflows/deploy.yml (được gọi)
on:
  workflow_call:
    inputs:
      env:
        type: string
        required: true
    secrets:
      DEPLOY_TOKEN:
        required: true
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.env }}
    steps:
      - run: ./deploy.sh "${{ inputs.env }}"
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
.github/workflows/release.yml (gọi)
jobs:
  deploy-prod:
    uses: ./.github/workflows/deploy.yml   # repo khác: org/repo/.github/workflows/deploy.yml@main
    with:
      env: production
    secrets: inherit

gh CLI

Mục đích Lệnh
Liệt kê run gần đây gh run list --limit 10
Theo dõi run đang chạy gh run watch
Xem log của step lỗi gh run view <run-id> --log-failed
Chạy lại job lỗi gh run rerun <run-id> --failed
Kích hoạt workflow_dispatch gh workflow run ci.yml -f env=staging

Workflow chạy bởi pull_request từ fork không đọc được secrets. Đừng chuyển sang pull_request_target rồi checkout code của PR, vì code lạ sẽ chạy với quyền và secret của repo.