hubotをdockerで動かしてみる（ローカル編）


## はじめに
チーム開発をしていて、レビュアーが足りなくて、レビュー待ちが発生することがあります。
そこで、レビュアーを増やすために、hubotにレビュアーを抽選＆アサインさせてみようと思います。
せっかくなので、普通に動かすのではなくて、dockerでローカルでもクラウド（`heroku`）でも同じように動かします。
今回は、ローカル編です。

さっさと動かしてみたい人は、こちらのリポジトリを参照ください。
https://github.com/imunew/hubot-github-reviewer-lotto

レビュアー抽選のアイデアは、下記のスライドが元ネタになっています。

- [Hubotレビュアーおみくじ @ githubkaigi // Speaker Deck](https://speakerdeck.com/sakatam/hubotrebiyuaomikuzi-at-githubkaigi)
- [sakatam/hubot-reviewer-lotto: A reviewer lottery script for Hubot](https://github.com/sakatam/hubot-reviewer-lotto)

## 事前準備
- [docker community edition](https://www.docker.com/community-edition) のインストール

## セットアップ
### Slackチームにhubotを導入
#### Hubot Integration を追加
- https://slack.com/apps/A0F7XDU93-hubot にアクセス
- 任意のチームにサインイン（URLのサブドメインを確認）`https://{your team}.slack.com`
- `Add configuration`ボタンをクリック
- `Username`にHubotの名前を入力
- `Add Hubot Integration`ボタンをクリック
- `API Token`をコピーしておく（後で環境変数にセットする）
- `Save Integration`ボタンをクリック

#### Hubot を任意のチャンネルに追加
追加されると、こんな感じで通知されます。
![join_bot.png](https://qiita-image-store.s3.amazonaws.com/0/26422/1c56bb5e-358e-486d-eff8-c21bfba989f3.png "join_bot.png")

### imunew/hubot-github-reviewer-lotto を clone
```bash
$ git clone git@github.com:imunew/hubot-github-reviewer-lotto.git
```

### 環境変数をセット
```bash
$ cd /path/to/repository
$ cp hubot/.env.example hubot/.env
$ vi hubot/.env
```

#### github 関連
[こちら](https://github.com/sakatam/hubot-reviewer-lotto)を参考に、下記の環境変数をセットします。

- HUBOT_GITHUB_TOKEN
- HUBOT_GITHUB_ORG
- HUBOT_GITHUB_REVIEWER_TEAM
- HUBOT_GITHUB_WITH_AVATAR

#### Slack 関連
[こちら](https://slackapi.github.io/hubot-slack/)を参考に、下記の環境変数をセットします。

- HUBOT_SLACK_TOKEN

前述の`Hubot Integration`を追加したときに、コピーしておいた`API Token`をセットします。

#### Redis 関連
今回は、docker-composeでredisコンテナと連携する関係で、下記のとおり設定します。

`REDIS_URL=redis://redis:6379`

その他、詳細は、[こちら](https://github.com/hubotio/hubot-redis-brain)を参照ください。

## Dockerコンテナのビルドと起動
```bash
$ docker-compose build --no-cache
$ docker-compose up -d
```

## レビュアーを抽選してみる
hubotを追加したSlackチャンネルにて、下記のようにコマンドを入力します。
`{bot name} reviewer for {repository name} {PR Number}`

コマンドを入力すると、

![request_reviewer.png](https://qiita-image-store.s3.amazonaws.com/0/26422/08c33666-e607-cef5-cf40-02a9fdc824a8.png "request_reviewer.png")

hubotから下記のように通知が返ってきます。

![reviewer_lotto.png](https://qiita-image-store.s3.amazonaws.com/0/26422/f6d6050c-e827-719e-1d5f-02eef78dc296.png "reviewer_lotto.png")

実際、githubで確認すると、`Pull-Request`の`Reviewers`に通知されたユーザーが追加されています。

![github_reviewers.png](https://qiita-image-store.s3.amazonaws.com/0/26422/95cb6c21-02a9-c8c8-1f1b-167835620481.png "github_reviewers.png")

## Docker化する上でハマったポイント
### `root`権限を持ったユーザーで`yo hubot`するとエラーになる
Dockerはデフォルトだと、rootユーザーで操作しますが、rootユーザーだと、`yo hubot`したときに、下記のようにエラーが発生します。

```
Error: EACCES, permission denied '/root/.config/configstore/insight-yo.json'
You don't have access to this file.
```

これは、既知の問題で、回避するには、一般ユーザーを作成、切り替えてから実行する方法が紹介されています。
https://github.com/yeoman/yo/issues/348

今回は、下記のようにして、ユーザーを切り替えるようにしました。

```
# hubot/Dockerfile
FROM node:4.8

RUN npm install -g yo generator-hubot
RUN npm install hubot-slack --save
RUN npm install underscore async github@8.2.1 weighted --save

RUN useradd hubot -m

USER hubot
WORKDIR /home/hubot

# Create hubot
RUN yo hubot --defaults --adapter slack

ADD ./external-scripts.json /home/hubot/external-scripts.json
ADD ./scripts/reviewer-lotto.coffee /home/hubot/scripts/reviewer-lotto.coffee

CMD bin/hubot --adapter slack
```

## レビュアー抽選スクリプトを改造
前述しましたが、このスクリプトは元ネタがあって、はじめは、`npm i --save hubot-reviewer-lotto`でインストールして終わりかなと思っていたのですが、`Pull-Request`の`Reviewers`ではなく、`Assignees`に追加されるので、そこだけ変更して、カスタムスクリプトとして、使うことにしました。

ちなみに、githubに`Reviewers`が追加されたのは、2016年の12月頃です。

- [GitHubでのコードレビューが爆速になる新機能review requestsの使い方 - Qiita](http://qiita.com/tonkotsuboy_com/items/cb64223737aff286111a)
- [Introducing review requests](https://github.com/blog/2291-introducing-review-requests)

`Assignees`から`Reviewers`に変更したポイントについて、まとめます。
詳しくは、下記のPRを参照ください。
https://github.com/sakatam/hubot-reviewer-lotto/pull/16

### node-github をアップグレード
githubの[Review Requests API](https://developer.github.com/v3/pulls/review_requests/)を使うために、結果的に`github@v8.2.1`までバージョンアップしました。

### node-github の仕様変更に対応
`github@v5.0.0`で、パラメータ`user`が`owner`に名前が変わったので、対応しました。

https://github.com/mikedeboer/node-github/blob/master/CHANGELOG.md#500

### `Assignees`から`Reviewers`に変更
`issues.edit`を`pullRequests.createReviewRequest`を使うように変更しました。

## おわりに
Docker化してみて良かったと思うことは、ローカルで動かすだけでもいくつかありました。

- 環境ごとパッケージになっているので、それぞれで環境構築しないで済む
  - 引き継ぎやすい？
- `yo hubot`で自動生成されたコードを管理しないで済んだ
  - 管理するのは、`scripts/`配下のファイルのみ

せっかくDockerで作った環境をできれば、そのままコンテナとしてデプロイしたいがどうするか、ということでクラウド（`heroku`）編に続きます。

ではでは。