Go言語のビルド生活を drone.ioで幸せに暮らす #golang

[Go Advent Calendar 2013](http://qiita.com/advent-calendar/2013/go) 5日目の投稿です。

Qiitaに投稿するのは初めてな @atotto です。よろしくお願いします。

# Go言語のビルド生活をdrone.ioで幸せに暮らす

## はじめに

Goは[クロスコンパイルがとても簡単](http://atotto.hatenadiary.jp/entry/20120501/1335846012)です。実行ファイル形式で配布する場合、他の環境用にサクっとコンパイルして渡すことができます。
ただ、githubなどにコードは公開してるけど各環境用にコンパイルしたものをさっと配布したいなーと思うとちょっと面倒です。みんながGoのコンパイル環境をもっているとも限りませんし。そこで、CI([継続的インテグレーション](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3))環境でクロスコンパイルしてバイナリを配布できるようにするしくみがないか探してみました。

やりたいことをまとめると:

* リポジトリにあるコードをCI環境上でクロスコンパイルしておきたい
* 成果物をダウンロードできるようにしておきたい

ということです。

この記事を読めば、drone.ioで自分のリポジトリをクロスコンパイルしたものを公開できるようになります。

### drone.ioとは？

[drone.io](https://drone.io/) は [Travis-CI](https://travis-ci.org/) や [BuildHive](https://buildhive.cloudbees.com/)と同じようにリポジトリと連携してCIしてくれるありがたいサービスです。drone.io 自体は１年ほど前から存在するサービスですが、今回はじめて使いました。
余談ですが[drone.ioのサービスはGoでできてます](https://groups.google.com/forum/#!topic/golang-nuts/Lo7KP3rWP3o)！

## 手順

まずは drone.io に登録し、githubアカウントと連携します。これは特に説明しません。
[New Project](https://drone.io/new)から自分のリポジトリを選択し、続いて利用する言語を選択します。もちろんGoを選択。

![select-go.png](https://qiita-image-store.s3.amazonaws.com/0/30362/c2b442be-ebb1-5ea6-de4f-adbff542b4da.png)

今回、実験に使うリポジトリは https://github.com/atotto/fileserver です。単純なWebファイルサーバをGoで書いてあります。

### 設定する

次に設定です。

#### Build & Test

Build Script、もしくは、Setting→Build & TestのCommands内に以下を入れておきます：

```shell-session
# Cross Compiling http://docs.drone.io/golang.html
rm -rf /usr/local/go/src/pkg/appengine
rm -rf /usr/local/go/src/pkg/appengine_internal

pushd /usr/local/go/src
GOOS=windows GOARCH=amd64 ./make.bash --no-clean 2> /dev/null 1> /dev/null
GOOS=darwin  GOARCH=amd64 ./make.bash --no-clean 2> /dev/null 1> /dev/null
popd

GOOS=windows GOARCH=amd64 go get ./...
GOOS=darwin  GOARCH=amd64 go get ./...

mkdir artifacts
cp -r `go env GOPATH`/bin artifacts
```

基本的に、 [Building Go Projects](http://docs.drone.io/golang.html)に書かれている通りですが以下に補足します。

line:6-7のクロスコンパイルの設定は、GOOSとGOARCHの環境変数へ値をいれます。Goのドキュメント[Optional environment variables](http://golang.org/doc/install/source#environment)に詳しい組み合わせが書いてありますので、クロスコンパイルしたい環境はここから選んでみてください。

line:10-11で、`go get ./...`としているのは、自パッケージのサブディレクトリにあるものを含めるためです。ここではgo testを実施しません。

line:13-14で、artifactsのディレクトリに、ビルドした実行ファイル群をコピーしています。これは、次のArtifactsに関係します。
普通に実行ファイルをビルドすると `$GOPATH/bin` へ格納されますが、クロスコンパイルでビルドした実行ファイルは `$GOPATH/bin/<GOOS>_<GOARCH>` なディレクトリへ格納されます。例えば、`GOOS=darwin`で`GOARCH=amd64`であれば、 `$GOPATH/bin/darwin_amd64` へ実行ファイルが格納されることになります。

ちなみにここでは`go test`を割愛しています。

#### Artifacts

次に、Artifacts に以下を入れます。

```shell-session
artifacts/bin/*/*
```

こんな感じ。↓
![Artifacts.png](https://qiita-image-store.s3.amazonaws.com/0/30362/f0752e4e-9dc1-73ce-2037-5be36e2d11e5.png)

これでartifactsに入っているファイル群を保存します。


### ビルドする！

最後に、Build & TestにあったBuild Nowボタンをクリックしてビルドを開始します。

![buildnow.png](https://qiita-image-store.s3.amazonaws.com/0/30362/0db3c62c-4552-eb6a-6de2-6bbac100d990.png)

すると、ビルドコンソールが表示され、、

![buildconsole.png](https://qiita-image-store.s3.amazonaws.com/0/30362/2d1e3bf5-5408-a31f-0ba5-f108dfa87296.png)
※ スクリーンショット中は調子にのって他の環境用のクロスコンパイルまでやってます。

ビルドが終われば 以下のようにDownloads のタブに成果物が入っているはずです↓

![downloads.png](https://qiita-image-store.s3.amazonaws.com/0/30362/f6a7cd8f-39e7-b91c-abe8-6f74482e7ad6.png)
※ スクリーンショット中は調子にのって他の環境用のクロスコンパイルまでやってます。

これで各環境用のバイナリができました！
通常はビルドボタンを押さずにgithubへpushしたことを契機に自動的にビルドしてくれます。

## まとめ

drone.ioを使って気になったところは、GoのバージョンをUI上で指定できないところです。Travis-CIではGoのバージョンを指定することができますが、drone.ioではGoのリリース版のみ使える様子です。最新のreleaseやtip版が使いたいとか、rc版を使いたいといった場合は、CI上でGoコンパイラを再コンパイルしたり、コンパイラをダウンロードしたりする工夫が必要になります。

といってる間に、私の設定は最終的にこうなりました : https://drone.io/github.com/atotto/fileserver/admin

おしまい。

## 参考資料

* [drone.io docs](http://docs.drone.io/)
  * [Project Setup](http://docs.drone.io/newproject.html)
  * [Building Go Projects](http://docs.drone.io/golang.html)
  * [Build Artifacts](http://docs.drone.io/artifacts.html)
* [Go言語でクロスコンパイルする](http://atotto.hatenadiary.jp/entry/20120501/1335846012)

# 宣伝

http://github.com/gophersjp/go で http://golang.org/ のドキュメントの一部を翻訳しています（のんびり）。
もし興味のある方は twitter @atotto や gophersjp@gmail.com までメールください。