goreleaser コマンドをちょろっと使ってみたらすごく便利だったメモ [GoReleaser]
はじめに
goreleaser コマンドをちょろっと使ってみたらすごく便利だったメモ。
GoReleaser は CLI と GitHub Actions が公開している。 個人的には GitHub Actions のほうを CI に取り込んで使うのがすごく便利に感じていて自分が作ってるツールとかは少しずつ GoReleaser を GitHub Actions のワークフローでやるようにしてるけど、GoReleaser がどんなものかは CLI のほうでいろいろ試してたら CLI のほうもすごく便利だった。
まだ GoReleaser を使ってないとかなら CLI でサッと試すのがお手軽だと思うし GitHub Actions じゃなくて CLI で手元のほうからなにかやるとかもありそうな気がするので CLI の goreleaser
コマンドをちょろっと使ってみたのをメモしておく。
GoReleaser はなにができるか
GoReleaser はこんなことができる。
- Go のプロジェクトをクロスコンパイルする
- アーティファクトを GitHub, GitLab と Gitea へリリースする
- Docker イメージとマニフェストを作成する
- Linux のパッケージと Homebrew のパッケージを作成する
自分は Go のプロジェクトは gox でクロスコンパイルして ghr で GitHub の Releases ページにアップロードしてるけどそのへんが GoReleaser で置き換えることができて、あと GoReleaser はクロスコンパイルの設定、アーティファクトの作成とか GitHub の releases へのアップロードの設定が YAML で設定できるのがとても便利で楽になってると感じる。
あと GoReleaser は動作がかなり速くて体感的にはクロスコンパイルとか一瞬で終わる感じ。
GoReleaser とかのバージョンをメモしておく。
GoReleaser のバージョン。
$ goreleaser --version goreleaser version 0.164.0 commit: d822baf11f7773f6c02eeaf7e187157b335935b3 built by: homebrew
macOS のバージョン。
$ sw_vers | grep Product ProductName: macOS ProductVersion: 11.3.1
インストール方法
Mac は brew で GoReleaser をインストールできる。
$ brew install goreleaser
go install
することもできる。
$ go install github.com/goreleaser/goreleaser
deb, rpm と apk でもインストールできる。このへんは 公式サイト のほうにやり方が書いてある。
goreleaser コマンドを使ってみる
.goreleaser.yml の雛形を作る
Git のリポジトリを作って適当な Go ファイルを作成する。
// main.go package main func main() { println("Hello World!") }
goreleaser init
コマンドを実行して .goreleaser.yml
の雛形を作る。実際に使うときは自分の用途に合うように .goreleaser.yml
を設定していく。
$ goreleaser init • Generating .goreleaser.yml file • config created; please edit accordingly to your needs file=.goreleaser.yml
goreleaser check
コマンドを実行して .goreleaser.yml
の設定が間違ってないかチェックする。
.goreleaser.yml
が YAML の構文エラーのときはこんな感じにエラーがある行を表示する。
$ goreleaser check • loading config file file=.goreleaser.yml ⨯ command failed error=yaml: line 5: mapping values are not allowed in this context
YAML の構文エラーがないけど .goreleaser.yml
の設定が間違ってるとこんな感じにエラーがある行を表示する。
$ goreleaser check • loading config file file=.goreleaser.yml ⨯ command failed error=yaml: unmarshal errors: line 10: field goosssss not found in type config.Build
.goreleaser.yml
が問題なければこんな感じに表示する。
$ goreleaser check • loading config file file=.goreleaser.yml • checking config: • snapshotting • github/gitlab/gitea releases • project name • loading go mod information • building binaries • creating source archive • archives • linux packages • snapcraft packages • calculating checksums • signing artifacts • docker images • artifactory • blobs • homebrew tap formula • scoop manifests • milestones • config is valid
とりあえず GoReleaser を動かしてみる
goreleaser --snapshot --skip-publish --rm-dist
コマンドを実行してとりあえず GoReleaser を動かしてみる。
$ goreleaser --snapshot --skip-publish --rm-dist
GoReleaser は通常は Git のタグと一緒に使うけど --snapshot
オプションを指定すると Git のタグは関係なく とりあえず クロスコンパイルする。あと GoReleaser はデフォルトではアーティファクトを GitHub とかにアップロードするけど --skip-publish
オプションを指定するとアーティファクトが GitHub とかにアップロードしない。
とりあえず動作と構成を確認したいけどアーティファクトは GitHub とかにアップロードしたくないときはこの2つのオプションを指定して goreleaser
コマンドを実行する感じ。
あと GoReleaser はデフォルトはアーティファクトを dist
ディレクトリに作成する & dist
が空じゃないときはエラーになるけど、--rm-dist
オプションを指定すると dist
ディレクトリを削除してからクロスコンパイルする。
一応、アーティファクトの作成先のディレクトリは .goreleaser.yml
の dist
で指定できる。
# .goreleaser.yml dist: ./build
バージョンの埋め込み
GoReleaser はデフォルトで以下を ldflags に設定する。
main.version
main.commit
main.date
こんな感じのコードを書いておくとバージョンとかが main.version
とかに埋め込む。
// main.go package main import "fmt" var ( version = "dev" commit = "none" date = "unknown" builtBy = "unknown" ) func main() { fmt.Printf("my app %s, commit %s, built at %s by %s", version, commit, date, builtBy) // my app v0.0.0-next, commit none, built at 2021-05-16T15:10:15Z by gorelease }
アーティファクトを GitHub にアップロードする
GoReleaser がアーティファクトを GitHub にアップロードするときは GitHub の API トークンが必要になるので PAT を GITHUB_TOKEN
に設定しておく。もし PAT がまだ発行してなかったら https://github.com/settings/tokens/new で発行しておく。
$ export GITHUB_TOKEN=<GitHub の API トークン> $ goreleaser --rm-dist
GitHub の API トークンはファイルに保存しておいてファイルへのパスを .goreleaser.yml
で指定することもできる。
env_files: github_token: /path/to/your/github_token
すぐに使える .goreleaser.yml
.goreleaser.yml
はだいたいこんな感じのものを個別のプロジェクトごとに設定をカスタマイズして使えそう。
before: hooks: - go mod tidy builds: - env: - CGO_ENABLED=0 goos: - linux - windows - darwin goarch: - 386 - amd64 - arm64 ignore: - goos: darwin goarch: 386 - goos: windows goarch: arm64 archives: # アーティファクトのアーカイブのフォーマット。 # `tar.gz`, `tar.xz`, `gz`, `zip` and `binary` のいずれかを指定する。デフォルトは `tar.gz` - format: zip # アーティファクトのファイル名のテンプレート。 # `myproject_darwin_amd64.zip` みたいなファイル名 name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' wrap_in_directory: true checksum: name_template: 'checksums.txt' snapshot: name_template: "{{ .Tag }}-next" changelog: sort: asc filters: exclude: - '^docs:' - '^test:'