วิธีทำให้เวิร์กโฟลว์การพัฒนาทีมของคุณง่ายขึ้นด้วย Git Hooks

เผยแพร่แล้ว: 2022-03-10
สรุปอย่างรวดเร็ว ↬ เวิร์กโฟลว์การพัฒนาสามารถหลุดพ้นจากมือได้อย่างง่ายดาย และเริ่มก่อให้เกิดความสับสนและความขัดแย้งภายในทีม — โดยเฉพาะอย่างยิ่งเมื่อมีขนาดใหญ่ขึ้น มีหลายครั้งเกินไปที่การตรวจสอบโค้ดของเราเพิ่งสังเกตเห็นว่าไม่มีเครื่องหมายจุลภาคหรือการทดสอบที่ล้มเหลวซึ่งไม่เคยทำงานก่อนที่จะพุชไปยังที่เก็บระยะไกล โชคดีที่มีเครื่องมือที่ช่วยขจัดความขัดแย้งนี้ ทำให้เวิร์กโฟลว์ของนักพัฒนาตรงไปตรงมายิ่งขึ้น และช่วยให้เรามีสมาธิกับสิ่งที่สำคัญจริงๆ ที่สุด ขอบคุณ git และ hooks ที่มีให้ เรามีระบบอัตโนมัติที่หลากหลาย ซึ่งเราสามารถกำหนดเวิร์กโฟลว์การพัฒนาของเราและทำให้ชีวิตของเราง่ายขึ้น

ข้อกำหนดหลักประการหนึ่งในการทำงานให้กับทีมหรือโครงการโอเพนซอร์สคือการใช้ระบบควบคุมเวอร์ชัน (VCS) Git คือระบบควบคุมเวอร์ชันโอเพ่นซอร์สแบบแจกจ่ายฟรีสำหรับการติดตามการเปลี่ยนแปลงซอร์สโค้ดระหว่างการพัฒนาซอฟต์แวร์ มันถูกสร้างขึ้นโดย Linus Torvalds ในปี 2548 เพื่อพัฒนาเคอร์เนล Linux ง่ายต่อการเรียนรู้และมีขนาดเล็กพร้อมประสิทธิภาพที่รวดเร็วดุจสายฟ้า

มีโอกาสสูงที่คุณจะใช้ Git อยู่แล้ว (เนื่องจากเป็นเครื่องมือ VCS ที่ได้รับความนิยมและนำมาใช้อย่างดีที่สุดในชุมชนการพัฒนา) และส่วนใหญ่แล้วคุณอาจมีความรู้เกี่ยวกับการจัดเตรียมและการคอมมิตโค้ดของคุณโดยการกดและดึง จากที่เก็บระยะไกล บทความนี้จะไม่กล่าวถึงพื้นฐานของเวิร์กโฟลว์ git แต่ส่วนใหญ่จะ เน้นที่ git hooks และวิธีใช้งาน เพื่อให้เกิดการทำงานร่วมกันในทีมของคุณได้ดียิ่งขึ้น เมื่อทีมเติบโตขึ้น การรักษาผู้ร่วมให้ข้อมูลให้อยู่ในแนวเดียวกันและรักษากฎเกณฑ์ต่างๆ เกี่ยวกับโค้ดจึงมีความสำคัญมากขึ้น

Git Hooks คืออะไร?

Git hooks เป็นสคริปต์ที่ทริกเกอร์เมื่อมีการดำเนินการหรือเหตุการณ์เฉพาะในที่เก็บ git การดำเนินการเหล่านี้เกี่ยวกับส่วนต่างๆ ของเวิร์กโฟลว์การควบคุมเวอร์ชัน เช่น การคอมมิตและการพุช Hooks มีประโยชน์อย่างยิ่งโดยทำให้งานอัตโนมัติบนเวิร์กโฟลว์ git ของคุณทำงาน ตัวอย่างเช่น พวกเขาสามารถช่วยเราตรวจสอบไวยากรณ์ของ codebase ของเราตามกฎเฉพาะบางอย่าง หรือทำการทดสอบบางอย่างก่อนที่จะทำการเปลี่ยนแปลงของเรา

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

