お手軽CI Bitbucket Pipelinesの使い方

この記事は[Wanoアドベントカレンダー](https://qiita.com/advent-calendar/2017/wano-group)の15日目です。
（実は日曜日に公開を予定していたのですが、体調不良でダウンして書けなかったので、代わりに15日目にアサインしました。なおてぃ代わりに日曜日に書いてくれてありがとう。）

みなさん、Bitbucketは使っていますか？
プライベートリポジトリが無料で作れるBitbucketは公私ともにお世話になっております。

ちょっと前にうちの会社のプロジェクトでテストコードをゴリゴリ書くようになりまして、それに伴ってテストをやってる感を演出するために、Bitbucket付属のお手軽CIであるBitbucket Pipelinesを導入しました。
使ってみるとこれが地味に便利で、常時テストが回っているので、コードの品質を担保するのに十分に役立ってくれています。

今回はこの便利なBitbucket Pipelinesをもっと使っていこうぜ、という布教のため、記事を書いてみました。

# Bitbucket Pipelinesって？
![image-20171122014123793.png](https://qiita-image-store.s3.amazonaws.com/0/69711/c31b6105-30ed-55fd-4597-89bc37ab5c96.png)
↑コイツ

Bitbucket付属のCI。
なんやいろいろ好きなコードを走らせる事ができる。
最初から同梱されているので、すぐに誰でも使える（無課金ユーザーでも使える）
コードの品質が保てて世界が幸せになれる魔法のツール（言い過ぎ

# 特徴
## 便利なところ
* 始めるにはbitbucket-pipelines.ymlというファイルを1つ作ってリポジトリに突っ込めばもう動いちゃう。
* CIをまわす環境は、Docker Hubにあるimageを色々組み合わせて利用することができる。
* imageがなくてもDockerFileでbuildしてCI回すとかもできるらしい。
    * （参考） https://blog.bitbucket.org/2017/04/18/bitbucket-pipelines-supports-building-docker-images-and-service-containers/
* 一応CIなので、他のサービス（AWS CodeDeployとか）と繋ぎこむことで、テスト成功後自動デプロイとかできたりもする。もちろん手動のトリガーによるデプロイも可能。
    * （参考）　https://community.atlassian.com/t5/Bitbucket-articles/Bitbucket-Pipelines-%E3%81%A7-AWS-CodeDeploy-%E3%81%99%E3%82%8B/ba-p/620423
* Bitbucketの料金に含まれているので、実質お値段が余計にかからない（超重要） ただし実行できる時間の制限がある。
    * （参考） https://ja.atlassian.com/software/bitbucket/pricing?tab=cloud
* もちろんテスト結果をSlackに通知とかも簡単に設定できる。
* CIで使うSSH鍵をあらかじめ登録することができる。なので、CI内で他プライベートリポジトリをcloneする必要とか、SFTPでファイルをダウンロードしてゴニョゴニョする必要とかあっても、問題なく動かすことができる。（地味に便利）

## 悲しいところ
* bitbucket-pipelines.ymlをcommitしてpushしないと動かない。CIを動かすために、修正してはcommit、修正してはcommitしてたら大量のcommitログができあがった（一番辛い）
* 動くDockerイメージは全てlocalhostで動く。host名指定とかできない。この場合、DockerのMySQLに接続するときに、ホスト名をlocalhostとすると動かないので、気をつける必要がある。
    * （参考） https://qiita.com/Lio/items/3127685e26081993b51e
* bitbucket-pipelines.ymlは空文字を受け付けてくれない（validation failedとなる）ので、MySQLのユーザーを空パスワードで作るとかできない。docker imageのMYSQL_ALLOW_EMPTY_PASSWORDをしても同じ。

# というわけで使ってみる。
以下の例は、社内のGo言語で書かれているプロジェクトの例。

MySQLのDokerイメージと、Go言語のDocker imageを持ってきて、ライブラリ管理ツールであるglideをインストールして、glide install、go testを実行するだけのシンプルなやつ。

## SSH鍵の登録
まずはCIをまわしているときに使うSSH鍵を登録する。

![スクリーンショット 2017-12-15 1.42.02のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/69711/3f8d22ed-eed7-58b7-846a-516c2ad4eca1.png)

設定 -> PIPELINESの項目のSSH keys -> 作った秘密鍵と公開鍵を登録する。

今回はさらに他のプライベートリポジトリをcloneできるように、作ったSSH鍵の公開鍵をcloneしたいプロジェクトに登録する。

![スクリーンショット 2017-12-15 2.00.34.png](https://qiita-image-store.s3.amazonaws.com/0/69711/ccdf9c1d-7cc7-54df-c283-6f7dd5308111.png)

cloneしたいリポジトリの設定 -> Access Keysから登録する。

## bitbucket-pipelines.ymlの作成
bitbucket-pipelines.ymlを作成する。
細かい仕様はこちら。
https://confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html

以下はうちのプロジェクトの例。

```yaml:bitbucket-pipeline.yml
image: golang:1.8.3 # CIをまわすDocker image。Docker Hubにあるやつはなんでも使える。

pipelines:
  default:
    - step:
        script:
          - curl https://glide.sh/get | sh  # glideのインストール
          - PACKAGE_PATH="${GOPATH}/src/bitbucket.org/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}"
          - mkdir -pv "${PACKAGE_PATH}"
          - tar -cO --exclude-vcs --exclude=bitbucket-pipelines.yml . | tar -xv -C "${PACKAGE_PATH}" # リポジトリのファイルをDocker内に展開
          - cd "${PACKAGE_PATH}"
          - glide install
          - go test -c -i -o hoge.test bitbucket.org/wanocoltd/hoge # テスト用バイナリを生成
          - ./hoge.test -test.v # テスト実行
        services:
          - database

definitions:
  services:
    database:
      image: mysql:5.7
      environment:
        MYSQL_ROOT_PASSWORD: hogehoge
        MYSQL_DATABASE:hoge_db
        MYSQL_USER: 'root'
```

ちなみにbitbucketは、bitbucket-pipelines.ymlファイルのバリデータを提供してくれているので、commitする前にそれとなく確認する事ができる。
https://bitbucket-pipelines.atlassian.io/validator

## CIの実行
先ほどのymlファイルをcommitしてpushすると、bitbucketのpipelinesのコンソール上で動き始める。

![image-20171122021418086.png](https://qiita-image-store.s3.amazonaws.com/0/69711/7f5990ad-d97b-0606-169e-c6abc22588ad.png)

Happy!!🎉

# まとめ
こんな感じで導入はかなり手軽なので、みんな使うと良いかと思います。
Bitbucketと契約しているプランにより、1ヶ月の間に回せるテストの時間が決まっていますが、特定のブランチだけテストを回す、なんてこともできるので、みんな気軽にymlファイルをpushしちゃえばいいじゃない！！

# （余談）Slackへの通知設定
テストを回すリポジトリの設定 -> Webhooksより、slackのBitbucketのWebhookURLを設定します。そのときに、以下のように、「ビルド ステータスが更新された」にチェックを入れれば、Pipelinesが動いた時のイベントを受け取る事ができます。

![スクリーンショット 2017-12-15 2.20.19.png](https://qiita-image-store.s3.amazonaws.com/0/69711/8e26ff1e-aa07-aac6-2fe6-3555a1f45789.png)

Slackでの通知内容なこんな感じ。
失敗時。
![スクリーンショット 2017-12-15 2.25.15.png](https://qiita-image-store.s3.amazonaws.com/0/69711/a928c632-911e-dbb9-da94-87112dde57dc.png)

成功時。
![スクリーンショット 2017-12-15 2.25.53.png](https://qiita-image-store.s3.amazonaws.com/0/69711/ab1acfdf-d76f-dfd1-2853-5fca0a59bb58.png)