reviewdogを使ってtextlintの結果をPull Requestに書き込む方法

この記事は、[textlint](https://github.com/textlint/textlint "textlint")のチェックでエラーとなった結果を、Pull Requestのレビューコメントとして書く設定をする手順をまとめたものです。

textlintを使っているCI環境に数行追加する程度で、次のようにPull Requestのコメントに指摘内容が自動で書き込めるようになります。

[![textlint-reviewdog-example 2017-02-10 23-23-17](https://cloud.githubusercontent.com/assets/19714/22829900/f0ab5cba-efe7-11e6-904f-7eae4e2701ba.png)](https://github.com/azu/textlint-reviewdog-example/pull/1)


[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")を使うことで、CIからレビューコメントとしてLintの結果を書き込むことができます。

CIでLintがエラーとなった場合、CIの画面までエラーを見に行く必要があって面倒です。
[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")を使うことで、PRの画面上にLintのエラーが表示されるので手間が省けて便利です。

基本的には次の記事と同様です。

- [textlintをTravis CIで動かして継続的に文章をチェックする - Qiita](http://qiita.com/azu/items/e36501d25593d008f6ac)
- [Travis CIでtextlintの指摘をPull Requestのレビューコメントとして書き込む - Qiita](http://qiita.com/azu/items/c2305f3dded3fda968e0)
  - この記事の[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")版という感じです
  - [reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")の方が設定は簡単な印象

## textlintとは

textlintはNode.jsで書かれた拡張可能な自然言語のLintツールです。
ESLintのようにルールをプラグインとしてインストールし、MarkdownやText、[Re:VIEW](https://github.com/orangain/textlint-plugin-review "Re:VIEW")などといったファイルを対象にLintを行えます。

- [textlintで日本語の文章をチェックする | Web Scratch](http://efcl.info/2015/09/10/introduce-textlint/ "textlintで日本語の文章をチェックする | Web Scratch")
- [Collection of textlint rule · textlint/textlint Wiki](https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule "Collection of textlint rule · textlint/textlint Wiki")

Lintするだけでなく`--fix`で自動修正することも一部ルールでは対応しています。
[textlint-rule-no-dead-link](https://github.com/nodaguti/textlint-rule-no-dead-link "textlint-rule-no-dead-link")を使ってリンク切れを見つけたり、[textlint-rule-terminology](https://github.com/sapegin/textlint-rule-terminology "textlint-rule-terminology")や[textlint-rule-prh](https://github.com/azu/textlint-rule-prh "textlint-rule-prh")を使ってプロジェクトに沿った辞書を作ったり、[技術文書向けのtextlintルールプリセット](https://github.com/textlint-ja/textlint-rule-preset-ja-technical-writing "技術文書向けのtextlintルールプリセット")などもあります。

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">textlint with terminology and no-dead-link rules is super cool. Most of the issues can be auto fixed.<a href="https://t.co/DVouqBOMga">https://t.co/DVouqBOMga</a> <a href="https://t.co/BQgPN7qT59">pic.twitter.com/BQgPN7qT59</a></p>&mdash; Artem Sapegin ☕ (@iamsapegin) <a href="https://twitter.com/iamsapegin/status/830459495113433090">February 11, 2017</a></blockquote>


## サンプルプロジェクト

この記事で作成したサンプルプロジェクトは次のようになっています。

- [azu/textlint-reviewdog-example: textlint + reviewdog example project](https://github.com/azu/textlint-reviewdog-example "azu/textlint-reviewdog-example: textlint + reviewdog example project")

textlintでのテストをTravis CIで動かし、[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")でtextlintの結果をレビューコメントとして書き込めます。

## textlintのインストール

```
npm init
npm install -D textlint textlint-rule-no-todo
```

ルールはこちらにまとめられています。

- [Collection of textlint rule · textlint/textlint Wiki](https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule "Collection of textlint rule · textlint/textlint Wiki")

## textlintの設定をする

以下のコマンドで`package.json`でインストールしているルール元に、`.textlintrc`が作成されます。

```
$(npm bin)/textlint --init
```

`.textlintrc`:

```json
{
  "filters": {},
  "rules": {
    "no-todo": true
  }
}
```

## textlintを動かす

```sh
✈ $(npm bin)/textlint README.md

/Users/azu/.ghq/github.com/azu/textlint-reviewdog-example/README.md
  13:3  error  Found TODO: '- [ ] Write usage instructions'  no-todo

✖ 1 problem (1 error, 0 warnings)
```

## Travis CIを設定する

基本的に[textlint](https://github.com/textlint/textlint "textlint")は[ESLint](https://github.com/eslint/eslint "ESLint")と互換のある`--format`を持っているので、`s/eslint/textlint`すると大体動きます。

詳細は[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")のREADMEを見てみてください。

- [reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")
- [reviewdog を飼ってコードレビューや開発を改善しませんか - haya14busa](http://haya14busa.com/reviewdog/ "reviewdog を飼ってコードレビューや開発を改善しませんか - haya14busa")

`.travis.yml`を次のように設定します。

```yaml
sudo: false
language: node_js
node_js: "stable"
env:
  - REVIEWDOG_VERSION=0.9.5
install:
  # reviewdogのバイナリを落としてパスを通す
  - mkdir -p ~/bin/ && export export PATH="~/bin/:$PATH"
  - curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o ~/bin/reviewdog && chmod +x ~/bin/reviewdog
  - npm install
script:
  # ここではtextlintでチェックしてるだけ
  - $(npm bin)/textlint README.md
after_failure:
  # テストが落ちた = textlintで見つかるエラーがある
  # PRの時のみreviewdogでレビューコメントを書き込む
  - test $TRAVIS_PULL_REQUEST && $(npm bin)/textlint -f checkstyle README.md | reviewdog -f=checkstyle -name="textlint" -ci="travis"
```

### `REVIEWDOG_GITHUB_API_TOKEN`を設定

[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")では、GitHubのPull Requestに書き込むためにGitHubのAPI Tokenが必要です。

[New personal access token](https://github.com/settings/tokens/new "New personal access token")から`repo`に権限を付けたTokenを発行します。

![repo](https://monosnap.com/file/duLWpPrFoqR8uPvOZOniupuiptE1GB.png)

そして、Travis CIの設定に秘密の環境変数として`REVIEWDOG_GITHUB_API_TOKEN=<token>`を設定します。

ウェブ上の画面や`travis`コマンドから環境変数を設定できます。

```
travis env set REVIEWDOG_GITHUB_API_TOKEN 作ったトークン
```

設定できたかは、Travis CIのサイト上や次のコマンドで確認することができます。

```
$ travis env list
# environment variables for azu/textlint-reviewdog-example
REVIEWDOG_GITHUB_API_TOKEN=[secure]
```

これでtextlintで文章をチェックして、Lint結果にエラーがあるなら、そのPull Requestにレビューコメントとして書き込まれます。
書き込みするアカウントは`REVIEWDOG_GITHUB_API_TOKEN`で設定したTokenの持ち主のアカウントになります。

## Pull Requestを出してテストする

実際にPull Requestを出して[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")で怒られている様子を次で見ることができます。

- [docs: Update README by azu · Pull Request #1 · azu/textlint-reviewdog-example](https://github.com/azu/textlint-reviewdog-example/pull/1 "docs: Update README by azu · Pull Request #1 · azu/textlint-reviewdog-example")

[![textlint-reviewdog-example 2017-02-10 23-23-17](https://cloud.githubusercontent.com/assets/19714/22829900/f0ab5cba-efe7-11e6-904f-7eae4e2701ba.png)](https://github.com/azu/textlint-reviewdog-example/pull/1)

## おわり

[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")を使ってTravis CIから指摘内容を書き込む方法を紹介しました。

基本的には[Saddler](https://github.com/packsaddle/ruby-saddler "Saddler")や[pronto-textlint](https://github.com/seikichi/pronto-textlint "pronto-textlint")などを使った方法とそこまで変わらないと思います。

- [Travis CIでtextlintの指摘をPull Requestのレビューコメントとして書き込む - Qiita](http://qiita.com/azu/items/c2305f3dded3fda968e0 "Travis CIでtextlintの指摘をPull Requestのレビューコメントとして書き込む - Qiita")

[reviewdog](https://github.com/haya14busa/reviewdog "reviewdog")はGolang製でバイナリをダウンロードするだけで良いので、依存がシンプルで分かりやすいかもしれないですね。

Circle CIでも同じことができます。
reviewdogの`-ci`引数が異なる程度の違いです。

- [jser.github.io/circle.yml at develop · jser/jser.github.io](https://github.com/jser/jser.github.io/blob/develop/circle.yml "jser.github.io/circle.yml at develop · jser/jser.github.io")