おそらくはそれさえも平凡な日々

Goツールのビルドをおこない、GitHub Releasesにアップロードする

今回で最終回。Goのツールをビルドして成果物を生成し、それをGitHub Releasesにアップロードする。

ビルドする

CGOを使っていない限り、最近のGoは簡単にマルチプラットフォーム対応の実行バイナリをそれぞれビルドすることができる。

僕の場合、OSはlinuxとdarwin(Mac)用は必ず作っている。windows用も余力があれば作るようにはしている。アーキテクチャーはamd64(64bit)決め打ちにしてしまうことも多い。

また、成果物を配布する場合は、実行バイナリの他にLICENSEやREADMEなどを含め、zipやtar玉等に固めるのが定番。

これらのビルドとアーカイブに固める作業のために特別なツールは必要なく、シェルスクリプトでもいけるレベルだが、僕は goxc を使っている。

https://github.com/laher/goxc/

goxc は結構ゴツくてGitHub Releasesとかbintrayに上げる機能とかも持ってたりするんだけど、それの、成果物を生成する部分だけを利用しているという具合。

成果物のネーミングルールや、成果物に含めるファイルのルールを設定できるところが便利ではある。ただ、更新が滞っていることもあるし、そういう成果物生成だけに絞ったもう少しシンプルなツールが欲しいと思っている。

goxcの設定

goxc.goxc.json をリポジトリにおいておけば、 % goxc と打つだけで設定通りにビルドしてくれる。ただ、それを丁寧に書くのを以前はやってたんだけど、それらは大体コマンドライン引数で指定できるし、goxc のためにファイル増やすのも馬鹿らしいので、最近は、Makefileにcrossbuildっていうターゲットを作ってをそこにベタっと書くようにしている。

ghchのMakefile、より抜粋すると以下のような具合。

crossbuild: devel-deps
    goxc -pv=v$(shell gobump show -r) -build-ldflags=$(BUILD_LDFLAGS) \
      -d=./dist -arch=amd64 -os=linux,darwin,windows \
      -tasks=clean-destination,xc,archive,rmbin

これで、 make crossbuild を実行すれば、 dist/ 配下に成果物を配置してくれる。

$ tree dist/
dist/
└── v0.1.2
    ├── ghch_v0.1.2_darwin_amd64.zip
    ├── ghch_v0.1.2_linux_amd64.tar.gz
    └── ghch_v0.1.2_windows_amd64.zip

make crossbuild とすれば、手元でもCI環境であっても同様に成果物が作られるのがポイント。

CGOを使っている場合

CGOを使っている場合は、そのプラットフォーム用のCI/CD環境を用意するなどしてビルドする必要がある。Windowsの場合は、AppVeyorが定番です。Macの場合は、TravisのOS X環境を使うなどすれば良さそうですが、あまり知見はない。

mackerel-agentの場合、AppVeyorを利用してビルドの他にインストーラーの作成やインストーラーへの署名などもおこなっています。

それらの環境でビルドした成果物をアップロードする手順を作るのは少し複雑にはなってはしまう。

成果物をGitHub Releasesにアップロードする

成果物のアップロードには、 ghr を使っている。これはGitHub Releasesにアップロードすることに特化したシンプルで良いツールです。

参考: 高速に自作パッケージをGithubにリリースするghrというツールをつくった

環境変数 $GITHUB_TOKEN を設定した状態で、

% ghr v0.1.2 dist/v0.1.2

などとすれば、第1引数に指定したバージョンタグのGitHub Releasesに対して、第2引数に指定したディレクトリ以下の成果物を一括アップロードしてくれる。

クロスコンパイルして、アップロードするところまでは実際には以下のようなシェルスクリプトを用いている。

#!/bin/sh
set -e
make crossbuild
ver=v$(gobump show -r)
ghr $ver dist/$ver

これで、Goで書いたツールを、GitHub Releaseにアップロードできるようになりました。

手元ではなくTravis上でビルドとアップロードをおこなう

これまでは手元でビルドしてアップロードする方法を書きましたが、git tagが打たれたのを契機に、CI/CD環境でビルドやデリバリーをおこなうのも定番スタイルです。CI/CD環境であればクリーンな環境でビルドを作れるのもメリットです。反面複雑さが増す部分もあります。

とは言え、上に挙げたシェルスクリプトを単にTravisなどの環境で実行させればよいだけの話ではあります。その際 $GITHUB_TOKEN 環境変数をセットする必要はあります。

また、Travisで実施する場合、ビルドは make crossbuild でおこなうが、GitHub ReleasesへのアップロードはTravisの機能を使う手もあります。ghchではそのようにしています。

その場合、

% travis setup releases

とすれば、 .travis.yml を書き換えてくれるのでそれを調整する手順になります。調整した、 .travis.yml を抜粋すると以下のようになります。

before_deploy:
- make crossbuild
deploy:
  provider: releases
  skip_cleanup: true
  api_key:
    secure: ...
  file_glob: true
  file: "dist/**/*.{tar.gz,zip}"
  on:
    tags: true
    branch: master
    condition: "$TRAVIS_TAG =~ ^v[0-9].*$"

まあ、それなりに便利ではあるんですが、若干煩雑になる感はある。また、 travis setup の度に、GitHubの個人Tokenがぽこぽこ作られる仕組みになっていて、ツールを提供しているリポジトリ毎にtokenが作られてしまうのは気持ち悪いので、あまりやらないようにしている。

以上です。

created at
last modified at

2017-10-18T14:02:12+0900

comments powered by Disqus