Pre-commit Hook: ตรวจสอบ Code อัตโนมัติก่อนทุก Commit

Git Hook เป็นเครื่องมือที่ช่วยให้คุณสามารถรัน Script อัตโนมัติในช่วงเวลาที่กำหนดในกระบวนการทำงาน Git ได้ Pre-commit Hook คือ Hook ที่ทำงานก่อนการ Commit ทุกครั้ง ซึ่งช่วยให้คุณตรวจสอบและแก้ไขปัญหาในโค้ดได้ก่อนที่จะบันทึกลงในประวัติ Git

Git Hook คืออะไร?

Git Hook คือไฟล์ Script ที่ Git จะรันอัตโนมัติเมื่อเกิดเหตุการณ์บางอย่างในระหว่างการทำงานกับ Repository Hook มีหลายประเภท ได้แก่ Pre-commit, Post-commit, Pre-push, Pre-rebase เป็นต้น Pre-commit Hook เป็นอันที่นิยมใช้มากที่สุดเพราะมันช่วยป้องกันการ Commit โค้ดที่มีปัญหาได้

ที่อยู่ของ Pre-commit Hook (.git/hooks/)

ไฟล์ Git Hook ทั้งหมดจะอยู่ในโฟลเดอร์ .git/hooks/ ซึ่งสร้างขึ้นโดยอัตโนมัติเมื่อคุณสร้าง Repository ใหม่ หรือ Clone Repository จาก Remote Pre-commit Hook จะเป็นไฟล์ชื่อ “pre-commit” ที่ไม่มีนามสกุล

.git/hooks/
├── pre-commit
├── post-commit
├── pre-push
├── prepare-commit-msg
└── commit-msg

สร้าง Pre-commit Hook แบบมี Script

การสร้าง Pre-commit Hook ทำได้โดยสร้างไฟล์ที่ชื่อว่า “pre-commit” ในโฟลเดอร์ .git/hooks/ และเขียน Bash Script หรือภาษาอื่นๆ ตามที่ต้องการ ตัวอย่างนี้จะตรวจสอบการ Lint โค้ด JavaScript ก่อนการ Commit

#!/bin/bash
# Pre-commit hook to check code quality

echo "Running pre-commit checks..."

# Check if eslint is installed
if ! command -v eslint > /dev/null; then
    echo "ESLint not found. Installing..."
    npm install --save-dev eslint
fi

# Run ESLint on staged files
GIT_STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')

if [ -n "$GIT_STAGED_FILES" ]; then
    echo "Linting files:"
    echo "$GIT_STAGED_FILES"
    npx eslint $GIT_STAGED_FILES
    if [ $? -ne 0 ]; then
        echo "ESLint check failed. Commit aborted."
        exit 1
    fi
fi

echo "All checks passed!"
exit 0

หลังจากสร้างไฟล์ Pre-commit Hook แล้ว คุณต้องให้สิทธิ์การทำงาน (Execute Permission) ให้กับไฟล์นี้:

chmod +x .git/hooks/pre-commit

ใช้ Pre-commit Framework (Pip Install)

Pre-commit Framework เป็นเครื่องมือที่ทำให้การจัดการ Git Hook ง่ายขึ้นมาก คุณไม่ต้องเขียน Shell Script เองแต่อย่างใด เพราะ Framework นี้มี Hook ที่สำเร็จรูปให้ใช้มากมายแล้ว

การติดตั้ง Pre-commit Framework ทำได้ดังนี้:

pip install pre-commit

การตั้งค่า .pre-commit-config.yaml

สร้างไฟล์ .pre-commit-config.yaml ในโฟลเดอร์หลักของ Repository เพื่อกำหนด Hook ที่ต้องการใช้

repos:
  - repo: https://github.com/psf/black
    rev: 23.1.0
    hooks:
      - id: black
        language_version: python3

  - repo: https://github.com/PyCQA/flake8
    rev: 6.0.0
    hooks:
      - id: flake8

  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.35.0
    hooks:
      - id: eslint
        types: [javascript]

  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
        args: ['--baseline', '.secrets.baseline']

จากนั้นรัน Command นี้เพื่อติดตั้ง Hook:

pre-commit install

Pre-commit Hook ที่นิยมใช้

1. Black – Formatter สำหรับ Python ที่ทำให้โค้ด Python มีรูปแบบเดียวกันทั่วโปรเจกต์

2. ESLint – Linter สำหรับ JavaScript ที่ช่วยตรวจสอบปัญหาในโค้ด JS

3. Prettier – Formatter สำหรับ JavaScript, HTML, CSS ที่ช่วยปรับรูปแบบโค้ดให้สวยงาม

4. Detect-secrets – ตรวจสอบ Secret Key, Password, Token ที่อาจจะ Commit โดยผิดพลาด

5. Pylint – Linter สำหรับ Python ที่มีความเข้มงวดมากขึ้น

ข้ามการทำงานของ Pre-commit Hook (–no-verify)

บางครั้งคุณอาจต้องข้ามการทำงานของ Pre-commit Hook ทั้งหมด โดยการใช้ Flag --no-verify ด้วย Command นี้:

git commit -m "Your commit message" --no-verify

หมายเหตุ: ควรใช้ --no-verify เฉพาะเมื่อจำเป็นเท่านั้น เพราะอาจจะ Commit โค้ดที่มีปัญหาได้

Best Practices สำหรับ Pre-commit Hook

  • ให้ Hook ทำงานเร็ว – Hook ควรทำงานสำเร็จภายในเวลาไม่กี่วินาที เพื่อไม่รบกวนการทำงาน
  • ชัดเจนในการแสดง Error – เมื่อ Hook ล้มเหลว ให้แสดงข้อความ Error ที่ชัดเจนว่าเกิดปัญหาอะไร
  • ไม่บังคับสิ่งที่ไม่จำเป็น – ใช้ Hook เพื่อตรวจสอบคุณภาพโค้ดเท่านั้น ไม่ควรบังคับให้เปลี่ยนโค้ดโดยอัตโนมัติ
  • บันทึก Hook ใน Repository – หากต้องการให้ทีมสมาชิกทั้งหมดใช้ Hook เดียวกัน ให้บันทึก Hook ในโฟลเดอร์ scripts/ และให้คำแนะนำในการติดตั้ง
  • ทดสอบ Hook ก่อนใช้งาน – ตรวจสอบให้แน่ใจว่า Hook ทำงานถูกต้องก่อนนำไปใช้ในโปรเจกต์จริง

Pre-commit Hook เป็นเครื่องมือที่สำคัญในการรักษาคุณภาพโค้ดและป้องกันปัญหาที่จะเกิดขึ้นในอนาคต การใช้งาน Pre-commit Hook อย่างถูกต้องจะช่วยให้ทีมของคุณสามารถสรุปโค้ดที่มีคุณภาพสูงได้