Travis CIでtextlintの指摘をPull Requestのレビューコメントとして書き込む

More than 3 years have passed since last update.

textlintをTravis CIで動かして継続的に文章をチェックする - Qiita

の続き的な話です。

textlintのチェックが失敗したら、Pull Requestのコメントとして書いてくれるものを作る仕組みの話です。

image

一般にLint系をCIで走らせると、どこで失敗したのかを確認しにくくCIまで見に行くのは面倒だし分かりにくいです。

GitHubではレビューコメントで該当行にコメントを書けるので、直接そこへ指摘のコメントある方が良いです。

Houndがまさにそういうサービスですが、任意のツールには対応していません。

Saddlerというツールが同じことをTravis CIやCircle CIから行う事ができます。


.travis.ymlの設定

普通のCIの設定はtextlintをTravis CIで動かして継続的に文章をチェックする - Qiitaにある通りなので、そこまでは既にできているという前提です。

レビューコメントを書き込むタイミングは、テスト失敗(Lint失敗)した時なので、.travis.ymlafter_failureにレビューコメントを書き込むシェルスクリプトを追加します。

sudo: false

language: node_js
node_js: "stable"
after_failure:
- ./.travis/review-textlint.sh

Rubyが必要なので、language: rubyをベースにする場合は以下のように設定できます。

sudo: false

language: ruby
rvm:
- '2.2'
env:
- NODE_JS_VERSION='6'
install:
- nvm install $NODE_JS_VERSION
- nvm use $NODE_JS_VERSION
- npm install
script:
- npm test
after_failure:
- ./.travis/review-textlint.sh

Travis CIにはデフォルトでrubyが入ってる言語は多いので、明示的にrubyを入れなくても動くとは思います。


GitHubのTokenの設定

Travis CIからSaddlerがレビューコメントを書くためには、GitHub Tokenの設定が必要です。

GITHUB_ACCESS_TOKEN=xxx という環境変数が設定されていれば自動的に利用できます。

Personal Access Tokensからrepoの権限を含んだTokenを発行して、コマンドラインからtravisコマンドで次のように設定すれば環境変数が定義されます。

travis env set GITHUB_ACCESS_TOKEN xxx

また、Travis CIの該当リポジトリの設定画面からも設定することができます

setting


review-textlint.sh

review-textlint.shでは、そのPull Requestで変更したファイルのみtextlintでLintしてその結果をPull Requestに書き込んでいます。

Travis CIではgit cloneがshallowであるため、改めて他のブランチなどを取得する作業が必要です(Circle CIでは不要です)。

これをしないと git diff で差分のファイル名取得が上手くできないと思います。

また、Pull Request時以外は実行しないように "$TRAVIS_PULL_REQUEST"で分岐しています。(Circle CIでは CI_PULL_REQUEST を見る必要があります)

#!/bin/bash

# Test if pull request
if [ "$TRAVIS_PULL_REQUEST" = "false" ] || [ -z "$TRAVIS_PULL_REQUEST" ]; then
echo 'not pull request.'
exit 0
fi

# Fetch other branch
# To avoid ambiguous argument
# http://stackoverflow.com/questions/37303969/git-fatal-ambiguous-argument-head-unknown-revision-or-path-not-in-the-workin
if [ "$TRAVIS" == "true" ]; then
#resolving `detached HEAD` by attaching HEAD to the `TRAVIS_FROM_BRANCH` branch
TRAVIS_FROM_BRANCH="travis_from_branch"
git branch $TRAVIS_FROM_BRANCH
git checkout $TRAVIS_FROM_BRANCH

#fetching `TRAVIS_BRANCH` branch
git fetch origin $TRAVIS_BRANCH
git checkout -qf FETCH_HEAD
git branch $TRAVIS_BRANCH
git checkout $TRAVIS_BRANCH

#switch to `TRAVIS_FROM_BRANCH`
git checkout $TRAVIS_FROM_BRANCH
fi

# Install saddler
# https://github.com/packsaddle/ruby-saddler
# Need secret env: `GITHUB_ACCESS_TOKEN=xxx`
gem install --no-document checkstyle_filter-git saddler saddler-reporter-github

# Diff Target Branch
# diff HEAD...target
# http://stackoverflow.com/questions/3161204/find-the-parent-branch-of-a-git-branch
# http://qiita.com/upinetree/items/0b74b08b64442f0a89b9
declare diffBranchName=$(git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -1 | awk -F'[]~^[]' '{print $2}')

# filter files and lint
echo "${diffBranchName}...HEAD"
echo "textlint -> review_comments"
git diff --name-only --diff-filter=ACMR ${diffBranchName} \
| grep -a '.*.md$' \
| xargs $(npm bin)/textlint -f checkstyle \
| checkstyle_filter-git diff ${diffBranchName} \
| saddler report \
--require saddler/reporter/github \
--reporter Saddler::Reporter::Github::PullRequestReviewComment

後はこのファイルを .travis/review-textlint.sh に置いて、実行できるようにchmod +x .travis/review-textlint.shします。

これでレビューコメントとしてLint結果を書き込む事ができるようになりました。

image


参考プロジェクト