Developer Tools

GitHub Actions CI/CD: สร้าง ทดสอบ และ Deploy Workflows ตั้งแต่เริ่มต้น

เรียนรู้วิธีตั้งค่า GitHub Actions สำหรับ continuous integration และ deployment ครอบคลุมเรื่อง triggers, jobs, matrices, secrets, caching, Docker และตัวอย่าง workflow ในการใช้งานจริง

10 นาทีในการอ่าน

GitHub code collaboration on screen

GitHub Actions เปลี่ยนทุก push, pull request และ merge ให้กลายเป็น automated pipeline — รันการทดสอบ, สร้าง artifacts, ตรวจสอบช่องโหว่ และ deploy ขึ้น production ได้โดยอัตโนมัติ เป็นแพลตฟอร์ม CI/CD ที่อยู่ภายใน repository ของคุณโดยตรง ไม่ต้องจัดการ infrastructure ใดๆ เลย

GitHub Actions ทำงานอย่างไร

ทุก workflow คือไฟล์ YAML ใน .github/workflows/ เมื่อ trigger event ถูกยิง GitHub จะสร้าง virtual machine ใหม่ขึ้นมา รันงานของคุณ และรายงานผลลัพธ์ — ทั้งหมดภายในไม่กี่วินาที

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 แรกของคุณ

สร้าง .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

เท่านี้ก็พอ ทุก push ไปยัง main และทุก PR จะรัน test suite ของคุณโดยอัตโนมัติ

Triggers: เมื่อไหร่ workflows จะทำงาน

Code events

on:
  push:
    branches: [main, develop]
    paths: ['src/**', 'package.json']  # Only run when these change
  pull_request:
    types: [opened, synchronize]

กำหนดเวลา (cron)

on:
  schedule:
    - cron: '0 6 * * 1'  # Every Monday at 6:00 UTC

Manual dispatch

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

ตัวเลือกนี้จะเพิ่มปุ่ม "Run workflow" ใน GitHub UI ที่ให้คุณเลือกพารามิเตอร์ได้

Reusable workflows

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

เรียกใช้จาก workflow อื่นด้วย uses: ./.github/workflows/reusable.yml

Jobs และ steps

Parallel jobs

Jobs ทำงานแบบ parallel โดยค่าเริ่มต้น:

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]  # Waits for both to pass
    steps:
      - uses: actions/checkout@v4
      - run: npm run build

Matrix strategy — ทดสอบข้ามหลายเวอร์ชัน

รัน job เดียวกันบน configuration หลายรูปแบบ:

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

วิธีนี้สร้าง parallel jobs ทั้งหมด 6 งาน (3 เวอร์ชัน × 2 ระบบปฏิบัติการ)

Secrets และ environment variables

การใช้ secrets

เก็บค่าที่ sensitive ใน Settings → Secrets and variables → Actions:

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

Secrets จะถูกซ่อนใน logs และไม่เคยถูกเปิดเผยต่อ forks

Environment variables

# Workflow-level
env:
  NODE_ENV: production

jobs:
  build:
    # Job-level
    env:
      CI: true
    steps:
      - name: Build
        # Step-level
        env:
          VITE_API_URL: https://api.example.com
        run: npm run build

Caching เพื่อให้ build เร็วขึ้น

หากไม่มี caching ทุกครั้งที่รันจะต้องดาวน์โหลด dependencies ทั้งหมดใหม่ตั้งแต่ต้น การใช้ caching ช่วยลดเวลา build ได้ถึง 50-80%:

- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: npm  # Built-in npm caching

# Or manual caching for other tools
- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

Artifacts: การแชร์ข้อมูลระหว่าง jobs

อัปโหลดผลลัพธ์ของการ build จาก job หนึ่ง แล้วดาวน์โหลดใน job อื่น:

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

ตัวอย่าง workflow ในการใช้งานจริง

Docker build และ push

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

Deploy ไปยัง 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 พร้อม 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

การกำหนดเงื่อนไขการทำงาน

ควบคุมว่าเมื่อไหร่ steps และ jobs จะทำงาน:

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!"}'

แนวทางด้านความปลอดภัย

1. Pin action versions ด้วย SHA

# ❌ Mutable tag — could be compromised
- uses: actions/checkout@v4

# ✅ Pinned to exact commit SHA
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

2. ใช้ permissions แบบ least-privilege

permissions:
  contents: read    # Only what's needed
  packages: write

3. ห้าม echo secrets เด็ดขาด

# ❌ NEVER do this
- run: echo ${{ secrets.API_KEY }}

# ✅ Use environment variables
- env:
    API_KEY: ${{ secrets.API_KEY }}
  run: ./script-that-uses-api-key.sh

4. จำกัด permissions สำหรับ PRs จาก forks

on:
  pull_request_target:  # Runs in context of base branch
    types: [opened, synchronize]

การ debug workflow ที่ล้มเหลว

  1. ตรวจสอบ logs — คลิกที่ step ที่ล้มเหลวเพื่อดู output ทั้งหมด
  2. เพิ่ม debug logging — ตั้งค่า secret ACTIONS_STEP_DEBUG เป็น true
  3. ใช้ act บนเครื่องตัวเอง — รัน workflows บนเครื่องของคุณด้วย nektos/act
  4. SSH เข้า runner — ใช้ mxschmitt/action-tmate สำหรับการ debug แบบ interactive

สร้าง workflows แบบ visual

ไม่อยากเขียน YAML เองใช่ไหม? ลองใช้ GitHub Actions Generator ของเราเพื่อสร้าง workflows แบบ visual พร้อม templates สำหรับ Node.js, Python, Docker, deployments และอื่นๆ อีกมากมาย แล้วดาวน์โหลด YAML ที่พร้อมใช้งาน production ได้เลย

สรุป

GitHub Actions มอบระบบ CI/CD ที่อยู่ภายใน repository ของคุณโดยตรง:

  1. เริ่มจากสิ่งง่ายๆ — ไฟล์ workflow เดียวที่มี build + test
  2. เพิ่ม caching — ลดเวลา build ด้วย actions/cache หรือ built-in language caching
  3. ใช้ matrix — ทดสอบข้ามหลายเวอร์ชันและระบบปฏิบัติการ
  4. ปกป้อง secrets — ห้าม hardcode เสมอ ให้ใช้ encrypted secrets
  5. Automate ทุกอย่าง — Releases, deployments, security scans, scheduled tasks

Pipeline CI/CD ที่ดีที่สุดคือสิ่งที่รันทุกครั้งที่ commit โดยที่คุณไม่ต้องคิดอะไรเลย ตั้งค่าครั้งเดียว แล้วปล่อยให้ GitHub จัดการส่วนที่เหลือ