CI/CD Pipeline ด้วย GitHub Actions แบบละเอียด

ในโลกของการพัฒนาซอฟต์แวร์ที่เปลี่ยนแปลงอย่างรวดเร็วในปัจจุบัน ประสิทธิภาพ ความน่าเชื่อถือ และความสามารถในการส่งมอบโค้ดใหม่ๆ สู่ผู้ใช้งานได้อย่างต่อเนื่อง คือหัวใจสำคัญของความสำเร็จครับ หนึ่งในแนวทางปฏิบัติที่ดีที่สุดที่ช่วยให้ทีมพัฒนาซอฟต์แวร์บรรลุเป้าหมายเหล่านี้ได้คือ CI/CD Pipeline หรือกระบวนการ Continuous Integration และ Continuous Delivery/Deployment นั่นเองครับ และเมื่อพูดถึงการสร้าง CI/CD Pipeline ที่ทรงพลัง ใช้งานง่าย และผสานรวมกับกระบวนการทำงานของนักพัฒนาได้อย่างไร้รอยต่อ GitHub Actions คือเครื่องมือที่โดดเด่นและเป็นที่นิยมอย่างมากในหมู่ชุมชนนักพัฒนาครับ

บทความนี้จะพาคุณเจาะลึกถึงแก่นแท้ของ CI/CD Pipeline ด้วย GitHub Actions ตั้งแต่แนวคิดพื้นฐาน ไปจนถึงการสร้าง Workflow ที่ซับซ้อน เทคนิคขั้นสูง และแนวทางปฏิบัติที่ดีที่สุด เพื่อให้คุณสามารถนำไปประยุกต์ใช้ในการพัฒนาโปรเจกต์ของคุณได้อย่างเต็มศักยภาพ ไม่ว่าคุณจะเป็นนักพัฒนาหน้าใหม่ที่เพิ่งเริ่มต้นเรียนรู้ CI/CD หรือนักพัฒนาที่มีประสบการณ์ที่ต้องการยกระดับ Pipeline ของคุณให้ดียิ่งขึ้น บทความนี้จะมีข้อมูลเชิงลึกและตัวอย่างที่ใช้งานได้จริงให้คุณได้ศึกษาอย่างละเอียดแน่นอนครับ

มาเริ่มต้นการเดินทางสู่การสร้าง CI/CD Pipeline ที่มีประสิทธิภาพด้วย GitHub Actions ไปพร้อมกันเลยครับ!

สารบัญ

ทำความเข้าใจ CI/CD Pipeline คืออะไร และทำไมถึงสำคัญ?

ก่อนที่เราจะดำดิ่งเข้าสู่โลกของ GitHub Actions เรามาทำความเข้าใจแนวคิดพื้นฐานของ CI/CD Pipeline กันก่อนครับ เพราะนี่คือรากฐานสำคัญที่จะทำให้เราเข้าใจถึงประโยชน์และวิธีการใช้งาน GitHub Actions ได้อย่างมีประสิทธิภาพสูงสุดครับ

Continuous Integration (CI) คืออะไร?

Continuous Integration (CI) คือแนวทางปฏิบัติในการพัฒนาซอฟต์แวร์ที่ให้นักพัฒนาแต่ละคนผสานรวมโค้ดของตนเข้ากับ Repository กลางบ่อยครั้ง โดยปกติจะหลายครั้งต่อวันครับ การผสานรวมแต่ละครั้งจะถูกตรวจสอบโดยการ Build อัตโนมัติและรันการทดสอบอัตโนมัติ (Automated Tests) เพื่อตรวจจับข้อผิดพลาดตั้งแต่เนิ่นๆ ครับ

วัตถุประสงค์หลักของ CI:

  • ลดปัญหาการผสานรวม (Integration Hell): เมื่อนักพัฒนาทำงานแยกกันเป็นเวลานาน การรวมโค้ดเข้าด้วยกันในภายหลังมักจะนำไปสู่ความขัดแย้งที่ซับซ้อนและใช้เวลานานในการแก้ไขครับ CI ช่วยให้การรวมโค้ดเกิดขึ้นบ่อยขึ้นในชิ้นเล็กๆ ทำให้ปัญหาที่เกิดขึ้นถูกตรวจพบและแก้ไขได้ง่ายและรวดเร็วขึ้นครับ
  • ตรวจจับข้อผิดพลาดตั้งแต่เนิ่นๆ: การ Build และ Test อัตโนมัติทุกครั้งที่มีการ Commit โค้ด ช่วยให้สามารถระบุ Bug หรือปัญหาที่เกิดจากการผสานรวมได้ทันที ซึ่งช่วยลดต้นทุนและเวลาในการแก้ไขเมื่อเทียบกับการค้นพบ Bug ในขั้นตอนที่ล่าช้ากว่าครับ
  • ปรับปรุงคุณภาพโค้ด: การมีชุดการทดสอบอัตโนมัติที่ครอบคลุมและทำงานอย่างสม่ำเสมอ เป็นการรับประกันว่าโค้ดที่ผสานรวมเข้ามานั้นมีคุณภาพตามมาตรฐานที่กำหนดครับ

Continuous Delivery (CD) และ Continuous Deployment (CD) คืออะไร?

หลังจากขั้นตอน CI ที่โค้ดถูกรวม ทดสอบ และ Build เรียบร้อยแล้ว ขั้นตอนต่อไปคือการส่งมอบซอฟต์แวร์ไปยังสภาพแวดล้อมที่พร้อมใช้งานครับ ซึ่งมีอยู่สองแนวคิดที่คล้ายกันแต่มีความแตกต่างที่สำคัญคือ Continuous Delivery และ Continuous Deployment ครับ

Continuous Delivery (CD)

Continuous Delivery (CD) คือการต่อยอดจาก CI โดยทำให้มั่นใจว่าโค้ดที่ผ่านการทดสอบและ Build แล้วจะสามารถนำไป Deploy ได้ทุกเมื่อครับ หมายความว่าหลังจากการ Build และทดสอบสำเร็จ ซอฟต์แวร์จะถูกแพ็กเกจและจัดเตรียมไว้ในสถานะที่พร้อมสำหรับการ Deploy ไปยังสภาพแวดล้อม Production ได้ตลอดเวลา แต่การ Deploy ไปยัง Production นั้นยังคงต้องอาศัยการตัดสินใจหรือการอนุมัติจากมนุษย์ (Manual Approval) ครับ

เป้าหมายของ Continuous Delivery:

  • ลดความเสี่ยงในการ Deploy: การเตรียมพร้อมสำหรับการ Deploy ตลอดเวลาช่วยลดความเสี่ยงที่เกี่ยวข้องกับการ Deploy เนื่องจากกระบวนการทั้งหมดถูกทำให้เป็นอัตโนมัติและทดสอบแล้วครับ
  • เพิ่มความยืดหยุ่น: ทีมสามารถตัดสินใจ Deploy เมื่อใดก็ได้ที่ต้องการ เช่น เมื่อมีฟีเจอร์ใหม่พร้อม หรือเมื่อต้องการแก้ไข Bug ด่วนครับ

Continuous Deployment (CD)

