ป้องกัน Branch ใน GitHub/GitLab ด้วย Branch Protection Rules

การบริหารจัดการโค้ดในระบบ Version Control เช่น GitHub และ GitLab เป็นส่วนสำคัญของกระบวนการพัฒนาซอฟต์แวร์สมัยใหม่ หนึ่งในความท้าทายที่ทีมพัฒนาต้องเผชิญคือการป้องกันการเปลี่ยนแปลงที่ไม่ได้อนุมัติในบรานช์สำคัญ เช่น main หรือ production บทความนี้จะแนะนำวิธีการตั้งค่า Branch Protection Rules ใน GitHub และ GitLab เพื่อปกป้องเบรนช์สำคัญของคุณ

Branch Protection Rules คืออะไร

Branch Protection Rules เป็นกลไกความปลอดภัยที่ช่วยให้คุณสามารถตั้งข้อจำกัดการเข้าถึงและการแก้ไขบรานช์เฉพาะใน Repository ได้ โดยอนุญาตให้เฉพาะผู้ที่ได้รับสิทธิเท่านั้นที่จะสามารถ Merge Code เข้าไปในบรานช์ที่ปกป้องได้

1. ป้องกัน Force Push ที่ทำลาย Git History

Force Push สามารถจำลองการเปลี่ยนแปลงที่ผ่านมาแล้วได้ ซึ่งอาจส่งผลให้เสียข้อมูลหรือทำให้บันทึกประวัติกิจกรรมสับสน Branch Protection Rules จะป้องกันการ Force Push ต่อบรานช์ที่ปกป้อง

2. บังคับใช้ Code Review ก่อน Merge

กลไกนี้ช่วยให้ทีมสามารถตรวจสอบ Pull Request ก่อนทำการ Merge เข้าสู่บรานช์หลัก ซึ่งช่วยลดโอกาสที่นำ Bug เข้ามาในเบรนช์หลัก

3. ต้องผ่าน CI/CD Tests

การตั้งค่าให้ Branch Protection Rules ต้องผ่าน Automated Tests ก่อน Merge จะช่วยให้มั่นใจว่าโค้ดใหม่ไม่ทำลายฟีเจอร์เดิมหรือการทำงานของระบบ

4. ป้องกันการลบบรานช์โดยไม่ตั้งใจ

บรานช์สำคัญสามารถถูกลบออกได้หากไม่มีการป้องกัน Branch Protection Rules จะป้องกันการลบบรานช์โดยไม่ได้รับอนุมัติจากผู้บริหารระบบ

ตั้งค่า Branch Protection Rules บน GitHub

การตั้งค่า Branch Protection Rules บน GitHub นั้นตรงไปตรงมาและมีตัวเลือกการปรับแต่งมากมาย ต่อไปนี้คือขั้นตอนทีละขั้น:

ขั้นตอนที่ 1: เข้าไปที่ Repository Settings

  • ไปที่หน้า Repository ของคุณ
  • คลิก “Settings” ที่มุมขวาบน
  • เลือก “Branches” จากเมนูด้านซ้าย