วิธีการรับพวกเขาตั้ง?

Git hooks เป็นคุณสมบัติในตัว หมายความว่าเราสามารถเข้าถึงพวกมันและเริ่มใช้งานได้ตราบใดที่มีการเริ่มต้นที่เก็บ git มาดูรายละเอียดเพิ่มเติมว่าการพยายามตั้งค่านั้นหมายความว่าอย่างไร

ใช้เทอร์มินัลที่คุณชื่นชอบ สร้างที่เก็บ git ใหม่

 mkdir my-new-repository && cd my-new-repository git init ls -la

คุณจะสังเกตเห็นว่าเพิ่งสร้างไดเร็กทอรีที่ซ่อนอยู่ใหม่ โฟลเดอร์ .git นี้ใช้จาก git เพื่อจัดเก็บข้อมูลที่เกี่ยวข้องกับที่เก็บ เช่น แฮชควบคุมเวอร์ชัน ข้อมูลเกี่ยวกับการคอมมิต ที่อยู่ที่เก็บระยะไกล และอื่นๆ นี่เป็นโฟลเดอร์ที่ hooks ใช้งานได้จริงสำหรับ git .git/hooks คุณสามารถค้นหาสคริปต์ตัวอย่างที่เติมไว้ล่วงหน้าบางส่วนที่สร้างขึ้นโดยอัตโนมัติในระหว่างการเริ่มต้น อันที่จริงแล้วสคริปต์เหล่านี้จะถูกทริกเกอร์หลังจากดำเนินการบางอย่าง

 ls .git/hooks

ตัวอย่างบางส่วนที่คุณสามารถหาได้คือ:

  • pre-commit.sample : เรียกใช้ก่อนทำการคอมมิต
  • commit-msg.sample : แก้ไขไฟล์ข้อความในตำแหน่ง
  • post-receive.sample : เรียกใช้หลังจากอัปเดตที่เก็บระยะไกลแล้ว

ภายใต้ประทุน

ตอนนี้เรารู้แล้วว่าสามารถหา hooks ได้จากที่ใด ให้ย้อนกลับไปเพื่อทำความเข้าใจว่ามันทำงานอย่างไร

Git hooks เป็นแบบอิงตามเหตุการณ์ ตราบใดที่เรารันคำสั่ง git ในขั้นตอนการพัฒนา git จะตรวจสอบโฟลเดอร์ hooks เพื่อดูว่ามีสคริปต์ที่เกี่ยวข้องให้รันหรือไม่ สคริปต์เหล่านี้บางส่วนจะทำงานก่อนหรือหลังการดำเนินการขั้นตอนการพัฒนาเหล่านี้

ตัวอย่างที่ดีสำหรับเราในการดำเนินการและเข้าใจโฟลว์ที่ hook ถูกทริกเกอร์อย่างเจาะจงมากขึ้นคือเวิร์กโฟลว์ที่ยอมรับซึ่งเป็นกรณีการใช้งานที่ค่อนข้างคุ้นเคย

เมื่อใดก็ตามที่เราทำการเปลี่ยนแปลงใดๆ กับ codebase ตะขอที่เกี่ยวข้องเหล่านี้บางส่วนจะถูกทริกเกอร์ในลำดับต่อไปนี้:

  1. pre-commit : ตรวจสอบสแนปชอตที่กำลังจะคอมมิต และตรวจสอบสิ่งที่จะคอมมิต
  2. prepare-commit-msg : ให้คุณแก้ไขข้อความเริ่มต้นก่อนที่ผู้เขียนคอมมิตจะเห็น
  3. commit-msg : ตั้งค่าข้อความยืนยันไปยังเทมเพลต
  4. post-commit : เรียกใช้การดำเนินการหลังจากที่คอมมิตเสร็จสิ้น และส่งการแจ้งเตือนเป็นต้น
Hooks ดำเนินการระหว่างกระบวนการสร้างคอมมิต
Hooks ดำเนินการระหว่างกระบวนการสร้างคอมมิต (เครดิตรูปภาพ: Atlassian Bitbucket) (ตัวอย่างขนาดใหญ่)