Continuous Deployment (CD) คือขั้นสูงสุดของ CI/CD ครับ มันคือการต่อยอดจาก Continuous Delivery โดยทำให้กระบวนการทั้งหมดเป็นอัตโนมัติอย่างสมบูรณ์ รวมถึงการ Deploy โค้ดที่ผ่านการทดสอบและ Build แล้วไปยังสภาพแวดล้อม Production โดยอัตโนมัติ โดยไม่มีการแทรกแซงจากมนุษย์เลย ครับ การเปลี่ยนแปลงทุกอย่างที่ผ่านการทดสอบอัตโนมัติจะถูกปล่อยออกสู่ผู้ใช้งานจริงทันทีครับ

เป้าหมายของ Continuous Deployment:

  • ความเร็วสูงสุดในการส่งมอบ: ช่วยให้ฟีเจอร์ใหม่ๆ หรือการแก้ไข Bug สามารถส่งมอบถึงมือผู้ใช้งานได้อย่างรวดเร็วที่สุดครับ
  • ลดการทำงานซ้ำซ้อน: ขจัดความจำเป็นในการทำงานที่ต้องทำซ้ำๆ ด้วยมือ ซึ่งช่วยลดข้อผิดพลาดที่เกิดจากมนุษย์ได้ครับ

ความแตกต่างหลักอยู่ตรงที่ว่า Continuous Delivery ยังคงต้องมี “คน” ตัดสินใจว่าจะ Deploy เมื่อไหร่ แต่ Continuous Deployment นั้น “ระบบ” จะ Deploy ให้เองทันทีที่ทุกอย่างผ่านครับ

ประโยชน์ของการใช้ CI/CD Pipeline

การนำ CI/CD Pipeline มาใช้ในกระบวนการพัฒนาซอฟต์แวร์นำมาซึ่งประโยชน์มากมาย ดังนี้ครับ

  • เพิ่มความเร็วในการส่งมอบ (Faster Time to Market): ด้วยกระบวนการอัตโนมัติที่รวดเร็วและต่อเนื่อง ทีมสามารถปล่อยฟีเจอร์ใหม่ๆ หรือการแก้ไข Bug ออกสู่ผู้ใช้งานได้บ่อยขึ้นและรวดเร็วขึ้นครับ
  • ปรับปรุงคุณภาพและความน่าเชื่อถือ (Improved Quality and Reliability): การทดสอบอัตโนมัติอย่างสม่ำเสมอช่วยตรวจจับข้อผิดพลาดได้ตั้งแต่เนิ่นๆ ลดโอกาสที่จะมี Bug หลุดรอดไปถึง Production ทำให้ซอฟต์แวร์มีคุณภาพและน่าเชื่อถือมากขึ้นครับ
  • ลดความเสี่ยง (Reduced Risk): การ Deploy การเปลี่ยนแปลงเล็กๆ บ่อยๆ มีความเสี่ยงน้อยกว่าการ Deploy การเปลี่ยนแปลงครั้งใหญ่ๆ ครับ หากเกิดปัญหา การย้อนกลับ (Rollback) ก็ทำได้ง่ายขึ้นครับ
  • ลดต้นทุน (Reduced Costs): แม้จะมีการลงทุนเริ่มต้นในการตั้งค่า แต่ในระยะยาว CI/CD ช่วยลดเวลาและทรัพยากรที่ใช้ในการแก้ไข Bug และการจัดการการ Deploy ครับ
  • เพิ่มประสิทธิภาพของทีม (Increased Team Efficiency): นักพัฒนาสามารถมุ่งเน้นไปที่การเขียนโค้ดและสร้างสรรค์สิ่งใหม่ๆ ได้เต็มที่ โดยไม่ต้องกังวลกับกระบวนการ Build และ Deploy ที่น่าเบื่อและซ้ำซากครับ
  • ข้อเสนอแนะที่รวดเร็ว (Faster Feedback Loop): ทีมจะได้รับข้อเสนอแนะเกี่ยวกับคุณภาพของโค้ดและการทำงานของฟีเจอร์ใหม่ๆ ได้อย่างรวดเร็ว ทำให้สามารถปรับปรุงและแก้ไขได้ทันท่วงทีครับ

ทำความรู้จัก GitHub Actions: หัวใจของ CI/CD ในโลก GitHub

เมื่อเราเข้าใจแนวคิดของ CI/CD แล้ว ก็ถึงเวลาที่จะมาทำความรู้จักกับ GitHub Actions ซึ่งเป็นเครื่องมือที่จะช่วยให้เราสร้าง CI/CD Pipeline เหล่านี้ได้อย่างง่ายดายและมีประสิทธิภาพครับ

GitHub Actions คือแพลตฟอร์มสำหรับ Automation ที่มีอยู่ใน GitHub โดยตรง ช่วยให้คุณสามารถสร้าง Workflow ที่สามารถตอบสนองต่อเหตุการณ์ต่างๆ ใน Repository ของคุณได้ เช่น การ Push โค้ด, การสร้าง Pull Request, การออก Release ใหม่ หรือแม้แต่การตั้งเวลาให้ทำงานเป็นประจำครับ ด้วย GitHub Actions คุณสามารถ Automate ได้เกือบทุกอย่างในวงจรการพัฒนาซอฟต์แวร์ของคุณ ตั้งแต่การ Build, Test, และ Deploy ไปจนถึงการจัดการโปรเจกต์และการสื่อสารในทีมครับ

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

หัวใจของ GitHub Actions คือไฟล์ YAML ที่กำหนด Workflow ซึ่งประกอบด้วยชุดของ Jobs ที่จะถูกเรียกใช้เมื่อมี Event ที่กำหนดไว้เกิดขึ้นครับ Workflow เหล่านี้จะถูกรันบน Runner ซึ่งเป็นเครื่องจักรเสมือนที่ GitHub จัดหาให้ หรือคุณจะใช้ Self-hosted Runner ของคุณเองก็ได้ครับ ในแต่ละ Job จะประกอบด้วย Steps ซึ่งเป็นคำสั่งหรือ Actions ที่จะดำเนินการตามลำดับครับ

ลองนึกภาพว่าคุณ Push โค้ดไปยัง Repository ของคุณครับ

  1. Event: GitHub ตรวจจับการ Push โค้ดนี้
  2. Workflow: GitHub ตรวจสอบไฟล์ Workflow (`.github/workflows/*.yml`) ของคุณ และพบว่ามี Workflow หนึ่งที่ถูกกำหนดให้ทำงานเมื่อมี Event ประเภท `push` เกิดขึ้น
  3. Jobs: Workflow นั้นเริ่มทำงาน และเรียกใช้ Jobs ที่กำหนดไว้ภายใน (เช่น Job สำหรับ Build, Job สำหรับ Test)
  4. Steps & Actions: แต่ละ Job จะมี Steps และ Actions ที่ถูกกำหนดไว้ ซึ่งจะทำงานตามลำดับที่ระบุ เช่น Step สำหรับ Checkout โค้ด, Step สำหรับติดตั้ง Dependencies, Step สำหรับรันการทดสอบ
  5. Runner: Jobs เหล่านี้จะถูกรันบน Runner (Virtual Machine) ที่ถูกสร้างขึ้นมาเฉพาะสำหรับ Workflow นั้นๆ ครับ
  6. Output: เมื่อ Jobs ทั้งหมดเสร็จสิ้น คุณจะเห็นผลลัพธ์ในแท็บ “Actions” บน GitHub Repository ของคุณครับ