ขั้นตอนที่ 2: เพิ่ม Branch Protection Rule

  • คลิก “Add rule” ในส่วน “Branch protection rules”
  • พิมพ์ชื่อบรานช์ที่ต้องการปกป้อง เช่น “main” หรือ “production”
  • สามารถใช้ Wildcard (*) เพื่อปกป้องหลายบรานช์ เช่น “release/*” เพื่อปกป้องบรานช์ที่มีชื่อขึ้นต้นด้วย “release”

ขั้นตอนที่ 3: ตั้งค่า Protection Options

มีตัวเลือกการปรับแต่งหลายอย่างที่คุณสามารถเลือก:

  • Require pull request reviews before merging: บังคับให้มี Code Review ก่อน Merge (ตั้ง Minimum Approvals เป็น 1-2 คน)
  • Require status checks to pass before merging: ต้องให้ CI/CD Tests ผ่านก่อน Merge
  • Require conversation resolution: ต้องแก้ไขความเห็นทั้งหมดก่อน Merge
  • Require code owners approval: ต้องได้รับอนุมัติจาก Code Owner (ตามที่กำหนดไว้ใน CODEOWNERS file)
  • Dismiss stale pull request approvals: ยกเลิก Approval เก่า เมื่อมีการ Push Commit ใหม่
  • Allow deletions: ปิดให้ไม่สามารถลบบรานช์ได้
  • Require linear history: อนุญาตเฉพาะ Merge Commit ที่ไม่สร้าง Merge Conflicts

ขั้นตอนที่ 4: บันทึกการตั้งค่า

  • คลิก “Create” หรือ “Save changes” เมื่อเสร็จแล้ว
  • ตรวจสอบว่า Rule มีผลใช้งานอยู่

ตั้งค่า Branch Protection บน GitLab

GitLab มีแนวทางการป้องกันบรานช์ที่คล้ายกันกับ GitHub แต่มีตัวเลือกและชื่อที่ต่างกันบ้าง

ขั้นตอนที่ 1: เข้า Repository Settings

  • ไปที่ Project Repository ของคุณ
  • คลิก “Settings” จากเมนูด้านซ้าย
  • เลือก “Repository” > “Protected Branches”

ขั้นตอนที่ 2: สร้าง Protected Branch

  • เลือกบรานช์ที่ต้องการปกป้องจาก Dropdown
  • สำหรับ “Allowed to merge” เลือก “Maintainers only” หรือเลือกกลุ่มที่สามารถ Merge ได้
  • สำหรับ “Allowed to push” ตั้งเป็น “No one” เพื่อให้ต้อง Push ผ่าน Merge Request เท่านั้น
  • เพิ่มเติม: คุณสามารถเลือก “Require approval” เพื่อบังคับให้มีการอนุมัติก่อน Merge
  • คลิก “Protect” เมื่อเสร็จแล้ว

1. ป้องกัน Main, Develop, และ Release Branches

อย่างน้อยควรป้องกัน main branch ไว้ เพิ่มเติมการป้องกัน develop และ release branches จะช่วยให้มั่นใจว่าคุณภาพของเบรนช์เหล่านั้นด้วย

2. ตั้ง Minimum 1-2 Reviewers

อย่างน้อย 1 คนควรตรวจสอบก่อน Merge เพื่อให้มั่นใจว่าคุณภาพของโค้ด ถ้าทีมมีขนาดใหญ่ อาจตั้งเป็น 2 Reviewers

3. เปิด Dismiss Stale Reviews

เมื่อมี Commit ใหม่เกิด PR Approval เก่าจะถูกยกเลิก เพื่อให้มั่นใจว่า Reviewer ตรวจสอบ Code ใหม่แล้ว

4. ใช้ CODEOWNERS File

สร้าง CODEOWNERS File ในโฟลเดอร์ .github เพื่อระบุว่าใครเป็นเจ้าของแต่ละส่วนของ Code ได้:

# CODEOWNERS file
# This file identifies the code owners for different directories

# Backend API
/api/** @backend-team

# Frontend UI
/frontend/** @frontend-team

# Database schemas
/migrations/** @devops-team

# Documentation
/docs/** @tech-writers

5. ทดสอบ Locally ก่อน Push

แม้ว่า Branch Protection Rules มี CI/CD Tests แต่ควรทดสอบในเครื่องของคุณเสียก่อน เพื่อหลีเลี่ยงการ Push Commit ที่ล้มเหลว:

# ทดสอบก่อน Push
npm test
npm run lint

# ถ้าทดสอบผ่านทั้งหมด จึง Push ขึ้น
git push origin feature/new-feature

ตัวอย่าง Workflow ที่ถูกต้องกับ Branch Protection Rules

เมื่อมี Branch Protection Rules ตั้งค่าอยู่แล้ว ขั้นตอนการพัฒนาควรเป็นดังนี้:

# 1. สร้าง Feature Branch จาก Develop
git checkout -b feature/new-login develop

# 2. ทำการเปลี่ยนแปลง และ Commit
git add .
git commit -m "Add new login form"

# 3. Push ไป Remote
git push origin feature/new-login

# 4. เปิด Pull Request บน GitHub/GitLab
# ผ่านหน้า Web Interface

# 5. GitHub/GitLab จะตรวจสอบ:
#    - มี Code Review ครบตามจำนวน?
#    - CI/CD Tests ผ่านหรือไม่?
#    - ความเห็นได้รับการแก้ไขไปแล้วหรือ?

# 6. เมื่อทุกอย่างผ่าน Maintainer สามารถ Merge ได้
# 7. Feature Branch จะถูกลบโดยอัตโนมัติ

GitHub Rulesets: ระบบป้องกันบรานช์ที่ทันสมัย

GitHub เพิ่มเติม GitHub Rulesets ซึ่งเป็นระบบป้องกันที่ยืดหยุ่นและทรงพลังกว่า Branch Protection Rules กฎนี้สามารถใช้ได้ที่ระดับ Organization และสามารถครอบคลุมบรานช์หลายตัวพร้อมกัน

ข้อดีของ GitHub Rulesets:

  • ตั้งค่าได้ที่ระดับ Organization แทนเพียงแค่ Repository
  • สามารถผสมผสานหลายกฎเข้าด้วยกัน
  • มี Enforcement ที่ละเอียดกว่า
  • สามารถสร้าง Custom Rules ได้

Conventional Commits กับ Branch Protection

เมื่อใช้ Branch Protection Rules ร่วมกับ Conventional Commits Convention จะช่วยให้ Code History เป็นระเบียบและติดตามได้ง่ายขึ้น ตัวอย่างของ Conventional Commit Messages:

feat: add new user authentication module
fix: resolve login form validation bug
docs: update README with installation steps
refactor: simplify database connection logic
test: add unit tests for payment module
chore: update dependencies