ในที่เก็บข้อมูลด้านบน ตอนนี้ ให้ลองเพิ่มสคริปต์ก่อนและหลังการคอมมิตแบบกำหนดเองเพื่อให้เห็นภาพว่า git hooks ทำงานจริงอย่างไร

 nano .git/hooks/pre-commit

เพิ่มข้อมูลโค้ดต่อไปนี้:

 #!/bin/sh echo Changes are about to be committed

ตรวจสอบให้แน่ใจว่าสคริปต์ของเราสามารถดำเนินการได้:

 chmod +x .git/hooks/pre-commit

ทำซ้ำขั้นตอนข้างต้นสำหรับสคริปต์ post-commit :

 nano .git/hooks/post-commit
 #!/bin/sh echo Changes have been committed
 chmod +x .git/hooks/post-commit

ตอนนี้ เราสามารถเพิ่มไฟล์ใหม่ nano index.html ด้วยข้อมูลโค้ด HTML ขนาดเล็กเพื่อการสาธิตเท่านั้น (ไม่จำเป็นต้องให้โปรแกรมตรวจสอบ HTML ทราบเกี่ยวกับเรื่องนี้)

 <h1>Hello world from our new repository!</h1>

เราจะเพิ่มการเปลี่ยนแปลงใน codebase ของเราผ่านการ staging แล้วทำสิ่งนี้:

 git add . git commit

หลังจากประมวลผลเสร็จเรียบร้อยแล้ว เราจะเห็นผลลัพธ์ต่อไปนี้ของสคริปต์ที่เพิ่มไว้ด้านบนสองตัวต่อไปนี้:

 Changes are about to be committed Changes have been committed

ตามที่คาดไว้ git ทริกเกอร์ hooks ในโฟลว์การส่ง สคริปต์ pre-commit และ post-commit ที่เพิ่มเข้ามากำลังทำงานและจะดำเนินการในลำดับที่ถูกต้อง (ตามลำดับที่เรากล่าวถึงก่อนหน้านี้)

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

ในตัวอย่างข้างต้น เราเลือกที่จะเขียนสคริปต์ทั้งสองนี้ในรูปแบบ bash แต่ความจริงก็คือ git รองรับ hooks ที่สามารถเขียนในภาษาสคริปต์ใดก็ได้ที่เราต้องการ Ruby, Python หรือ JavaScript เป็นทางเลือกที่ดี ตราบใดที่เราตั้งค่า shebang ที่ถูกต้องที่บรรทัดแรกของสคริปต์สั่งการของเรา

ตัวอย่างเช่น เราสามารถเขียน hook pre-commit ใหม่เป็นสคริปต์ Node.js ดังนี้:

 #!/usr/bin/env node console.log("Changes are about to be commited")

Hooks ในพื้นที่และระยะไกล

ตะขอถูกแยกระหว่างโลคัลและรีโมต (หรือไคลเอนต์และเซิร์ฟเวอร์) ในขณะที่ hooks โลคัลรันก่อนหรือหลังการดำเนินการเฉพาะบนที่เก็บโลคัล hooks ระยะไกลจะทำงานก่อนหรือหลังพุชไปยังเซิร์ฟเวอร์ ไม่สามารถใช้นโยบายท้องถิ่นในการบังคับใช้นโยบายได้เนื่องจากลักษณะของนโยบายช่วยให้นักพัฒนาแก้ไขได้อย่างง่ายดาย ส่วนใหญ่จะใช้สำหรับยึดติดกับหลักเกณฑ์เฉพาะบางอย่างที่เราต้องการนำไปใช้ภายในทีม ในกรณีที่เราต้องการเข้มงวดมากขึ้นและบังคับใช้นโยบายบางอย่างสำหรับที่เก็บของเรา เราอยู่ใน Remote hooks

ตะขอท้องถิ่น

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypatch
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push

ตะขอระยะไกล

  • pre-receive
  • update
  • post-receive

ตะขอแบ่งปัน