องค์ประกอบหลักของ GitHub Actions

เพื่อให้เข้าใจ GitHub Actions ได้อย่างลึกซึ้งยิ่งขึ้น เรามาดูองค์ประกอบหลักๆ ที่สำคัญกันครับ

  • Workflow: ไฟล์ YAML ที่กำหนดกระบวนการอัตโนมัติทั้งหมด มันคือพิมพ์เขียวของ CI/CD Pipeline ของคุณครับ
  • Event: เหตุการณ์ที่ทริกเกอร์ให้ Workflow ทำงาน เช่น push, pull_request, issue_comment, schedule ครับ
  • Job: ชุดของ Steps ที่จะถูกรันบน Runner ตัวเดียวกัน Jobs สามารถรันแบบขนาน (Parallel) หรือเรียงลำดับ (Sequential) กันได้ครับ
  • Step: หน่วยย่อยที่สุดของการทำงานภายใน Job ซึ่งอาจเป็น Shell command หรือ Action ที่นำมาใช้ซ้ำได้ครับ
  • Action: แอปพลิเคชันที่นำกลับมาใช้ซ้ำได้ ซึ่งเป็นส่วนประกอบพื้นฐานของ Step ที่ทำงานบางอย่าง เช่น actions/checkout เพื่อดึงโค้ด หรือ actions/setup-node เพื่อตั้งค่า Node.js ครับ
  • Runner: เซิร์ฟเวอร์ที่ติดตั้ง GitHub Actions Runner application และรอรับ Job เพื่อรันครับ สามารถเป็น GitHub-hosted runner (VM ที่ GitHub จัดหาให้) หรือ Self-hosted runner (VM ที่คุณจัดการเอง) ครับ

เจาะลึกแนวคิดหลักของ GitHub Actions

เรามาทำความเข้าใจแนวคิดหลักเหล่านี้ให้ละเอียดขึ้น เพื่อให้สามารถออกแบบและสร้าง Workflow ที่มีประสิทธิภาพได้ครับ

Workflow

Workflow คือไฟล์ YAML ที่เก็บอยู่ในไดเรกทอรี .github/workflows/ ภายใน Repository ของคุณครับ ชื่อไฟล์จะเป็นอะไรก็ได้ที่คุณต้องการ เช่น ci.yml, deploy.yml เป็นต้น

โครงสร้างพื้นฐานของ Workflow:

name: My First Workflow # ชื่อ Workflow
on: [push, pull_request] # Events ที่จะทริกเกอร์ Workflow
jobs: # ชุดของ Jobs
  build: # ชื่อ Job แรก
    runs-on: ubuntu-latest # Runner ที่ใช้รัน Job นี้
    steps: # ชุดของ Steps ภายใน Job
      - uses: actions/checkout@v4 # Action สำหรับ checkout โค้ด
      - run: echo "Hello, world!" # Shell command

แต่ละ Workflow จะมี name (เป็นทางเลือกแต่แนะนำ) และ on ที่ระบุ Events ที่จะทริกเกอร์ Workflow ครับ

Events (ทริกเกอร์)

Events คือเหตุการณ์ที่เกิดขึ้นใน Repository ของคุณที่สามารถทริกเกอร์ Workflow ได้ครับ GitHub Actions รองรับ Events หลากหลายรูปแบบ:

  • push: เมื่อมีการ Push โค้ดไปยัง Branch ที่กำหนด
  • pull_request: เมื่อมีการสร้าง, เปิด, อัปเดต Pull Request
  • schedule: ตั้งเวลาให้ Workflow ทำงานตามช่วงเวลาที่กำหนด (ใช้ Cron syntax)
  • workflow_dispatch: อนุญาตให้รัน Workflow ด้วยตนเองจาก GitHub UI
  • release: เมื่อมีการสร้าง, เผยแพร่, อัปเดต Release
  • issue_comment: เมื่อมี Comment ถูกเพิ่มใน Issue หรือ Pull Request
  • และอื่นๆ อีกมากมาย

คุณสามารถระบุ Event ได้โดยตรง หรือระบุเงื่อนไขเพิ่มเติม เช่น Branch ที่ต้องการให้ Workflow ทำงานครับ

on:
  push:
    branches:
      - main # จะทำงานเมื่อมีการ push ไปยัง branch "main" เท่านั้น
  pull_request:
    branches:
      - main # จะทำงานเมื่อมีการสร้าง PR เข้าสู่ branch "main"
  schedule:
    - cron: '0 0 * * *' # รันทุกวันเวลาเที่ยงคืน UTC
  workflow_dispatch: # อนุญาตให้รันด้วยตนเอง

Jobs

Job คือชุดของ Steps ที่ทำงานเป็นกลุ่มบน Runner ตัวเดียวกันครับ ทุก Step ใน Job จะแชร์สภาพแวดล้อมเดียวกันและเข้าถึงไฟล์ที่สร้างขึ้นโดย Step ก่อนหน้าได้ครับ

คุณสมบัติสำคัญของ Job:

  • runs-on: ระบุประเภทของ Runner ที่ Job จะรัน เช่น ubuntu-latest, windows-latest, macos-latest หรือชื่อของ self-hosted runner group ครับ
  • steps: ลิสต์ของ Steps ที่จะทำงานตามลำดับ
  • needs: ระบุ Job อื่นๆ ที่ Job นี้ต้องรอให้เสร็จก่อน ทำให้สามารถสร้าง Job ที่ทำงานแบบเรียงลำดับได้ครับ
  • if: กำหนดเงื่อนไขว่า Job จะทำงานหรือไม่
  • outputs: กำหนดค่าที่ Job สามารถส่งออกไปให้ Job อื่นๆ ที่ขึ้นอยู่กับ Job นี้ได้
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Building..."
  test:
    needs: build # Job 'test' จะรันหลังจาก 'build' เสร็จสิ้น
    runs-on: ubuntu-latest
    steps:
      - run: echo "Testing..."
  deploy:
    needs: [build, test] # Job 'deploy' จะรันหลังจาก 'build' และ 'test' เสร็จสิ้น
    if: github.ref == 'refs/heads/main' # จะ deploy เฉพาะเมื่อ push ไปที่ main branch
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying..."

Steps

Step คือหน่วยที่เล็กที่สุดของงานใน Workflow ครับ แต่ละ Step สามารถเป็นได้ทั้ง Shell command หรือ Action ที่นำมาใช้ซ้ำได้ครับ

คุณสมบัติสำคัญของ Step:

  • name: ชื่อที่แสดงใน UI ของ GitHub Actions (เป็นทางเลือกแต่แนะนำ)
  • run: สั่งให้ Runner รัน Shell command (เช่น npm install, python script.py)
  • uses: ใช้ Action ที่มีอยู่แล้ว เช่น actions/checkout@v4
  • with: ส่งค่า Input ให้กับ Action ที่ใช้
  • env: กำหนด Environment Variables เฉพาะสำหรับ Step นั้น
