Help us understand the problem. What is going on with this article?

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

参考プロジェクト

azu
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away