Diary of a Perpetual Student

Perpetual Student: A person who remains at university far beyond the normal period

GoReleaser を使って Homebrew でインストール可能な CLI ツールを公開する時にも GitHub Apps トークンが使える

3行

  • GoReleaser を使うと、作ったツールを Homebrew でインストールするための formula を書き出してくれて便利
  • GitHub Actions でこれを行う際、GitHub の PAT が必要とされているが、代わりに GitHub Apps トークンも使える
  • PAT を利用する方法と比較して、GitHub Apps トークンを使うと有効期限での強制的なローテーション業務が発生せず運用が楽になる

前置き

GoReleaser を使っていますか?設定ファイルを用意すると、ソースコードを様々な環境に向けてクロスコンパイルした上で、GitHub などの Release に載せられるツールです。

GitHub Actions と合わせて使うことでリリース作業を自動化でき、バージョンタグを打つだけでバイナリや checksum ファイルを生成して Release に載せることができます。

この GoReleaser には便利な機能があり、設定ファイル .goreleaser.yaml に以下のように追記することで、指定したリポジトリに Homebrew の formula ファイルを push することができます。簡単に自分の作った CLI ツールを Homebrew でインストール可能にできるわけです。

brews:
  - repository:
      owner: Arthur1
      name: homebrew-tap
      token: "{{ .Env.TAP_GITHUB_TOKEN }}"

※2023-06-13 にリリースされた v1.19.0 より、旧来 brews: - tap: と書いていた記法が deprecated になっています。cf.) https://goreleaser.com/deprecations/#brewstap

ここまでの内容についてのより詳しい説明は他の記事に譲ります:

zenn.dev

本題

さて、GoReleaser を GitHub Actions で動かす際に必要な、tap リポジトリへの push を行うための token をどのように用意していますか?多くの解説記事では GitHub の Personal Access Token (PAT) を用いる方法が紹介されています。また、GoReleaser の公式ドキュメントの例でも PAT を用いているような表現があります。

goreleaser.com

しかし、世の中には運用上の面でより優れている代わりの方法があります。それは GitHub Apps トークンを用いる方法です。GitHub App の秘密鍵から temporary なトークンを都度生成して利用します。PAT(正確には Fine-grained PAT)と異なり有効期限がないため定期的なローテーションが must にならないこと、一時トークンが流出しても秘密鍵さえ流出しなければ影響範囲を絞れること、といったメリットがあります。

PAT の代わりに GitHub Apps トークンを GitHub Apps で運用する方法について知りたい方は以下の記事を読むと良いでしょう。少々混み入ったところまで踏み込んでいますが、丁寧に説明されています。

zenn.dev

GoReleaser の Homebrew 機能のために GitHub Apps トークンを用いるための設定ポイントは以下の 2つです:

  • App の permission を設定するとき、Repository permissions の 「Contents」を 「Access: Read and Write」にセットする
  • App をインストールするとき、Only select repositories で、Homebrew tap のためのリポジトリを指定する *1

というわけで、GitHub Actions で GoReleaser を動かし、Homebrew formula を自動で書き出すときにも GitHub Apps が使えるというお話でした。

*1:All repositories でも実現可能ですが、App が持つ権限は最低限に絞りたいですよね?