textlintをTravis CIで動かして継続的に文章をチェックする - Qiita
の続き的な話です。
textlintのチェックが失敗したら、Pull Requestのコメントとして書いてくれるものを作る仕組みの話です。
一般にLint系をCIで走らせると、どこで失敗したのかを確認しにくくCIまで見に行くのは面倒だし分かりにくいです。
GitHubではレビューコメントで該当行にコメントを書けるので、直接そこへ指摘のコメントある方が良いです。
Houndがまさにそういうサービスですが、任意のツールには対応していません。
Saddlerというツールが同じことをTravis CIやCircle CIから行う事ができます。
- 変更したファイルにrubocopやjscsを実行して pull requestに自動でコメントする – Saddler - checkstyle to anywhere
- packsaddle/ruby-saddler
.travis.ymlの設定
普通のCIの設定はtextlintをTravis CIで動かして継続的に文章をチェックする - Qiitaにある通りなので、そこまでは既にできているという前提です。
レビューコメントを書き込むタイミングは、テスト失敗(Lint失敗)した時なので、.travis.yml
のafter_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の該当リポジトリの設定画面からも設定することができます
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結果を書き込む事ができるようになりました。