26
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ViibarAdvent Calendar 2015

Day 9

pull requestした差分にrubocopの結果を自動でコメントしてCircleCIをfailedにするよ

Posted at

Viibar社員でもないのにまた登場しました @nifuramu です。おっすおっす〜〜〜

変更したファイルにrubocopやjscsを実行して pull requestに自動でコメントする

に少しだけ手を加えてCircleCIをfailedにして直すまでマージ阻止だ!!!って感じの内容です。

必要とするGem

  gem 'rubocop'
  gem 'rubocop-select'
  gem 'rubocop-checkstyle_formatter'
  gem 'saddler'
  gem 'saddler-reporter-github'
  gem 'checkstyle_filter-git'

ベースとなるスクリプト

#!/bin/bash
if [ "${CIRCLE_BRANCH}" != "master" ]; then
    git diff -z --name-only origin/master \
    | xargs -0 bundle exec rubocop-select \
    | xargs bundle exec rubocop \
        --require rubocop/formatter/checkstyle_formatter \
        --format RuboCop::Formatter::CheckstyleFormatter \
    | bundle exec checkstyle_filter-git diff origin/master \
    | bundle exec saddler report \
        --require saddler/reporter/github \
        --reporter Saddler::Reporter::Github::PullRequestReviewComment
fi

exit 0

こちらに手を加えて行くます。

方針

rubocopを実行した結果、何かしらエラーが発生したら exit 1 してCircleCIの結果をfailedにする。

Step1

まずはrubocopが何かしらの警告があるかどうかを調べ、その後にpull request送信、そしてfailという処理を愚直に書いてみる。

#!/bin/bash
if [ "${CIRCLE_BRANCH}" != "master" ]; then
    warn=$(git diff -z --name-only origin/master \
           | xargs -0 bundle exec rubocop-select \
           | xargs bundle exec rubocop)
           
    if [ -n "$warn" ]; then
        echo "$warn" \
        | bundle exec rubocop \
            --require rubocop/formatter/checkstyle_formatter \
            --format RuboCop::Formatter::CheckstyleFormatter \
        | bundle exec checkstyle_filter-git diff origin/master \
        | bundle exec saddler report \
            --require saddler/reporter/github \
            --reporter Saddler::Reporter::Github::PullRequestReviewComment
        exit 1
    fi
fi

exit 0

このままではhtmlやcssなどrubyに関係のない変更があった場合やそもそも何も警告がなかった場合でも $warn

1 file inspected, no offenses detected

という値となりifの中のスクリプトが実行されてしまうので、何かしらの警告があった場合のみに対応する。

Step2

Offenses: が存在すればrubocopが何かしらの警告を出しているはずなので、$warn をgrepして存在した時のみ実行するようにした。

#!/bin/bash
if [ "${CIRCLE_BRANCH}" != "master" ]; then
    warn=$(git diff -z --name-only origin/master \
           | xargs -0 bundle exec rubocop-select \
           | xargs bundle exec rubocop)
           
    detected=$(echo "$warn" | grep "Offenses:")
    if [ -n "$detected" ]; then
        # fail処理
    fi
fi

exit 0

Step3

rubocop-selectで対象となるファイルが存在しない場合は bundle exec rubocop しなくてよいのでxargsコマンドに--no-run-if-emptyオプションをつけてrubocopを実行しないようにする

#!/bin/bash
if [ "${CIRCLE_BRANCH}" != "master" ]; then
    warn=$(git diff -z --name-only origin/master \
           | xargs -0 bundle exec rubocop-select \
           | xargs --no-run-if-empty bundle exec rubocop)
           
    detected=$(echo "$warn" | grep "Offenses:")
    if [ -n "$detected" ]; then
        # fail処理
    fi
fi

exit 0

完成形

#!/bin/bash
if [ "${CIRCLE_BRANCH}" != "master" ]; then
    warn=$(git diff -z --name-only origin/master \
           | xargs -0 bundle exec rubocop-select \
           | xargs --no-run-if-empty bundle exec rubocop)
           
    detected=$(echo "$warn" | grep "Offenses:")
    if [ -n "$detected" ]; then
        echo "$warn" \
        | bundle exec rubocop \
            --require rubocop/formatter/checkstyle_formatter \
            --format RuboCop::Formatter::CheckstyleFormatter \
        | bundle exec checkstyle_filter-git diff origin/master \
        | bundle exec saddler report \
            --require saddler/reporter/github \
            --reporter Saddler::Reporter::Github::PullRequestReviewComment
        exit 1
    fi
fi

exit 0

CircleCIで実行できるようにする

スクリプトに実行権限をつける

上記スクリプトを適当な名前で保存し、実行権限をつける。今回はrun-rubocop.shとして保存しました。

$ chmod a+x run-rubocop.sh

cicle.ymlの設定

circle.ymlに設定を追加

circle.yml
test:
  post:
    - run-rubocop.sh

GitHubアクセストークンを取得してCicleCIへ保存

Saddler::Reporter::Github:: PullRequestReviewComment はGitHubのアクセストークンがないと動かないのでPersonal access tokensからトークンを取得します。

取得したトークンをCircleCIのProject SettingsページのEnvironment variablesにて GITHUB_ACCESS_TOKEN という名前で保存します。

以上でpull requestした差分にrubocopの結果を自動でコメントしてCircleCIをfailedが完成です!

84ca3f43ea0ec4d7ccb315cad10cb9e1.png

なお、こちらの元ネタは @shrkw がViibar社で対応したものをちょろっといじったものとなります。手柄を横取りしたった!

あとこんな事しないでもSideCI使えばいいんじゃないかなーと思いました。

26
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?