• 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) แล้วให้สิทธิ์ ContentWrite กับ 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 อื่นเพิ่มอีกหรือไม่ แต่ก็พอใจกับการที่อย่างน้อยมีความเป็นไปได้นี้เปิดอยู่

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น