steps:
  - name: Checkout repository # ชื่อ Step
    uses: actions/checkout@v4 # ใช้ Action จาก GitHub Marketplace
  - name: Install dependencies
    run: npm install # รัน Shell command
  - name: Run tests
    run: npm test
    env:
      NODE_ENV: test # กำหนด Environment Variable สำหรับ Step นี้

Actions

Actions คือแอปพลิเคชันที่นำกลับมาใช้ซ้ำได้ ซึ่งเป็นส่วนประกอบพื้นฐานของ Step ครับ Actions สามารถช่วยให้คุณทำงานทั่วไปได้ง่ายขึ้น เช่น การ Checkout โค้ด, การตั้งค่าสภาพแวดล้อม (Node.js, Python, Java), การอัปโหลด Artifacts เป็นต้น

Actions มีหลายประเภท:

  • GitHub-provided Actions: Actions ที่ GitHub สร้างและดูแล เช่น actions/checkout, actions/setup-node
  • Community Actions: Actions ที่สร้างโดยชุมชนนักพัฒนาและเผยแพร่ใน GitHub Marketplace
  • Custom Actions: คุณสามารถสร้าง Actions ของคุณเองได้ด้วย JavaScript หรือ Docker ครับ

การใช้ Action ทำได้โดยระบุ uses: owner/repo@ref หรือ uses: ./path/to/action (สำหรับ Custom Action ใน Repository เดียวกัน) ครับ

steps:
  - uses: actions/checkout@v4 # ใช้ Action 'checkout' เวอร์ชัน 4
  - uses: actions/setup-node@v4
    with:
      node-version: '20' # ส่ง input 'node-version' ให้กับ Action

Runners

Runner คือเซิร์ฟเวอร์ที่ติดตั้งแอปพลิเคชัน GitHub Actions Runner และรอรับ Job เพื่อรันครับ

  • GitHub-hosted runners:
    • เป็น VM ที่ GitHub จัดหาให้และจัดการเอง
    • มีหลายระบบปฏิบัติการให้เลือก (ubuntu-latest, windows-latest, macos-latest)
    • เป็นตัวเลือกเริ่มต้นและสะดวกสบายที่สุดสำหรับการใช้งานทั่วไป
    • มีทรัพยากรจำกัดและอาจมีค่าใช้จ่ายเมื่อใช้งานเกินโควต้าฟรี
  • Self-hosted runners:
    • เป็นเซิร์ฟเวอร์หรือ VM ที่คุณติดตั้งและจัดการเอง
    • เหมาะสำหรับกรณีที่ต้องการทรัพยากรเฉพาะ, สภาพแวดล้อมที่กำหนดเอง, หรือเข้าถึงเครือข่ายส่วนตัว
    • คุณต้องดูแลการบำรุงรักษาและการอัปเดตเอง

คุณระบุ Runner ที่ต้องการใช้ด้วย runs-on ใน Job ครับ

jobs:
  build:
    runs-on: ubuntu-latest # ใช้ GitHub-hosted Ubuntu runner
  deploy:
    runs-on: self-hosted # ใช้ self-hosted runner

Contexts

Contexts คือชุดของข้อมูลที่ GitHub Actions จัดเตรียมไว้ให้คุณสามารถเข้าถึงข้อมูลต่างๆ ที่เกี่ยวข้องกับ Workflow, Job, Runner, Event และอื่นๆ ได้ครับ คุณสามารถใช้ Contexts เพื่อเข้าถึงข้อมูลในรูปแบบของ Expression โดยใช้ไวยากรณ์ ${{ <context.property> }}

Contexts ที่พบบ่อย:

  • github: ข้อมูลเกี่ยวกับ Repository, Event ที่ทริกเกอร์, Commits, Pull Requests ครับ
  • env: Environment Variables ที่กำหนดไว้
  • job: ข้อมูลเกี่ยวกับ Job ปัจจุบัน
  • steps: ข้อมูลเกี่ยวกับ Steps ที่ผ่านมา รวมถึง Outputs ด้วย
  • runner: ข้อมูลเกี่ยวกับ Runner ที่กำลังทำงานอยู่
  • secrets: ค่าความลับที่ถูกจัดเก็บไว้อย่างปลอดภัย
steps:
  - name: Print branch name
    run: echo "Current branch is ${{ github.ref_name }}"
  - name: Check if it's a pull request
    if: github.event_name == 'pull_request'
    run: echo "This is a Pull Request!"

Secrets

Secrets คือค่าความลับที่คุณต้องการใช้ใน Workflow ของคุณ เช่น API keys, รหัสผ่าน, SSH private keys ครับ GitHub จะจัดเก็บ Secrets อย่างปลอดภัยและไม่เปิดเผยใน Logs ของ Workflow ครับ

คุณสามารถกำหนด Secrets ได้ที่:

  • ระดับ Repository: Settings > Secrets and variables > Actions
  • ระดับ Environment: สำหรับการ Deploy ไปยัง Environment ที่เฉพาะเจาะจง
  • ระดับ Organization: สำหรับ Secrets ที่ใช้ร่วมกันในหลาย Repository

การเข้าถึง Secret ทำได้โดยใช้ Context secrets ครับ

steps:
  - name: Deploy to production
    run: deploy-script.sh
    env:
      API_KEY: ${{ secrets.MY_API_KEY }} # ใช้ Secret ที่ชื่อ MY_API_KEY

ข้อควรระวัง: อย่า Hardcode Secrets ลงในไฟล์ Workflow ของคุณเด็ดขาดครับ และระมัดระวังในการแสดง Secrets ใน Logs ครับ

สร้าง CI/CD Pipeline แรกของคุณด้วย GitHub Actions (ตัวอย่าง Node.js)

มาถึงส่วนที่น่าตื่นเต้นที่สุดครับ เราจะมาสร้าง CI/CD Pipeline ที่ใช้งานได้จริงสำหรับแอปพลิเคชัน Node.js อย่างง่ายๆ ครับ Pipeline นี้จะประกอบด้วย:

  • CI (Continuous Integration):
    • Checkout โค้ด
    • ติดตั้ง Dependencies
    • รัน Linting เพื่อตรวจสอบคุณภาพโค้ด
    • รัน Unit Tests
    • Build แอปพลิเคชัน
    • อัปโหลด Artifacts (ไฟล์ที่ Build แล้ว)
  • CD (Continuous Delivery/Deployment):
    • ดาวน์โหลด Artifacts ที่ Build ไว้
    • จำลองขั้นตอนการ Deploy ไปยังเซิร์ฟเวอร์หรือบริการคลาวด์

การเตรียมความพร้อม

ก่อนอื่น ให้คุณสร้าง GitHub Repository ใหม่ (หรือใช้ Repository ที่มีอยู่แล้ว) และสร้างโปรเจกต์ Node.js อย่างง่ายๆ ขึ้นมาครับ

