- Homebrew เป็นตัวจัดการแพ็กเกจที่ช่วยให้ติดตั้งและจัดการ เครื่องมือ CLI บน macOS ได้ง่าย ทำให้นักพัฒนาสามารถจัดสภาพแวดล้อมของระบบได้อย่างมีประสิทธิภาพด้วยเครื่องมือที่ใช้บ่อย
- คู่มือนี้อธิบายกระบวนการเผยแพร่สคริปต์ CLI ส่วนตัวด้วย Homebrew และแสดงวิธีทำให้การดูแลรักษาง่ายขึ้นผ่าน การเชื่อมต่อกับ GitHub และเวิร์กโฟลว์อัตโนมัติ
- กระบวนการเผยแพร่จะเป็นลำดับ สร้าง CLI → GitHub release → สร้าง Tap → เขียนและอัปเดต Formula และสุดท้ายสามารถติดตั้งได้ด้วยคำสั่ง
brew tap และ brew install เท่านั้น
- หากเข้าใจ ระบบคำศัพท์ และ แนวทางปฏิบัติที่ดี ของ Homebrew ก็จะสามารถเผยแพร่ได้อย่างเสถียรพร้อมเสริมความสามารถในการทำซ้ำและความปลอดภัยของซัพพลายเชน
- สามารถทำให้เป็นอัตโนมัติด้วยเวิร์กโฟลว์ GitHub Actions ได้ และเมื่อตั้งค่าไว้ครั้งหนึ่งแล้ว การเผยแพร่ CLI ตัวอื่นในภายหลังก็จะ ง่ายมาก
พื้นหลังและแรงจูงใจ
- Homebrew เป็น ตัวจัดการแพ็กเกจที่นิยมใช้เมื่อติดตั้งเครื่องมือ CLI และมีนักพัฒนาจำนวนมากใช้งาน
- แต่หลายคนมักเผยแพร่ CLI ที่สร้างเองผ่าน npm หรือ RubyGem ทำให้แนวทางการเผยแพร่ผ่าน Homebrew อาจรู้สึกไม่คุ้นขั้นตอน
- เนื่องจากคลัง core อย่างเป็นทางการของ Homebrew มีนโยบายไม่ค่อยรับเครื่องมือทำเองเข้าไป ทีม Homebrew จึงทำให้ นักพัฒนาทั่วไปต้องเผยแพร่ผ่าน tap และ formula แยกต่างหาก
- คู่มือนี้อธิบายโดยอิงจาก ประสบการณ์การเผยแพร่ CLI แบบง่ายที่เขียนด้วย Ruby
คำอธิบายคำศัพท์
- Homebrew ใช้ คำศัพท์เฉพาะ ที่สะท้อนธีมการต้มเบียร์ ดังนั้นหากเข้าใจก็จะมองโครงสร้างระบบได้ง่ายขึ้น
- Formula คือไฟล์ นิยามแพ็กเกจ ที่มีคำสั่งสำหรับติดตั้งซอร์สโค้ดหรือไบนารี
- Tap คือ Git repository ของ Formula หลายตัว ใช้จัดการแพ็กเกจแบบกำหนดเองตามผู้ใช้หรือองค์กร
- Cask คือแมนิเฟสต์สำหรับติดตั้ง แอป GUI หรือไบนารีขนาดใหญ่ คล้าย Formula แต่ใช้กับไฟล์ที่สร้างเสร็จแล้ว
- Bottle คือรูปแบบที่คัดลอก แพ็กเกจไบนารีที่ build ไว้ล่วงหน้า แทนการ build จากซอร์ส ช่วยให้ติดตั้งได้เร็วขึ้น
- Cellar คือ ไดเรกทอรี ที่เก็บ Formula ที่ติดตั้งแล้ว เช่นพาธ
/opt/homebrew/Cellar
- Keg คือ ไดเรกทอรีของอินสแตนซ์การติดตั้ง ของ Formula เฉพาะตัวหนึ่ง ซึ่งจะถูกจัดวางตามเวอร์ชันภายใน Cellar
ภาพรวม
- เนื่องจากคลัง core ของ Homebrew ไม่รับคอนเทนต์ที่เฉพาะทางมากหรือเป็นการส่งเข้ามาแบบส่วนบุคคล ผู้ใช้จึงต้อง สร้าง tap repository แยกต่างหาก เพื่อเผยแพร่ CLI
- 1. สร้าง CLI แล้วอัปขึ้น GitHub และทำ tag release
- 2. สร้าง Tap ด้วย
brew tap-new แล้ว push ขึ้น GitHub
- 3. สร้าง Formula ด้วย
brew create (รวม URL ของ tarball และ SHA256)
- 4. ทุกครั้งที่ออกเวอร์ชันใหม่ ให้อัปเดต Formula เพื่อให้ผู้ใช้ติดตั้งได้ง่ายด้วยคำสั่ง
brew install
- เมื่อเผยแพร่เสร็จ ผู้ใช้จะติดตั้ง CLI ได้ด้วยสองคำสั่ง:
brew tap your_github_handle/tap และ brew install your_cool_cli
- คู่มือนี้จะข้ามขั้นตอนการพัฒนา CLI และเน้นที่การสร้าง tap, การสร้าง Formula และกระบวนการอัปเดต
- ตัวอย่างที่ใช้คือ CLI ชื่อ
imsg ซึ่งสร้าง เว็บอาร์ไคฟ์แบบโต้ตอบได้ จากฐานข้อมูล iMessage
การสร้าง tap
- ให้ทำตาม คู่มือการสร้าง tap ของ Homebrew โดยแทนที่ด้วยชื่อผู้ใช้หรือชื่อองค์กรบน GitHub ของคุณ
- เพื่อรวบรวมเครื่องมือ CLI ทั้งหมดไว้ใน tap เดียวกันในอนาคต จึงแนะนำชื่อ
homebrew-tap โดยคำนำหน้า homebrew จะถูกจัดการเป็นพิเศษใน CLI และคำนำหน้า tap ก็เป็นธรรมเนียมที่ใช้กัน
- รันคำสั่งสร้าง tap:
brew tap-new searlsco/homebrew-tap
- คำสั่งนี้จะสร้าง scaffold ไว้ที่
/opt/homebrew/Library/Taps/searlsco/homebrew-tap
- จากนั้นสร้าง repository ที่สอดคล้องกันบน GitHub และ push เนื้อหาที่สร้างขึ้น:
cd /opt/homebrew/Library/Taps/searlsco/homebrew-tap, git remote add origin git@github.com:searlsco/homebrew-tap.git, git push -u origin main
- เมื่อเป็นเจ้าของ tap แล้ว ผู้ใช้อื่นสามารถ clone repository นี้ด้วยคำสั่ง
brew tap searlsco/tap เพื่อนำไปวางใน /opt/homebrew/Library/Taps ได้
- ช่วงแรกอาจยังไม่มีอะไรที่มีประโยชน์อยู่ภายใน แต่ก็สามารถยืนยันการทำงานพื้นฐานได้
การสร้าง Formula
- แม้ Homebrew จะอ้างอิง GitHub repository ได้โดยตรง แต่แนะนำให้ใช้ tarball แบบมีเวอร์ชัน และ checksum เพื่อเพิ่มความสามารถในการทำซ้ำและความปลอดภัยของซอฟต์แวร์โอเพนซอร์สในซัพพลายเชน
- คำสั่งสร้าง Formula:
brew create https://github.com/searlsco/imsg/archive/refs/tags/v0.0.5.tar.gz --tap searlsco/homebrew-tap --set-name imsg --ruby
- แฟล็ก
--tap ใช้ระบุ tap แบบกำหนดเอง และวาง Formula ไว้ที่ /opt/homebrew/Library/Taps/searlsco/homebrew-tap/Formula
--set-name imsg ใช้ตั้งชื่อ Formula อย่างชัดเจน ควรเลือกให้ไม่ซ้ำเพื่อหลีกเลี่ยงการชนชื่อ (เช่น ระวังชนกับ TLDR หรือ standard CLI ที่มีอยู่แล้ว)
--ruby คือ template preset สำหรับ Ruby CLI ซึ่งเป็นหนึ่งในหลายตัวเลือกที่ช่วยให้การปรับแต่งง่ายขึ้น
- Formula ที่สร้างขึ้นอาจยังใช้งานไม่ได้ในตอนแรก จึงสามารถใช้ LLM ช่วยแก้ไขได้: รัน
brew install --verbose imsg แล้วนำข้อผิดพลาดไปใส่ใน ChatGPT จากนั้นอัปเดต Formula ซ้ำไปเรื่อย ๆ
- ไฟล์สุดท้าย Formula/imsg.rb สามารถคัดลอกไปใช้เป็นจุดเริ่มต้นสำหรับการเผยแพร่ Ruby CLI ได้
- การเผยแพร่ผ่าน Homebrew แทนตัวจัดการแพ็กเกจเฉพาะภาษา ช่วยให้แม้จะเปลี่ยนภาษา implementation ในภายหลัง ผู้ใช้ก็ยังอัปเกรดได้อย่างราบรื่น
จุดสำคัญของ Formula
- Formula ทุกตัวจะเขียนด้วย Ruby เพราะเครื่องมือพัฒนาที่เคยได้รับความนิยมก่อนยุค JavaScript หรือ AI นั้นจำนวนมากสร้างอยู่บน Ruby
- สามารถใช้เมธอด
head เพื่อระบุ Git repository ได้ แต่ผลลัพธ์จริงยังไม่แน่ชัด
- การเพิ่ม
livecheck มีคุณค่าเพราะช่วยให้อัปเดตเวอร์ชันของ Formula ได้ง่ายขึ้น
- การทดสอบการรันไบนารีสามารถทำอย่างง่ายได้ด้วยการตรวจสอบผลลัพธ์ของ help output จึงไม่ต้องกังวลกับคอมเมนต์ที่ถูกสร้างมาให้
- ใช้คำสั่ง
brew style searlsco/tap เพื่อตรวจสอบข้อผิดพลาดด้านสไตล์
- ค่าเริ่มต้น
uses_from_macos "ruby" ของ template --ruby จะใช้เวอร์ชัน 2.6.10 (ออกก่อนช่วง COVID และหมดอายุการสนับสนุนมา 3 ปีแล้ว) ดังนั้นจึงแนะนำให้พึ่งพา Ruby Formula รุ่นใหม่ด้วย depends_on "ruby@3"
- เมื่อพอใจกับ Formula แล้ว ก็เผยแพร่จริงได้ด้วย
git push และผู้ใช้จะติดตั้งได้ด้วย brew tap searlsco/tap และ brew install imsg
การอัปเดต Formula สำหรับแต่ละ CLI release
- ค่า
url และ hash sha256 ด้านบนของ Formula ต้องอัปเดตด้วยตนเองทุก release ซึ่งยุ่งยาก และผู้เขียนยังชี้ว่าการ push tag หรือสร้าง GitHub release เองก็ชวนเหนื่อยเช่นกัน
- สามารถใช้คำสั่ง
bump-formula-pr ของ Homebrew หรือ GitHub Action เพื่อสร้าง PR ได้ แต่ขั้นตอน fork และ PR นั้นซับซ้อนเกินจำเป็น
- หากคุณเป็นเจ้าของ tap วิธีที่ตรงไปตรงมาและเหมาะกว่าคือ commit เข้า branch main โดยตรง
- เพื่อหลีกเลี่ยงเรื่องนี้ จึงแนะนำให้เพิ่ม GitHub workflow ใน repository ของ Formula เพื่ออัปเดต tap อัตโนมัติเมื่อมี release
- สามารถคัดลอก workflow example ไปใช้ได้
- ต้องตั้งค่าบางอย่าง: สร้าง GitHub personal access token (PAT) แล้วให้สิทธิ์
Content → Write กับ repository homebrew-tap จากนั้นเก็บไว้ใน Secrets ของ repository Formula โดยใช้ชื่อ HOMEBREW_TAP_TOKEN
- ระบุ tap และ Formula ผ่าน environment variables (เช่น บรรทัด 13-15)
- แนะนำให้อัปเดตค่าบัญชีบอตของ GitHub:
GH_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com, GH_NAME: github-actions[bot]
- หลังสร้าง release แล้ว เมื่อรัน
git push --tags จะมีการอัปเดตอัตโนมัติภายในไม่กี่วินาที และผู้ใช้จะอัปเกรดได้ด้วย brew update และ brew upgrade imsg
ส่วนที่ดีที่สุด
- แม้กระบวนการนี้จะซับซ้อน แต่เมื่อทำการตั้งค่า tap และมีตัวอย่าง Formula หนึ่งตัวเสร็จแล้ว การเผยแพร่ CLI เพิ่มเติมจะ แทบเป็นเรื่องเล็กน้อย
- สามารถเผยแพร่ Formula ใหม่ได้ภายในไม่กี่นาที จึงสะดวกมาก
- แม้กระบวนการอย่างเป็นทางการของ Homebrew จะค่อนข้างซับซ้อน แต่ระบบอัตโนมัติช่วยให้ใช้งานสะดวกขึ้น
- ลดความยุ่งยากระหว่างการ release และการเผยแพร่ของแต่ละเครื่องมือ และยังรองรับการขยายไปสู่ CLI ที่เขียนด้วยภาษาหลากหลายได้
- ผู้เขียนเองก็ยังไม่แน่ใจว่าจะเผยแพร่ Formula อื่นเพิ่มอีกหรือไม่ แต่ก็พอใจกับการที่อย่างน้อยมีความเป็นไปได้นี้เปิดอยู่
ยังไม่มีความคิดเห็น