Next.jsでPullRequestの鮮度を保つツールを作っている

[第2のドワンゴ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/dwango2)折り返し地点の12日目です([第1はこちら](http://qiita.com/advent-calendar/2016/dwango))。

ドワンゴで開発したりしている@ringo(aoki)です。初心者なんでお手柔らかにおねがいします。忙しい人は適当にスクロールしてスクリーンショットとかを眺めてもらえればよいと思います。
先月(2016年11月)の12、13日に[Node Knockout](https://www.nodeknockout.com/)というnode.jsの48時間ハッカソンがありました（去年は[@mesoさんがPrizeをゲットしてました](http://qiita.com/meso/items/9de42917e000a5724225)。おとなしくチームmesoに入っていればよかったと今でも後悔しています）。ぼくは、このイベントに新卒のときから（成果はともかく）毎年参加しており、今年も参加しました。しかし、Engine Yardへのデプロイにハマり、指定されたドメインにホスティングができなくて途中で心がおれて幕を閉じました。

途中で断念してしまったこともあり、折角なのでその時に取り組みたかったことを今回のアドベントカレンダーのネタにしてみました。


## 腐っていくプルリクエスト

まず、Node KOで何を作ろうとしたかというと、GitHubの複数Organization、複数リポジトリに出されたプルリクエストを串刺しで一覧するツールです。開発しているときに、リポジトリが沢山あると各リポジトリに出されたプルリクエストを見て回るのが面倒くさくてやってられません。チームのリポジトリをカウントしてみたら大小含めて56リポジトリありました。さらに、忘れ去られたリポジトリがあったりもして、放置されるプルリクエスト。誰にもみてもらえない、可哀想なプルリクエストは、そのうち出した本人も忘れてしまうこともあります。失われる**フレッシュネス**。

毎日、15時から行われる朝会でプルリクエストを確認はしているんですが、複数リポジトリを一覧する方法がGitHubにはなく（ないよね。。？）非常に困っていました。一応、HubotでSlackにPR一覧を投稿するaokibotを作って運用していますが、出来ることに限界があります。

大きな要件としては、以下のようなものになります。

- Organization内のプルリクエストを一覧したい
- レビュアーがレビューしてくれているか知りたい
- プルリクエストの鮮度がどのくらいか知りたい
- 依存関係があるプルリクエストが一覧にあると見辛いのでなんとかしたい
- 「このプルリクエストをレビューお願いします」っていうのが面倒くさい

基本的にみんな自分のタスクがあるので人のプルリクエストは後回しな感じがあると思います。面倒くさいことを潰して、ハードルを下げていけばプルリクエストのフレッシュネスが保てる気がします。


## Next.js + React.js + Redux

今回はNext.jsというReact.jsをサーバサイドレンダリングしつつも、フロントでもReact.jsが使えるフレームワークを採用しました（表現があってるかな？）。「採用した」というようりも、使ってみたいという気持ちだけでしたが。このフレームワークは[10月末に発表されて](https://zeit.co/blog/next)、「Node KOで使おう」と思ってから少し触ってみたりしていました。

Next.jsはサーバサイドとフロントエンドを同じコードベースで記述できる不思議なでイケてるフレームワークだと思います。説明すると長くなるし、上手く伝えられない気がするので、どんなものかは[公式ページ(zeit/next.js)](https://github.com/zeit/next.js/)か[Kanezawaさん(@nkzawa)が訳してくれている記事](http://qiita.com/nkzawa/items/1e0e93efd13fb982c8c0)を読んでくれればわかると思います。また、Node Kockoutの裏側で開催されていた、[東京ノード学園祭2016のKanezawaさんの発表](https://www.youtube.com/watch?v=_WtCQmAsWlk)をみるのもよいと思います。

普段はReduxではなくRefluxを使っていたので、Reduxにも入門してみました。

公開まで時間がないので細かいことはブログとかに書いていこうかと思います。


## Freshness Pull Request
できたのがコチラ。

![ss.png](https://qiita-image-store.s3.amazonaws.com/0/23980/238ee8ad-3f81-090a-8b50-113efc253a6d.png)

対象のOrganizationは[dwango.oss](https://dwango.github.io/)に載っているものにしました。まだ、上手く整えられていませんが、Org.、リポジトリ、プルリクエストの順で階層的に表示しています。アイコンはプルリクエストを出した人。右の赤い数字はフレッシュネス（何日放置されているか？）を表示したものです。とりあえず3日以内を新鮮。5日までを普通。それを超えると腐ったプルリクエストとしました（ちょっとキツすぎたかな）。


ぼくのチームの状況はこんな感じ(Darkバージョン)。

![ss_ghe 2.png](https://qiita-image-store.s3.amazonaws.com/0/23980/fd4d3a72-24b0-f8c9-be57-683256f85f52.png)


プルリクエストのボディに

```markdown
- [ ] @aoki
- [ ] @aoki2
- [ ] @aoki3
```

のようなリストを書くと、レビュアーとして認識して、プルリクエストの右側にアイコンを表示します。レビュー完了するとその人のアイコンは半透明になります。最新のGitHub、GitHub Enterpriseにはレビューが完了しないとマージできない設定も入ったので、そっちにも対応したいです。

ここのプルリクエストを見ると大体、2か3日での鮮度っぽいです（休日を挟むとすぐ腐りますが）。

## まとめ
もう公開まで30分切ったのでまとめと今後の展望を。

### Next.jsの感想

Next.jsは最近のbabelとかreactとかのモジュールと何もインストールしないで、コードを書き始められるので、**書き始めるまでにやる気が下がらない確率が高い**。何か作ろうと思っても、babelやwebpack、reactの設定をアレコレしてると、それだけである程度の謎の満足感が得られ本来やりたかった事へのモチベーションが低下している（気づくと）。そして、そういうのがあると思うと腰が重い。しかし、Next.jsはそこら辺がないので最高だった。まあ、create-react-appとかもあるんですが。

- ES6をなにも考えずにつかえる
- babelとかを設定しなくてもいいから最高
- モチベーションが低下しないうちにコードを書き始められる
- 自動リロード機能もついてる
- サーバサイドとクラアントでアイソモーフィックなコードが書ける

package.jsonもスッキリする。

```json
  "dependencies": {
    "immutable": "3.8.1",
    "isomorphic-fetch": "2.2.1",
    "next": "1.2.3",
    "perchance": "^1.0.1",
    "react-github-corner": "^0.3.0",
    "react-redux": "4.4.6",
    "redux": "3.6.0",
    "redux-thunk": "2.1.0"
  },
  "devDependencies": {
    "ava": "0.17.0",
    "eslint-config-xo": "0.17.0",
    "eslint-config-xo-react": "0.10.0",
    "eslint-config-xo-react-space": "0.5.0",
    "eslint-config-xo-space": "0.15.0",
    "eslint-plugin-react": "6.8.0",
    "xo": "0.17.1"
  },
```

逆に、どうしたらよいかわからなかったことは、

- サーバアプリの初期化処理をどこでかけばよいのか？
  - サーバで読み込む環境変数や、トークンなどをどこで読み込めば良いのか？
  - `getInitialProps` なのか??
- next/css をマージするにはどうしたらよいのか？


もう少し触ってみたりしようと思う。
[nuxt](https://nuxtjs.org/)っていうvue.jsベースのもあるらしいよ。nextのslackにnuxtの情報を探しにきた人が入ってきて面白かった。

### これから

実装してみたいことがたくさん出てきました。

- Reviewer Required に対応する
- 設定ファイルから設定を読み込めるようにする
  - フレッシュネスの閾値
  - Organizationの指定
  - GitHub、GHEの切り替え
- だれかレビュー頼むボタン
  - 押すとSlackにPOSTしてレビューしてない人にメンションしてくれる
- Dockerで起動できるようにする
- Organizationだけではなく、Userリポジトリのプルリクエストにも対応
- 認証をちゃんとする（今はtokenでGitHubの認証をしてるので）
- プルリクエスト依存関係を表示する（PR:aはPR:bに依存してるとか）
- プルリクエストの優先度を表示する（nice値みたいのがほしい）
- カラースキームを設定できる
  - light/dark
- チケットIDからJIRAチケットなどへの自動リンク

## GitHubに公開してあります

ソースコードは[GitHub](https://github.com/ringohub/freshness)に公開してあります。
**ツッコミやアドバイス、Issue、プルリクエスト**などなんでもお待ちしております。
最後の方は駆け足（かなり）になってしまって、申し訳ありませんでした。。。とりあえず、近々READMEでもかきます。

また、JSやReact、Redux、Next.jsへの理解が浅く、Next.jsの良さを、まだフルに使えていない気がします。

- GitHub: [ringohub](https://github.com/ringohub)
- Twitter: [ringohub](https://twitter.com/ringohub)
- Blog: [ri.hateblo.jp](http://ri.hateblo.jp/)

## References
- [GitHub - zeit/next.js: A minimalistic framework for universal server-rendered React applications](https://github.com/zeit/next.js)
- [Next.js - Qiita](http://qiita.com/nkzawa/items/1e0e93efd13fb982c8c0)
- [Reactの再レンダリングをなるべく減らす - Aqutras Members&#39; Blog](http://blog.aqutras.com/entry/2016/06/23/210000)
- [React.jsのComponent Lifecycle - Qiita](http://qiita.com/koba04/items/66e9c5be8f2e31f28461)
- [Redux example · zeit/next.js Wiki · GitHub](https://github.com/zeit/next.js/wiki/Redux-example)
- [Redux Extension](http://zalmoxisus.github.io/redux-devtools-extension/#1.-with-redux)
- [Dan Abramov - Live React: Hot Reloading with Time Travel at react-europe 2015 - YouTube](https://www.youtube.com/watch?v=xsSnOQynTHs)
- [ざっくり React with Redux チュートリアル - Qiita](http://qiita.com/pullphone/items/d28baeb296666a4847b8)