ตัวอย่างโครงสร้างโปรเจกต์ Node.js (package.json):

{
  "name": "my-node-app",
  "version": "1.0.0",
  "description": "A simple Node.js app for CI/CD demo",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "jest",
    "lint": "eslint .",
    "build": "echo \"Building app...\" && mkdir -p dist && cp index.js dist/index.js && cp package.json dist/package.json"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "eslint": "^8.56.0",
    "jest": "^29.7.0"
  }
}

ไฟล์ index.js (แอปพลิเคชัน Express อย่างง่าย):

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello from CI/CD Node.js App!');
});

app.get('/health', (req, res) => {
  res.status(200).send('OK');
});

if (require.main === module) {
  app.listen(port, () => {
    console.log(`App listening at http://localhost:${port}`);
  });
}

module.exports = app; // Export for testing

ไฟล์ .eslintrc.js (สำหรับ ESLint):

module.exports = {
  env: {
    node: true,
    commonjs: true,
    es2021: true,
    jest: true // Add jest environment for test files
  },
  extends: 'eslint:recommended',
  parserOptions: {
    ecmaVersion: 12
  },
  rules: {
    // Add custom rules here if needed
  }
};

ไฟล์ jest.config.js (สำหรับ Jest):

module.exports = {
  testEnvironment: 'node',
};

ไฟล์ index.test.js (สำหรับ Unit Test):

const request = require('supertest');
const app = require('./index'); // Import your Express app

describe('GET /', () => {
  test('It should respond with "Hello from CI/CD Node.js App!"', async () => {
    const response = await request(app).get('/');
    expect(response.statusCode).toBe(200);
    expect(response.text).toBe('Hello from CI/CD Node.js App!');
  });
});

describe('GET /health', () => {
  test('It should respond with "OK" and status 200', async () => {
    const response = await request(app).get('/health');
    expect(response.statusCode).toBe(200);
    expect(response.text).toBe('OK');
  });
});

หลังจากสร้างไฟล์เหล่านี้แล้ว ให้ Push โค้ดไปยัง GitHub Repository ของคุณครับ

สร้าง Workflow สำหรับ Continuous Integration (CI)

สร้างไฟล์ชื่อ .github/workflows/node-ci-cd.yml ใน Repository ของคุณครับ

name: Node.js CI/CD Pipeline

on:
  push:
    branches:
      - main
      - develop
  pull_request:
    branches:
      - main
      - develop

jobs:
  build_and_test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository code
        uses: actions/checkout@v4

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: '20' # Specify the Node.js version you want to use
          cache: 'npm' # Cache npm dependencies to speed up subsequent runs

      - name: Install dependencies
        run: npm ci

      - name: Run ESLint
        run: npm run lint

      - name: Run unit tests
        run: npm test

      - name: Build application
        run: npm run build

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: node-app-build
          path: dist # The directory containing your built application
          retention-days: 7 # How long to keep the artifact

มาทำความเข้าใจแต่ละ Step ใน Workflow นี้กันครับ:

1. Checkout repository code

      - name: Checkout repository code
        uses: actions/checkout@v4

Step นี้ใช้ actions/checkout@v4 เพื่อดึงโค้ดจาก Repository ของคุณไปยัง Runner ครับ นี่คือ Step แรกที่เกือบทุก Workflow จำเป็นต้องมีครับ

2. Setup Node.js environment

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

เราใช้ actions/setup-node@v4 เพื่อติดตั้ง Node.js เวอร์ชัน 20 บน Runner ครับ Parameter cache: 'npm' จะช่วยให้ GitHub Actions แคช Dependencies ของ npm ซึ่งจะช่วยลดเวลาในการติดตั้ง Dependencies ในการรัน Workflow ครั้งถัดไปได้อย่างมากครับ

3. Install dependencies

      - name: Install dependencies
        run: npm ci

คำสั่ง npm ci (Clean Install) จะติดตั้ง Dependencies ตามที่ระบุใน package-lock.json (หรือ npm-shrinkwrap.json) เพื่อให้มั่นใจว่าการติดตั้ง Dependencies มีความสอดคล้องกันทุกครั้งครับ ซึ่งแตกต่างจาก npm install ที่อาจอัปเดตเวอร์ชันของ Dependencies ได้ครับ

4. Run ESLint และ 5. Run unit tests

      - name: Run ESLint
        run: npm run lint

      - name: Run unit tests
        run: npm test

Step เหล่านี้จะรันคำสั่ง npm run lint และ npm test ตามที่กำหนดไว้ใน package.json ของคุณครับ นี่คือส่วนสำคัญของ CI ที่ช่วยตรวจสอบคุณภาพโค้ดและค้นหาข้อผิดพลาดตั้งแต่เนิ่นๆ ครับ หาก Step ใด Step หนึ่งล้มเหลว Workflow จะถูกหยุดและแสดงสถานะ Failed ครับ

6. Build application

      - name: Build application
        run: npm run build

คำสั่ง npm run build จะถูกรันเพื่อสร้างไฟล์ที่พร้อมสำหรับ Production ครับ ในตัวอย่างของเราคือการคัดลอกไฟล์ index.js และ package.json ไปยังโฟลเดอร์ dist ครับ ในโปรเจกต์จริง คุณอาจมี Webpack, Rollup หรือ Transpiler อื่นๆ ที่ทำงานใน Step นี้ครับ

7. Upload build artifact

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: node-app-build
          path: dist
          retention-days: 7

หลังจาก Build แอปพลิเคชันเสร็จแล้ว เราจะใช้ actions/upload-artifact@v4 เพื่ออัปโหลดไฟล์ที่ Build แล้ว (ในโฟลเดอร์ dist) เป็น Artifact ครับ Artifact คือไฟล์หรือโฟลเดอร์ที่ถูกสร้างขึ้นระหว่าง Workflow และสามารถดาวน์โหลดได้หลังจาก Workflow เสร็จสิ้น หรือนำไปใช้ใน Job อื่นๆ ได้ครับ retention-days กำหนดระยะเวลาที่จะเก็บ Artifact ไว้ครับ

เมื่อคุณ Commit และ Push ไฟล์ node-ci-cd.yml นี้ไปยัง GitHub Repository ของคุณ GitHub Actions จะตรวจจับ Event push และรัน Workflow นี้ทันทีครับ คุณสามารถดูสถานะและความคืบหน้าได้ในแท็บ “Actions” ของ Repository ครับ

สร้าง Workflow สำหรับ Continuous Delivery/Deployment (CD)

เราจะเพิ่ม Job ที่สองเข้าไปในไฟล์ node-ci-cd.yml เดิม เพื่อจัดการส่วนของ CD ครับ Job นี้จะขึ้นอยู่กับ Job build_and_test เพื่อให้แน่ใจว่าการ Deploy จะเกิดขึ้นเฉพาะเมื่อ Build และ Test สำเร็จเท่านั้นครับ

name: Node.js CI/CD Pipeline

on:
  push:
    branches:
      - main
      - develop
  pull_request:
    branches:
      - main
      - develop

