Help us understand the problem. What is going on with this article?

GoReleaser覚え書き

はじめに

GoReleaserを使い始めて、執筆時点で1ヶ月余りが過ぎた。
この間に、GoReleaserとGitHub Actionsを使って3つほどGolangのCLIのリリースを自動化した。
到底、使い倒したといえるほどのものではないが、得られた知見などをまとめておく。

随時、加筆更新予定。

※元ネタは個人のメモサイトに書き溜めていたもの

GoReleaserとは

https://goreleaser.com/intro/

Goプロジェクトのリリース自動化ツール。

主な機能:

  • バイナリのクロスコンパイル
  • GitHub / GitLabへの公開
    • 公開済みのtagを参照してreleaseを作り、バイナリをアップロードする
    • Release Note生成 ... commit logからChange Logを生成

CIツールから使われることを念頭に作られているようだが、ローカルにインストールして実行することもできる。

参考:

Installation

https://goreleaser.com/install/

macOS:

brew install goreleaser/tap/goreleaser

Snap (Ubuntu, etc.):

sudo snap install --classic goreleaser

Docker:

docker pull goreleaser/goreleaser

Usage

ここではローカルで実行できる手順を示すが、CIツールを使うにしても、大まかなプロセスの内容は変わらない。

①.goreleaser.ymlの生成

.goreleaser.ymlは、goreleaserを使うために必須の設定ファイルで、ふつうはプロジェクトのルートディレクトリに置く。
goreleaserコマンドのオプションでパスを指定可能なので、好みで変えることはできそう。

次のコマンドで雛形を生成できる:

goreleaser init

②設定の編集

生成したYAMLを編集して、挙動をカスタマイズすることができる。
自分がよく使う設定については後述する。

③APIトークンの設定

GitHubやGitLabにリリースする際、goreleaserが利用するAPIトークンを設定する必要がある。
GitHubの場合、次のようにする:

export GITHUB_TOKEN="<YOUR API TOKEN>"

GitHub Actionsで設定する場合については後述する。

④goreleaserコマンド実行

ローカルから実行する場合、GitHubにタグをpushした後、次のコマンドでリリースを行う:

goreleaser --rm-dist

Dockerでgoreleaserを実行

④で示したように、ローカルにインストールしたgoreleaserのバイナリを使ってビルドを行うと、生成物にカレントパス(など)の情報が含まれてしまう。
即ち、生成されたバイナリを実行して、panicした際などにビルド環境のパスが露出したりする。

これを避けるには、CIから実行するか、goreleaserのDockerイメージを使って実行するとよい。

dockerコマンドで実行する場合は、次のようにする:

src_path="/go/src/github.com/<account>/<repo>"  # Module/パッケージに合わせて適切に設定する
docker run --rm --privileged \
  -v $PWD:$src_path \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -w $src_path \
  -e GITHUB_TOKEN \
  goreleaser/goreleaser release --rm-dist

(ローカル実行時の)ハマりポイント

主にローカルで実行する際に、初心者が一度はハマるだろうと思われるポイント:

  • ワーキングツリーの最新のコミットが最新のタグと一致してないとNG
    • これはCIでも同じと思われる
  • ワーキングツリーがdirtyだと失敗する。管理外のファイル、ディレクトリがあってもNG
  • 前回のビルド生成物が残っているなどで dist/ が空じゃないとき、 --rm-dist オプションを付けてないと失敗する

Configuration

.goreleaser.yml でカスタマイズしたくなりそうなところや、設定のTipsを記す。

(公式サイトに詳しいYAMLのサンプルがあるのは良いのだけど、大き過ぎて見切れてるとつらいのなんとかならないかな。。)

テンプレート変数

GoReleaserでは、YAML内の様々なフィールドでGoのテンプレート機能を使えるようだ。

使える変数は https://goreleaser.com/customization/templates に記されている。

Builds

https://goreleaser.com/customization/build/

builds:
# 複数のビルド対象を記述可能
- 
  # mainパッケージまたはmain.goへのパス
  # デフォルトは "."
  main: ./cmd/main.go

  # デフォルトは [linux, darwin]
  # Windowsもサポートしたいなら足す
  goos:
  - linux
  - darwin
  goarch:
  # デフォルトでは386(32-bit)も含まれる
  - amd64

Archive

https://goreleaser.com/customization/archive/

アーカイブファイル形式や、含めるファイルとか、ファイル名の設定。

archives:
- 
  # デフォルトはtar.gzだけど、単バイナリでいいときとか変えたくなりそう
  #format: binary

  # アップロードされるファイルで、GOOSやGOARCHの文字列を置換したいときに設定する。
  # 特にこだわりがなければ設定不要
  replacements:
    amd64: x86_64

  files:
  # アーカイブに何も追加したくない場合は、マッチしないglob文字列を書かないといけない
  - nothing*

Release

https://goreleaser.com/customization/release/

GitHubやGitLabに作成するリリースに関する設定。

changelog:
  # changelog要らない場合はtrueに設定。デフォルトは未設定
  skip: true
  # changelogにcommit logを昇順・降順どちらで載せるか(だと思う)
  sort: asc
  filters:
    # 無視するcommit log
    exclude:
    - '^docs:'
    - '^test:'

リリースノートをもっと自由にカスタマイズしたい場合、goreleaserコマンドの引数に指定する。

# 静的ファイル
goreleaser --release-notes=FILE
# コマンドで動的に生成
goreleaser --release-notes <(some_change_log_generator)

Features

Homebrew Formula生成

https://goreleaser.com/customization/homebrew/

GoReleaserでHomebrewのFormulaを生成することができる。

参考:

CI設定

各種CIツールへの設定方法についても公式ガイドがあって捗る。

GitHub Actions

https://goreleaser.com/ci/actions/

公式のアクションを利用できるので、簡単。

2020-06-14現在、progrhyme/shelpでの設定は下の通り。

name: goreleaser

on:
  push:
    tags:
      - '*'

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          # コミットログからリリースノートを作るならこのオプションが必要
          fetch-depth: 0

      - uses: actions/setup-go@v2
        with:
          go-version: 1.14
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v2
        with:
          version: latest
          args: release --rm-dist
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

任意のコマンドでリリースノートを生成

こちらの設定方法については、下の記事に書いた:

progrhyme
Software Engineer. Was @key-amb
https://progrhy.me/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away