Git hooks ทั้งหมดเกี่ยวกับการแบ่งปันภายในทีม นี่คือเหตุผลหลักที่สิ่งเหล่านี้มีอยู่: ส่งเสริมการทำงานร่วมกันในทีมที่ดีขึ้น ทำให้กระบวนการที่เป็นอันตรายเป็นไปโดยอัตโนมัติ และปล่อยให้เรามุ่งความสนใจไปที่ส่วนสำคัญของ Codebase เท่านั้น

ตามที่ระบุไว้ก่อนหน้านี้ .git/hooks เป็นโฟลเดอร์ที่โฮสต์ hooks ที่กำหนดเองของเรา แต่สิ่งนี้ไม่มีประโยชน์จริง ๆ เมื่อเราต้องการแชร์สคริปต์เหล่านี้ภายในทีม เนื่องจาก git ไม่ได้ติดตามโฟลเดอร์นี้

วิธีที่ดีในการแก้ปัญหานี้คือการเพิ่ม hooks ที่กำหนดเองทั้งหมดของเราลงในโฟลเดอร์แยกต่างหากภายในที่เก็บของเรา ตัวอย่างเช่น เราสามารถเพิ่มโฟลเดอร์ .githooks และบันทึกสคริปต์สั่งการได้ที่นั่น จากนั้นในการเริ่มต้นโครงการ เราสามารถคัดลอกหรือเชื่อมโยงสคริปต์เหล่านี้อย่างชัดเจนไปยังโฟลเดอร์เดิมเพื่อเก็บ hooks .git/hooks ของเราไว้

 find .git/hooks -type l -exec rm {} \\; find .githooks -type f -exec ln -sf ../../{} .git/hooks/ \\;

หรือหากคุณใช้ git เวอร์ชันล่าสุด (พูดถึง 2.9 ขึ้นไป) เราสามารถกำหนดค่าพาธ git hooks ไปยังโฟลเดอร์ที่กำหนดเองได้โดยตรง:

 git config core.hooksPath .githooks

Git Hooks ทำได้ง่าย (กรณีการใช้งาน JavaScript Codebase)

มีเครื่องมือที่ช่วยให้เรารวม git hooks เข้ากับความต้องการของ codebase ของเราได้มากขึ้น โดยเฉพาะสำหรับฐานรหัส JavaScript มี Husky ที่เราสามารถปรับแต่งการกระทำบนเหตุการณ์ git ผ่านการกำหนดค่าได้อย่างง่ายดาย

ตัวอย่างเช่น เราสามารถ lint โค้ดของเราหรือรันการทดสอบบางอย่างในเหตุการณ์ pre-commit และดำเนินการคอมมิตได้โดยพิจารณาจากว่าการ linting การทดสอบหรือทั้งสองอย่างประสบความสำเร็จหรือไม่

สามารถทำได้โดยขยายการกำหนดค่า package.json ง่ายๆ ดังนี้:

 { "scripts": { "test": "echo Running tests" }, "devDependencies": { "eslint": "5.16.0", }, "husky": { "hooks": { "pre-commit": "eslint . && npm test", } } }

บทสรุป

ในบทความนี้ เราพบว่าการดำเนินการต่างๆ ที่เกิดขึ้นกับที่เก็บ git สามารถเรียกสคริปต์ที่กำหนดเองให้ทำงาน สคริปต์เหล่านั้นสามารถอยู่ภายใต้การควบคุมของนักพัฒนาในพื้นที่หรือจัดการจากส่วนกลางมากขึ้นสำหรับทีมหรือโครงการบนรีโมต นอกจากนี้เรายังได้เรียนรู้ว่าสคริปต์มักเขียนในเชลล์สคริปต์ เช่น bash แต่จริงๆ แล้วสามารถใช้ภาษาสคริปต์ได้เกือบทุกภาษา แม้แต่ JavaScript

Git hook สามารถเป็นส่วนที่ทรงพลังมากของเวิร์กโฟลว์ที่ออกแบบมาอย่างดี และผมขอแนะนำให้คุณลองดูและดูว่าคุณสามารถทำอะไรกับโปรเจ็กต์ของคุณเองได้บ้าง