jobs:
  build_and_test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository code
        uses: actions/checkout@v4

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run ESLint
        run: npm run lint

      - name: Run unit tests
        run: npm test

      - name: Build application
        run: npm run build

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: node-app-build
          path: dist
          retention-days: 7

  deploy:
    needs: build_and_test # This job depends on 'build_and_test' job
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' # Deploy only on push to 'main' branch
    
    # Optional: Use deployment environments for manual approvals and environment-specific secrets
    # environment:
    #   name: Production
    #   url: https://your-app.com # URL to the deployed application

    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: node-app-build
          path: ./app-to-deploy # Directory to download the artifact to

      - name: List downloaded files (for verification)
        run: ls -R ./app-to-deploy

      - name: Simulate deployment
        run: |
          echo "Simulating deployment to production server..."
          echo "Deploying artifact from ./app-to-deploy to your server..."
          # In a real scenario, this is where your actual deployment logic would go.
          # Examples:
          # - Using SCP to copy files to an SSH server:
          #   sshpass -p "${{ secrets.SSH_PASSWORD }}" scp -r ./app-to-deploy/* user@your-server-ip:/var/www/html/
          # - Using AWS S3 Sync for static sites:
          #   aws s3 sync ./app-to-deploy/ s3://your-s3-bucket/
          # - Using a cloud provider's CLI (e.g., gcloud, az, vercel):
          #   vercel deploy ./app-to-deploy --prod --token=${{ secrets.VERCEL_TOKEN }}
          # - Triggering a webhook or API call to your deployment service

          echo "Deployment simulated successfully!"

มาทำความเข้าใจ Job deploy กันครับ:

  • needs: build_and_test: Job นี้จะทำงานก็ต่อเมื่อ Job build_and_test ทำงานสำเร็จแล้วเท่านั้นครับ
  • runs-on: ubuntu-latest: Job นี้จะรันบน GitHub-hosted Ubuntu runner ครับ
  • if: github.ref == 'refs/heads/main': นี่คือเงื่อนไขสำคัญครับ เราต้องการให้ Deploy เฉพาะเมื่อมีการ Push โค้ดไปยัง Branch main เท่านั้น เพื่อป้องกันการ Deploy โค้ดที่ยังไม่สมบูรณ์ครับ github.ref จะให้ค่าเป็น refs/heads/<branch-name> ครับ
  • environment (Optional): คุณสามารถกำหนด environment ได้เพื่อวัตถุประสงค์ในการติดตามการ Deploy, การกำหนดค่าความลับเฉพาะสภาพแวดล้อม และการเพิ่ม Manual Approvals ครับ อ่านเพิ่มเติมเกี่ยวกับ Environments

1. Download build artifact

      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: node-app-build
          path: ./app-to-deploy

Step นี้ใช้ actions/download-artifact@v4 เพื่อดาวน์โหลด Artifact ที่เราอัปโหลดไว้ใน Job build_and_test ครับ โดยจะถูกดาวน์โหลดไปยังโฟลเดอร์ ./app-to-deploy บน Runner ครับ

2. การนำไป Deploy จริง (ตัวอย่างแนวคิด)

      - name: Simulate deployment
        run: |
          echo "Simulating deployment to production server..."
          echo "Deploying artifact from ./app-to-deploy to your server..."
          # ... (ตัวอย่างโค้ดจริงสำหรับการ Deploy) ...
          echo "Deployment simulated successfully!"

นี่คือหัวใจของกระบวนการ Deploy ครับ ในตัวอย่างนี้ เราได้ใส่เพียงคำสั่ง echo เพื่อจำลองว่ากำลัง Deploy อยู่ครับ

ในสถานการณ์จริง คุณจะต้องใส่คำสั่งหรือ Action ที่เหมาะสมกับการ Deploy แอปพลิเคชันของคุณครับ ตัวอย่างเช่น:

  • Static Site (เช่น React, Vue, Angular) ไปยัง S3/Netlify/Vercel:
    # For AWS S3
    aws s3 sync ./app-to-deploy/ s3://your-s3-bucket-name/ --delete
    # For Vercel
    npm install -g vercel
    vercel deploy ./app-to-deploy --prod --token=${{ secrets.VERCEL_TOKEN }}
    
  • Node.js Backend ไปยัง EC2/VPS ผ่าน SSH:
    # ต้องติดตั้ง sshpass หรือใช้ SSH key ที่ปลอดภัยกว่า
    # ติดตั้ง sshpass (ในกรณีที่จำเป็น)
    # sudo apt-get update && sudo apt-get install -y sshpass
    
    # Deploy ผ่าน SSH (ต้องตั้งค่า SSH_USERNAME, SSH_HOST, SSH_PASSWORD หรือ SSH_PRIVATE_KEY ใน GitHub Secrets)
    # ใช้ rsync เพื่อคัดลอกไฟล์
    rsync -avz --delete ./app-to-deploy/ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/var/www/your-app/
    # รันคำสั่งบนเซิร์ฟเวอร์เพื่อรีสตาร์ทแอป
    ssh ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} "cd /var/www/your-app && npm install --production && pm2 restart your-app-name"
    

    หมายเหตุ: การใช้รหัสผ่านผ่าน Environment Variable เช่น SSH_PASSWORD ไม่ใช่วิธีที่ปลอดภัยที่สุดครับ ควรใช้ SSH Key และตั้งค่า Key ใน Secrets แทนครับ

  • Containerized App (Docker) ไปยัง Docker Hub และ Kubernetes:
    # Build Docker image
    docker build -t your-docker-id/my-node-app:latest ./app-to-deploy
    
    # Login to Docker Hub
    echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
    
    # Push Docker image
    docker push your-docker-id/my-node-app:latest
    
    # Deploy to Kubernetes (using kubectl)
    # kubectl apply -f kubernetes/deployment.yaml
    

เมื่อคุณ Commit และ Push การเปลี่ยนแปลงนี้ไปยัง Branch main Workflow ของคุณจะรันทั้ง Job build_and_test และ Job deploy ตามลำดับครับ

เทคนิคขั้นสูงสำหรับ GitHub Actions

GitHub Actions มีความสามารถที่หลากหลายและยืดหยุ่นมากครับ นอกจากพื้นฐานแล้ว ยังมีเทคนิคขั้นสูงอีกหลายอย่างที่จะช่วยให้ Workflow ของคุณมีประสิทธิภาพ ปลอดภัย และจัดการได้ง่ายขึ้นครับ

Matrix Strategies: การทดสอบข้ามสภาพแวดล้อม

Matrix Strategy ช่วยให้คุณสามารถรัน Job เดียวกันหลายๆ ครั้ง โดยใช้ชุดของตัวแปรที่แตกต่างกันไปครับ มีประโยชน์อย่างมากสำหรับการทดสอบแอปพลิเคชันของคุณกับ Node.js หลายเวอร์ชัน, ระบบปฏิบัติการหลายประเภท หรือแม้กระทั่ง Browser หลายตัวครับ

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [18, 20]
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install dependencies
        run: npm ci
      - name: Run tests
        run: npm test

ในตัวอย่างนี้ Job test จะถูกรัน 4 ครั้ง (2 OS x 2 Node.js versions) ทำให้มั่นใจได้ว่าแอปพลิเคชันของคุณทำงานได้ดีในหลายสภาพแวดล้อมครับ

