Bitbucket Pipelinesファーストインプレッション Ansible * PostgresをCIしてみた。

Bitbucketに新しく導入されたPipelines (β版) をつかってAnsibleでPostgreSQLをインストールするビルドタスクを走らせてみます。

Pipelinesを使うのが初めてなので、ファーストインプレッションの感想が多めです。
※細かな設定はBitbucketリポジトリ [i05 / ansible\-postgres](https://bitbucket.org/i05/ansible-postgres)  から確認できます。


## Bitbucketリポジトリで Pipelines を有効にする
![Screenshot 2016-11-01 21.29.44.png](https://qiita-image-store.s3.amazonaws.com/0/1654/6cfa16cb-0483-f360-ac0b-5364b4e5eba0.png)

リポジトリを作成後、サイドバーから **Pipelines** を選択します。ここで、1つ小さな注意点があります。

#### ポイント: `bitbucket-pipelines.yml` はチェックインしない
私は [bitbucket\-pipelines\.yml の設定](https://ja.confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html) を前もって読んで bitbucket-pipelines.yml を `git commit` した状態でレポジトリへプッシュしたのですが bitbucket-pipelines.yml はBitbucketのページから作成する必要があるようで *"A file with this name already exists"* なるエラーが出てしまいました[^1]。

![Screenshot 2016-11-01 21.34.43.png](https://qiita-image-store.s3.amazonaws.com/0/1654/eedbd976-e175-4821-4e72-8f308c75351f.png)

ということで気を取り直し bitbucket-pipelines.yml を取り除いた状態で再プッシュ。

## プルリクエスト作成でビルド開始
Bitbucket上で bitbucket-pipelines.yml を編集します。

```yaml:bitbucket-pipelines.yml
image: python:2.7.12

pipelines:
  default:
    - step:
        script:
          - pip install --upgrade pip && pip install --requirement requirements.txt
          - echo localhost > inventory
          - ansible-galaxy install --role-file=role_packages.yml
          - ansible-playbook --inventory-file inventory site.yml --connection=local
```

特段トリッキーな印象はなく、書式に従えば期待通り動きました。
実行する処理はDockerfileに記述する内容と同等だと考えればよさそうです。
ここでは以前使用したことのある travis.yml のコマンドを大部分流用しました。

![Screenshot 2016-11-01 21.36.45.png](https://qiita-image-store.s3.amazonaws.com/0/1654/93947d71-5e84-e606-d7e5-e5bff2346130.png)

次のうちどちらにするか聞かれるのでお好みの動作を選択。ここでは健全にプルリクエストを作成します。

* そのまま master ブランチにコミット
* プルリクエストを作成

実際に作成したプルリクエストは [**i05 / ansible\-postgres / Pull request \#1: bitbucket\-pipelines\.yml created online with Bitbucket**](https://bitbucket.org/i05/ansible-postgres/pull-requests/1/bitbucket-pipelinesyml-created-online-with/diff) になります。

![Screenshot 2016-11-01 21.37.56.png](https://qiita-image-store.s3.amazonaws.com/0/1654/b3ca5d90-9b8d-04d1-965b-7c74ae13be4e.png)

プルリクエストを作成すると、自動的にビルドタスクが開始されます。
このあたり、外部サービスで新規レポジトリのビルドを走らせる場合は設定が必要（サービスに遷移→アカウント下のレポジトリを読み込み→プロジェクトでスイッチをONにする、など）なので嬉しいところです。

空いているからかすぐにビルドが始まりました。
待ち時間がないのは快適ですね。

標準出力をよしなに抜粋して折りたたみ表示をしてくれます。

![Screenshot 2016-11-01 21.40.00.png](https://qiita-image-store.s3.amazonaws.com/0/1654/843145e1-e8cb-070e-0d30-46eb0f8f1e52.png)

ビルド失敗の様子。色がついていて直感的に理解できます。

![Screenshot 2016-11-01 21.49.32.png](https://qiita-image-store.s3.amazonaws.com/0/1654/5c074bb5-b5cc-3d3b-55b5-b4c5f5eff372.png)

プルリクエスト一覧ページでもビルドステータスが表示されています。

![Screenshot 2016-11-01 21.53.49.png](https://qiita-image-store.s3.amazonaws.com/0/1654/9382d7bc-7c6d-cc01-2efc-93d9e37cb79e.png)

ビルド失敗のメール通知も届きました。

## ビルドがこけた箇所を修正

![Screenshot 2016-11-01 21.50.21.png](https://qiita-image-store.s3.amazonaws.com/0/1654/8c198eae-38e3-2c33-d083-f62bb203200c.png)

お行儀が悪いですが今回は master ブランチ側を修正したので *"Sync now"* で修正を反映します。

![Screenshot 2016-11-01 21.50.41.png](https://qiita-image-store.s3.amazonaws.com/0/1654/9de1e6e7-ab5e-b4ae-2ec7-87eabb34c6ee.png)

Pipelinesとは関係ないですが、明示的に sync しなければならないのは好き嫌いが分かれるところかもしれません（gitの `push.default` 設定に通ずるところがある気がします）。

![Screenshot 2016-11-01 21.52.00.png](https://qiita-image-store.s3.amazonaws.com/0/1654/cb128d2e-2100-b866-4f16-6c2ddda790d1.png)

そして sync にともなって自動でビルドタスクが走ります。賢い。

## ビルドが走りきったのでマージします
![Screenshot 2016-11-01 23.10.12.png](https://qiita-image-store.s3.amazonaws.com/0/1654/5c45011c-a1f1-f004-11af-c0e5ac9b896d.png)

何度かの修正後、Ansibleのタスクが走りきりました。

![Screenshot 2016-11-01 23.10.06.png](https://qiita-image-store.s3.amazonaws.com/0/1654/60abb8ea-825f-8834-8344-27060e7c3b3e.png)


公式ドキュメントの [Debug your pipelines locally with Docker](https://confluence.atlassian.com/bitbucket/debug-your-pipelines-locally-with-docker-838273569.html) では、今回のように失敗ビルドを量産して恥ずかしい目にあわないように手元のマシンで試す方法が紹介されています。

といっても、特別なことは何もなく通常通りDockerイメージを走らせるだけなのですが、ドキュメントではPipelinesの環境を再現できるよう `memory` のオプションなどが紹介されています。

![Screenshot 2016-11-01 23.10.17.png](https://qiita-image-store.s3.amazonaws.com/0/1654/65e78e78-7b66-628d-ebe6-0de38476cdd4.png)

プルリクエスト一覧ページからもビルドステータスが確認できます。

![Screenshot 2016-11-01 23.10.27.png](https://qiita-image-store.s3.amazonaws.com/0/1654/999445fc-9ee0-0a1f-6fba-adb74e0dd86c.png)

個別のプルリクエストページでも ***"N of N passed"*** と表示されています。

## ステータスはOverviewで表示される
![Screenshot_2016-11-02_11_34_45.png](https://qiita-image-store.s3.amazonaws.com/0/1654/bfa8304e-556d-d909-08a2-04b665c3b742.png)

地味に便利なのが Overview ページに "**master** has passed" と表示されているところ。
外部サービスを利用すると手動でREADMEにバッチを貼り付けなくちゃいけませんが、その手間が省けます。


## 所感
あくまで個人プロジェクトで軽くつかってみての感想です。

#### Pros
* 外部サービスではないので、複数のタブを行ったり来たりせずに済むのが気楽。
* ビルド開始の待ち時間が短い（これは今後の普及度合いによって変わってきそうです）。

#### Cons
* 任意のDocker imageが使えるのでほとんどのLinux環境などは使えるが、例えば類似のCIサービスではMacOS環境をサポートしてiOSアプリをビルドできたりするので、そういう用途ではまだ使えない。
* ~~REST API が未サポートなので外部ツールとの連携が難しい。オープンなチケットは [#13116 \- Add pipelines endpoint to REST API](https://bitbucket.org/site/master/issues/13116/add-pipelines-endpoint-to-rest-api) にあるので用意されそうではあります。~~ *2016-12-01追記:* Bitbucket APIにて[Pipelinesエンドポイント](https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Busername%7D/%7Brepo_slug%7D/pipelines)が提供開始されました。ビルドの一覧取得やエンキュー、状態取得および停止操作などが可能です。
* 複雑なデプロイタスクにまで発展させられるようなJenkins的な「なんでもあり」感はない[^2]。

まとめると、統合サービスならではの導入の手軽さが魅力。CIサービスとして、ビルドやテストが主用途となりそう。

[^1]: 2016-11-01現在。改善が入りそうな予感はあります。
[^2]: 具体的には複数リポジトリや静的ファイルホストサービス (S3など) と協調するようなデプロイタスクとフェイルオーバーの仕組み。あと鍵管理・ネットワーク制限を用いてデプロイをセキュアに実行する仕組みも気になるところです。簡易的な鍵管理の方法は [How do I set up ssh public\-key authentication](https://answers.atlassian.com/questions/39429257/how-do-i-set-up-ssh-public-key-authentication-so-that-i-can-use-ssh-sftp-or-scp-from-my-bitbucket-pipelines-pipeline) にて紹介されています。