Bỏ qua

GitHub Actions Basics

GitHub Actions là gì?

GitHub Actions là CI/CD platform tích hợp sẵn trong GitHub, cho phép automate workflows.

┌─────────────────────────────────────────────────────────────┐
│                    GITHUB ACTIONS                            │
│                                                              │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐            │
│  │  Trigger │────▶│   Jobs   │────▶│  Deploy  │            │
│  │  (Push)  │     │ (Build)  │     │  (CF)    │            │
│  └──────────┘     └──────────┘     └──────────┘            │
│                                                              │
│  Triggers: push, pull_request, schedule, workflow_dispatch  │
│  Runners: ubuntu, windows, macos                            │
│  Actions: Reusable steps from marketplace                   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Workflow Structure

# .github/workflows/deploy.yml

name: Deploy        # Workflow name

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

env:                # Environment variables
  NODE_VERSION: '20'

jobs:               # Jobs to run
  build:            # Job name
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: npm ci
      - run: npm run build

Core Concepts

Workflow

File YAML trong .github/workflows/ định nghĩa automation pipeline.

Jobs

Các units chạy song song (hoặc sequential với needs).

jobs:
  test:
    runs-on: ubuntu-latest
    steps: [...]

  deploy:
    needs: test  # Wait for test job
    runs-on: ubuntu-latest
    steps: [...]

Steps

Các actions hoặc commands trong một job.

steps:
  - uses: actions/checkout@v4      # Use action
  - run: npm install               # Run command
  - name: Custom step              # Named step
    run: |
      echo "Multi-line"
      echo "commands"

Common Triggers

Push & Pull Request

on:
  push:
    branches: [main, develop]
    paths:
      - 'src/**'
      - 'package.json'
  pull_request:
    branches: [main]

Schedule (Cron)

on:
  schedule:
    - cron: '0 2 * * *'  # 2 AM UTC daily

Manual Trigger

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deploy environment'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production

Secrets & Variables

Configuring Secrets

Repository → Settings → Secrets and variables → Actions

Secrets:
- CLOUDFLARE_API_TOKEN
- SUPABASE_SERVICE_KEY

Variables:
- SUPABASE_PROJECT_ID
- CLOUDFLARE_ACCOUNT_ID

Using in Workflow

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to Cloudflare
        env:
          CF_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: wrangler deploy

      - name: Use variable
        run: echo "Project: ${{ vars.SUPABASE_PROJECT_ID }}"

Environments

Setup Environments

Repository → Settings → Environments

Create environments:
- staging
- production (with protection rules)

Protection Rules

  • Required reviewers
  • Wait timer (delay deployment)
  • Branch restrictions
  • Deployment branches

Use in Workflow

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    environment: staging  # Use staging secrets
    steps: [...]

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production  # Use production secrets
    steps: [...]

Workflow cho Light Stack

Complete Example

# .github/workflows/deploy.yml
name: Deploy Light Stack

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

env:
  NODE_VERSION: '20'

jobs:
  # ===================
  # Build & Test
  # ===================
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Type check
        run: npm run type-check

      - name: Test
        run: npm run test

      - name: Build Next.js
        run: npm run build

      - name: Build for Cloudflare
        run: npm run build:worker

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: .open-next/
          retention-days: 1

  # ===================
  # Deploy Staging
  # ===================
  deploy-staging:
    needs: build
    if: github.ref == 'refs/heads/staging'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4

      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-output
          path: .open-next/

      - name: Deploy to Cloudflare
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
          command: deploy --env staging

  # ===================
  # Deploy Production
  # ===================
  deploy-production:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-output
          path: .open-next/

      - name: Deploy to Cloudflare
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
          command: deploy --env production

Useful Actions

Action Purpose
actions/checkout@v4 Clone repository
actions/setup-node@v4 Setup Node.js
actions/cache@v4 Cache dependencies
actions/upload-artifact@v4 Save build output
cloudflare/wrangler-action@v3 Deploy to Cloudflare
supabase/setup-cli@v1 Setup Supabase CLI

Debugging

Enable Debug Logging

# Set in Repository Secrets
ACTIONS_RUNNER_DEBUG: true
ACTIONS_STEP_DEBUG: true

View Logs

Actions tab → Select workflow run → Click job → View logs

Retry Failed Jobs

Actions tab → Failed run → Re-run failed jobs

Tổng kết

Key Files

.github/
└── workflows/
    ├── deploy.yml       # Main deployment
    ├── preview.yml      # PR previews
    └── migrations.yml   # DB migrations

Best Practices

  1. Use environments for secrets separation
  2. Cache dependencies for faster builds
  3. Upload artifacts to share between jobs
  4. Use protection rules for production
  5. Keep workflows DRY with reusable actions

Q&A

  1. Đã dùng GitHub Actions trước đây chưa?
  2. Có workflows nào đang chạy?
  3. Challenges với CI/CD hiện tại?