Caching Dependencies: เพิ่มความเร็วให้ Workflow

การติดตั้ง Dependencies เช่น npm install, pip install, หรือ composer install มักใช้เวลานานครับ GitHub Actions มี Action actions/cache@v3 ที่ช่วยให้คุณแคช Dependencies เหล่านี้ได้ ทำให้ Workflow รันได้เร็วขึ้นอย่างมากในการรันครั้งถัดไปครับ

steps:
  - uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm' # ใช้ cache built-in ของ setup-node action

  # หรือใช้ actions/cache@v3 สำหรับกรณีที่ซับซ้อนกว่า
  # - name: Cache dependencies
  #   uses: actions/cache@v3
  #   with:
  #     path: ~/.npm # หรือ node_modules สำหรับ Yarn/pnpm
  #     key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
  #     restore-keys: |
  #       ${{ runner.os }}-node-

  - name: Install dependencies
    run: npm ci

การเลือกใช้ cache: 'npm' ใน setup-node action เป็นวิธีที่ง่ายและแนะนำสำหรับโปรเจกต์ Node.js ครับ หากต้องการแคชที่ซับซ้อนขึ้นสำหรับภาษาอื่น หรือต้องการปรับแต่ง Path การแคช คุณสามารถใช้ actions/cache@v3 ได้โดยตรงครับ

Environment Variables และ Secrets

เราได้กล่าวถึง Secrets ไปแล้วก่อนหน้านี้ว่าเป็นวิธีที่ปลอดภัยในการจัดเก็บข้อมูลที่ละเอียดอ่อนครับ นอกจากนี้ คุณยังสามารถกำหนด Environment Variables ได้ในระดับต่างๆ ครับ

  • ระดับ Workflow: ใช้ env: ที่ระดับบนสุดของ Workflow
  • ระดับ Job: ใช้ env: ภายใน Job
  • ระดับ Step: ใช้ env: ภายใน Step
name: Env and Secrets Demo

on: [push]

env:
  GLOBAL_VAR: "This is a global variable"

jobs:
  my_job:
    runs-on: ubuntu-latest
    env:
      JOB_VAR: "This is a job variable"
    steps:
      - name: Print variables
        run: |
          echo "Global var: ${{ env.GLOBAL_VAR }}"
          echo "Job var: ${{ env.JOB_VAR }}"
          echo "Secret: ${{ secrets.MY_SECRET }}" # เข้าถึง secret
        env:
          STEP_VAR: "This is a step variable" # กำหนด env เฉพาะ step
          # สามารถ override env ระดับที่สูงกว่าได้
          JOB_VAR: "Overridden job variable"

การใช้ Environment Variables ช่วยให้ Workflow ของคุณยืดหยุ่นและปรับแต่งได้ง่าย โดยไม่ต้องแก้ไขโค้ด Workflow ครับ

Reusable Workflows: การสร้าง Workflow ที่นำกลับมาใช้ซ้ำได้

เมื่อโปรเจกต์ของคุณเติบโตขึ้น คุณอาจพบว่ามี Workflow หลายตัวที่มี Steps หรือ Jobs ที่คล้ายกันครับ Reusable Workflows ช่วยให้คุณสามารถสร้าง Workflow ที่สามารถเรียกใช้จาก Workflow อื่นๆ ได้ ทำให้โค้ด Workflow ของคุณ DRY (Don’t Repeat Yourself) และง่ายต่อการบำรุงรักษาครับ

ตัวอย่าง: Workflow ที่เรียกใช้ได้ (.github/workflows/callable-build.yml)

name: Callable Build & Test

on:
  workflow_call: # กำหนดให้ Workflow นี้สามารถถูกเรียกใช้ได้
    inputs:
      node-version:
        required: true
        type: string
        description: 'Node.js version to use'
    outputs:
      build-output:
        description: "Path to the built artifact"
        value: ${{ jobs.build.outputs.artifact-path }}
    secrets:
      NPM_TOKEN:
        required: false

jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      artifact-path: ${{ steps.upload.outputs.artifact-path }}
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - name: Install dependencies
        run: npm ci
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # ใช้ secret ที่ส่งมา
      - name: Run tests
        run: npm test
      - name: Build application
        run: npm run build
      - name: Upload build artifact
        id: upload # กำหนด id ให้ step เพื่อเข้าถึง outputs
        uses: actions/upload-artifact@v4
        with:
          name: node-app-build-${{ github.run_id }}
          path: dist
          retention-days: 7
        env:
          artifact-path: dist # กำหนด output ของ step นี้

ตัวอย่าง: Workflow ที่เรียกใช้ Reusable Workflow (.github/workflows/main-ci-cd.yml)

name: Main CI/CD Pipeline

on:
  push:
    branches: [main]

jobs:
  ci:
    uses: ./.github/workflows/callable-build.yml # เรียกใช้ Reusable Workflow
    with:
      node-version: '20'
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # ส่ง secret ไปยัง Reusable Workflow
  
  deploy:
    needs: ci
    runs-on: ubuntu-latest
    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: node-app-build-${{ github.run_id }}
          path: ./app-to-deploy
      - name: Deploy to production
        run: echo "Deploying from ${{ github.workspace }}/app-to-deploy"
        # ... your deployment logic ...

Reusable Workflows ช่วยให้คุณสามารถสร้าง Component ของ Workflow ที่เป็นมาตรฐานและนำกลับมาใช้ได้ทั่วทั้ง Organization หรือ Repository ของคุณครับ อ่านเพิ่มเติมเกี่ยวกับการสร้าง Reusable Workflows

Self-Hosted Runners: รัน Workflow ในโครงสร้างพื้นฐานของคุณ

ในบางกรณี คุณอาจต้องการรัน Workflow บนเครื่องของคุณเองแทนที่จะใช้ GitHub-hosted runners ครับ เช่น:

  • ต้องการฮาร์ดแวร์เฉพาะ: GPU สำหรับ Machine Learning, CPU ที่มีประสิทธิภาพสูง
  • ต้องการสภาพแวดล้อมที่กำหนดเอง: ซอฟต์แวร์เฉพาะ, การตั้งค่าเครือข่ายพิเศษ
  • เข้าถึงทรัพยากรภายในเครือข่ายส่วนตัว: ฐานข้อมูล, เซิร์ฟเวอร์ภายในองค์กร
  • ลดค่าใช้จ่าย: หากคุณมีการใช้งาน GitHub Actions จำนวนมาก การใช้ Self-hosted runners อาจคุ้มค่ากว่า

การตั้งค่า Self-hosted runner ประกอบด้วยการติดตั้งแอปพลิเคชัน GitHub Actions Runner บนเครื่อง Linux, Windows หรือ macOS ของคุณ และลงทะเบียนกับ GitHub ครับ จากนั้นคุณสามารถระบุ runs-on: self-hosted หรือใช้ Label ที่กำหนดเอง เช่น runs-on: [self-hosted, linux, x64, my-custom-label] ใน Job ของคุณได้ครับ

