GitHub Actions CI/CD: สร้าง ทดสอบ และ Deploy Workflows ตั้งแต่เริ่มต้น
เรียนรู้วิธีตั้งค่า GitHub Actions สำหรับ continuous integration และ deployment ครอบคลุมเรื่อง triggers, jobs, matrices, secrets, caching, Docker และตัวอย่าง workflow ในการใช้งานจริง
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 ที่ล้มเหลว
- ตรวจสอบ logs — คลิกที่ step ที่ล้มเหลวเพื่อดู output ทั้งหมด
- เพิ่ม debug logging — ตั้งค่า secret
ACTIONS_STEP_DEBUGเป็นtrue - ใช้
actบนเครื่องตัวเอง — รัน workflows บนเครื่องของคุณด้วย nektos/act - 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 ของคุณโดยตรง:
- เริ่มจากสิ่งง่ายๆ — ไฟล์ workflow เดียวที่มี build + test
- เพิ่ม caching — ลดเวลา build ด้วย
actions/cacheหรือ built-in language caching - ใช้ matrix — ทดสอบข้ามหลายเวอร์ชันและระบบปฏิบัติการ
- ปกป้อง secrets — ห้าม hardcode เสมอ ให้ใช้ encrypted secrets
- Automate ทุกอย่าง — Releases, deployments, security scans, scheduled tasks
Pipeline CI/CD ที่ดีที่สุดคือสิ่งที่รันทุกครั้งที่ commit โดยที่คุณไม่ต้องคิดอะไรเลย ตั้งค่าครั้งเดียว แล้วปล่อยให้ GitHub จัดการส่วนที่เหลือ