Security Index

セキュリティやソフトウェアについてのあれこれ

GoReleaserとGithub Actionsを使ってGoのCLIツールをHomebrew installできるようにする

go-cve-search 作ってみた - TDD, Circleci, README Badge, Terminal Gif, Cliツール開発の話の続きでGoReleaserを使ってhomebrew installでGoのCLIツールを簡単にインストールできるようにしました。

brew tapでs-index/go-cve-searchを登録して、brew installするとインストールできるようになります。

$ brew tap s-index/go-cve-search
$ brew install s-index/go-cve-search/go-cve-search

brew tapというものを今まで知らなかったのですが公式以外のリポジトリを登録してそこからインストールできるようにするもののようです。

brew tapとは - Qiita

作成したレポジトリはこちら。 GitHub - s-index/go-cve-search: lightweight CVE search

f:id:security_index:20200823104156j:plain

公式サイトは以下になります。

Homebrew - GoReleaser

困ったときやより細かい設定をしたくなった時に役立ちます。

設定

完成したGoReleaserのyamlファイルとそれを実行するGithub Actionsの設定は以下のようになります。

GoReleaserの設定

.goreleaser.yml

# プロジェクト名に変更
project_name: go-cve-search
env:
  - GO111MODULE=on
before:
  hooks:
    - go mod tidy
# homebrewで必要な設定
brews:
  - tap:
      # Github usernameに変更
      owner: s-index
      # homebrew-<コマンド名>
      name: homebrew-go-cve-search
    folder: Formula
    # homepage
    homepage: https://github.com/s-index/go-cve-search
    # コマンドの説明
    description: lightweight tool to search CVE (Common Vulnerabilities and Exposures)
    test: |
      system "#{bin}/goreleaser -v"
# binary提供用の設定
builds:
  - main: .
    binary: go-cve-search
    goos:
      - windows
      - darwin
      - linux
    ldflags:
      - -s -w
      - -X main.Version={{.Version}}
      - -X main.Revision={{.ShortCommit}}
    env:
      - CGO_ENABLED=0
# binary提供用の設定
archives:
  - name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
    replacements:
      darwin: macOS
      linux: linux
      windows: windows
      386: 32-bit
      amd64: 64-bit
    format_overrides:
      - goos: windows
        format: zip
release:
  prerelease: auto

ownernameなどの部分を自分の環境に変更するだけで大丈夫です。

# binary提供用の設定の部分は前回の記事や以下の記事などが参考になります。

Go で書いた CLI ツールのリリースは GoReleaser と GitHub Actions で個人的には決まり | tellme.tokyo

Github Actionsの設定

.github/workflows/release.yml

name: release
on:
  push:
    tags:
    - "v[0-9]+.[0-9]+.[0-9]+"
jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1
        with:
          fetch-depth: 1
      - name: Setup Go
        uses: actions/setup-go@v1
        with:
          go-version: 1.13.3
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v1
        with:
          version: latest
          args: release --rm-dist
        env:
          # Homebrewでは他のレポジトリへのアクセスが必要なので```secrets.GITHUB_TOKEN```ではうまくいかないのでTOKENを作成、設定が必要
          GITHUB_TOKEN: ${{ secrets.HOMEBREW_TOKEN }}

この設定をコピペするだけで基本的に大丈夫ですが、最後のGITHUB_TOKENだけ注意が必要です。

Homebrew installをしない場合は GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}と書くだけでよかったのですが、今回はGithub Actionsが動作しているリポジトリ以外のリポジトリ(今回だとs-index/homebrew-go-cve-searchs-index/homebrew-go-cve-search)にも変更を与える必要があるため、別途TOKENを作成、設定する必要があります。

Github Actions用のTOKEN設定

https://github.com/settings/tokensでPersonal access tokensを作成します。

f:id:security_index:20200823145807p:plain

scopesはrepoにチェックを入れます。

f:id:security_index:20200823160502p:plain

生成するとaccess tokenが生成されますのでコピーしておきます。

この値をあとで利用します。

f:id:security_index:20200823160725p:plain

次にリポジトリのSettingsのSecretsでSecretsの生成を行います。

f:id:security_index:20200823161123p:plain

New secretをクリックすると以下のようなページになります。

Nameには今回使う用途に合わせて名前をつけます。今回、私の場合ではHOMEBREW_TOKENとしました。

(GITHUBから始まる名前は使えませんので注意)

Valueには先ほど生成し、コピーしておいたaccess tokenの値を入力します。

f:id:security_index:20200823161745p:plain

Nameで設定した値を.github/workflows/release.ymlGITHUB_TOKEN: ${{ secrets.HOMEBREW_TOKEN }}のように設定します。

Homebrew用のリポジトリ作成

GoReleaserを実行するとHomebrewのFormulaというbrew installで実際に実行されるRubyのスクリプトが作成され、それをHomebrew用のリポジトリにコミットする、という処理が行われます。

そのため、Homebrew用のリポジトリを事前に作成しておく必要があります。

リポジトリ名は.goreleaser.ymlnemeと同じものにしましょう。

GitHub - s-index/homebrew-go-cve-search

tagをつけてリリースする

設定は上記で完了です。

あとは、tagをつけてリリースするだけでGithub Actionsがバイナリの提供やHomebrew Formulaを作成してくれます。

Actionsをみると正常に動作したか、またはエラーが発生したのか確認できます。

f:id:security_index:20200823162531p:plain

Github Tokenの設定がうまくいかなった時には以下のようなエラーが出ました。

.github/workflows/release.ymlGITHUB_TOKENの設定をGITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}のように自動で生成されるGITHUB_TOKEN secretでは他のリポジトリへのアクセス権限がないためにエラーとなります。

また、secretsの名前が正しくない場合にも当然ですがエラーになります。

f:id:security_index:20200823162832p:plain

上手くできた場合にはこのようにgoreleaserbotがHomebrew Formulaを生成してくれます。

f:id:security_index:20200823163538p:plain

binary提供用の設定もしている場合にはリリースページでWindows/macOS/Linux用の実行ファイルも自動で提供されます。

f:id:security_index:20200823163850p:plain

最後に

GoReleaserとGithub Actionsを使えばとても簡単に各OS毎の実行ファイル、Homebrew installの設定が行えます。

一度設定してしまえばあとはリリースする度に最新のものが自動で提供されるようになるのでとてもおすすめです。

改訂2版 みんなのGo言語

Goならわかるシステムプログラミング

Go言語でつくるインタプリタ


Twitter (@security_index)