ข้อควรพิจารณา: คุณต้องรับผิดชอบในการบำรุงรักษา, อัปเดต, และความปลอดภัยของ Self-hosted runner ของคุณเองครับ

Deployment Environments และ Manual Approvals

สำหรับกระบวนการ Continuous Delivery ที่ต้องการการตรวจสอบหรืออนุมัติก่อนการ Deploy ไปยัง Production GitHub Actions มีฟีเจอร์ Deployment Environments ครับ

คุณสามารถกำหนด Environment เช่น “Staging”, “Production” ใน Repository Settings ได้ครับ สำหรับแต่ละ Environment คุณสามารถ:

  • กำหนดผู้ตรวจสอบ (Reviewers): กำหนดให้บุคคลหรือทีมบางคนต้องอนุมัติก่อนที่ Workflow จะ Deploy ไปยัง Environment นั้นๆ
  • กำหนดเวลาป้องกัน (Wait Timer): กำหนดให้ Workflow รอเป็นระยะเวลาหนึ่งก่อนที่จะ Deploy
  • กำหนด Secrets เฉพาะ Environment: Secrets ที่จะถูกเปิดเผยเฉพาะเมื่อ Deploy ไปยัง Environment นั้นๆ เท่านั้น

การใช้ใน Workflow:

jobs:
  deploy-to-production:
    runs-on: ubuntu-latest
    environment:
      name: Production # กำหนด Environment ที่จะ Deploy
      url: https://your-production-app.com # URL ของแอปที่ถูก deploy
    steps:
      - name: Deploy to production
        run: echo "Deploying to production with approval..."
        env:
          PROD_API_KEY: ${{ secrets.PROD_API_KEY }} # ใช้ Secret เฉพาะ Production

เมื่อ Workflow นี้ถูกทริกเกอร์และถึง Job deploy-to-production หากมีการกำหนด Reviewers ไว้ Workflow จะหยุดรอการอนุมัติก่อนดำเนินการต่อครับ

Monorepos และ Path Filtering

ใน Monorepo ที่มีโปรเจกต์หลายตัวใน Repository เดียวกัน คุณอาจไม่ต้องการให้ Workflow ทั้งหมดรันเมื่อมีการเปลี่ยนแปลงเพียงส่วนเล็กๆ ของโค้ดครับ GitHub Actions รองรับ Path Filtering ซึ่งช่วยให้คุณกำหนดได้ว่า Workflow จะรันเมื่อมีการเปลี่ยนแปลงใน Path ที่กำหนดเท่านั้นครับ

on:
  push:
    paths:
      - 'services/frontend/**' # Workflow นี้จะทำงานเมื่อโค้ดในโฟลเดอร์ frontend เปลี่ยนแปลง
      - '.github/workflows/frontend-ci.yml' # และเมื่อไฟล์ workflow นี้เปลี่ยนแปลงด้วย
  pull_request:
    paths:
      - 'services/frontend/**'

คุณยังสามารถใช้ Conditional logic ใน Jobs หรือ Steps เพื่อตรวจสอบว่า Path ใดเปลี่ยนแปลงไป และรันส่วนที่เกี่ยวข้องเท่านั้นได้ครับ

แนวทางปฏิบัติที่ดีที่สุดสำหรับ CI/CD ด้วย GitHub Actions

เพื่อให้ GitHub Actions Pipeline ของคุณมีประสิทธิภาพ ปลอดภัย และจัดการได้ง่าย มีแนวทางปฏิบัติที่ดีที่สุดบางอย่างที่คุณควรพิจารณาครับ

ความปลอดภัย

  • ใช้ Secrets อย่างระมัดระวัง:
    • อย่า Hardcode Secrets ใน Workflow ของคุณครับ
    • ใช้ Secrets ใน GitHub Actions และจำกัดสิทธิ์การเข้าถึงให้เฉพาะ Workflow หรือ Environment ที่จำเป็นเท่านั้น
    • หลีกเลี่ยงการแสดง Secrets ใน Logs ของ Workflow (GitHub Actions จะเซ็นเซอร์โดยอัตโนมัติ แต่ควรระมัดระวังการสร้าง Output ที่อาจเปิดเผย Secret)
  • จำกัดสิทธิ์ของ Access Token: GitHub Actions จะสร้าง GITHUB_TOKEN สำหรับแต่ละ Workflow ครับ คุณสามารถกำหนดสิทธิ์ (permissions) ของ Token นี้ได้ในระดับ Workflow หรือ Job เพื่อให้มีสิทธิ์น้อยที่สุดเท่าที่จำเป็น (Least Privilege) ครับ
  • ตรวจสอบ Actions ของบุคคลที่สาม: ก่อนใช้ Actions จาก GitHub Marketplace ให้ตรวจสอบผู้สร้าง, จำนวนการใช้งาน, รีวิว, และโค้ดของ Action นั้นๆ เพื่อความปลอดภัยครับ
  • พินเวอร์ชันของ Actions: ใช้เวอร์ชันที่แน่นอนของ Actions (เช่น @v4 หรือ @commit_hash) แทนที่จะใช้ @latest เพื่อหลีกเลี่ยงการเปลี่ยนแปลงที่ไม่คาดคิดครับ
  • ใช้ Environments และ Manual Approvals: โดยเฉพาะสำหรับการ Deploy ไปยัง Production เพื่อเพิ่มชั้นความปลอดภัยและการตรวจสอบครับ

ประสิทธิภาพ

  • ใช้ Caching อย่างมีประสิทธิภาพ: แคช Dependencies, Build artifacts เพื่อลดเวลาในการรัน Workflow ครับ
  • รัน Jobs แบบขนาน: หาก Jobs ไม่ได้ขึ้นต่อกัน ให้รันแบบขนานเพื่อประหยัดเวลาครับ
  • ใช้ Self-hosted runners สำหรับงานหนัก: หากคุณมีงานที่ต้องใช้ทรัพยากรสูง หรือต้องการฮาร์ดแวร์เฉพาะ Self-hosted runners อาจเป็นทางเลือกที่ดีกว่าครับ
  • Path Filtering ใน Monorepos: รัน Workflow เฉพาะเมื่อมีการเปลี่ยนแปลงในส่วนที่เกี่ยวข้องเท่านั้นครับ
  • ลดขนาด Docker Images: หากคุณ Build Docker Images พยายามทำให้ Image มีขนาดเล็กที่สุดเพื่อลดเวลาในการ Build และ Push ครับ

ความสามารถในการบำรุงรักษา

จัดส่งรวดเร็วส่งด่วนทั่วประเทศ
รับประกันสินค้าเคลมง่าย มีใบรับประกัน
ผ่อนชำระได้บัตรเครดิต 0% สูงสุด 10 เดือน
สะสมแต้ม รับส่วนลดส่วนลดและคะแนนสะสม

© 2026 SiamLancard — จำหน่ายการ์ดแลน อุปกรณ์ Server และเครื่องพิมพ์ใบเสร็จ

SiamLancard
Logo
Free Forex EA Download — XM Signal · EA Forex ฟรี
iCafeForex.com - สอนเทรด Forex | SiamCafe.net
Shopping cart