複数のGoツールをひとつのhomebrewリポジトリで配布する
Goで書かれたCLIツールを homebrew で配布するために goreleaser@goreleaser-action がよく使われている。よくある解説では、ひとつのCLIに対してひとつの homebrew リポジトリを作成して Formula を配布するかたちになっていることが多いが、複数の CLI tool を配布するとなったとき、毎回ツール自体のリポジトリとセットで homebrew 用のリポジトリを作成するのはちょっと面倒くさい。
aws や hashicorp がひとつの homebrew用リポジトリにある Formula ディレクトリに複数ツールの配布用データセットを置いているのを見つけたので、構成をマネして goreleaser の設定を書いてみた。
なお、githubの公開リポジトリで野良配布する前提で、goreleaserで単発配布まではできているとします。
homebrew用リポジトリ
取り急ぎ、Formula を置くリポジトリをつくる。たぶん任意の名前で良いが、 aws や hashicorp にならって homebrew-tap
とする。わかりやすい。
私のを参考までに:bayashi/homebrew-tap
GITHUB Personal access tokens
まず、複数CLIをまとめることには関係ないが、homebrew向けのワークフロー設定に必要なので、githubアカウントで Personal access token を発行しておく。repo権限があればOK。これはリポジトリごとに発行してもいいし、ひとつのトークンを使いまわしても良いと思う。なぜなら同じリポジトリを変更するための token だから(ひとつひとつのツールをセキュアにするなら個別発行の方が望ましいとは思いますが)。
発行した token は、CLI ツールのリポジトリの Actions secrets
メニューで HOMEBREW_TAP_GITHUB_TOKEN
という名前で secrets に登録しておく。この名前は任意です。後述する goreleaser の設定ファイル .yaml の中で指定します。
goreleaser
releaser.yaml
まず、.github/workflows/releaser.yaml
に上で発行した HOMEBREW_TAP_GITHUB_TOKEN
の指定を追加しておきます(最終行)。
name: releaser
on:
push:
tags:
- v*
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: 1.19
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
workflow 自体のファイル名は任意です。
.goreleaser.yaml
つづいて、プロジェクト直下に配置する .goreleaser.yaml には、brew 向けに以下のような項目を書いておきます。irir
というツールの例です。
brews:
- tap:
owner: bayashi
name: homebrew-tap
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
folder: Formula
homepage: https://github.com/bayashi/irir
description: A filter to add colors for text lines generically from a YAML configuration file easily
test: |
system "#{bin}/irir", '--version'
抽象化した解説を書いておくと、
brews:
- tap:
owner: {あなたのgithubアカウント}
name: {homebrew用リポジトリ名}
token: "{{ .Env.CLIツールのリポジトリでsecretsに登録したtokenの名前 }}"
folder: {homebrew用リポジトリでのディレクトリ名。特に変更する必要もないので Formula のまま}
homepage: {CLIツールを紹介するページURL}
description: {CLIツールの紹介文}
test: |
system "#{bin}/{CLIツールコマンド}", '{必要ならオプション}' # テスト発行するコマンド
brews.tap.name
のところを {homebrew用リポジトリ名}
として、今回は homebrew-tap
と指定している。HOMEBREW_TAP_GITHUB_TOKEN
は上で発行したもの。
Workflow permissions
この設定は 複数CLI配布するためというわけではないが、goreleaser を github で動かすために必要な設定。
CLIのリポジトリの settings タブにある、Actions.General のメニューの中に Workflow permissions
というのがあるので、これを read and write permissions
に変更して保存する。
これをしておかないと、goreleaser のワークフローが 403 でこける。
homebrew 配布コマンド
goreleaser が無事走り切ると、homebrew-tap/Formula 以下に {ツール名}.rb
が生成されていると思います。
配布用のコマンドは以下のようになります。
brew tap {あなたのgithubアカウント}/tap
brew install {あなたのgithubアカウント}/tap/{ツール名}
例えば、bayashi の irir というツールの場合、
brew tap bayashi/tap
brew install bayashi/tap/irir
となります。
まとめ
リポジトリを毎回作る手間が省けてハッピー