Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

Rubyアプリのコードレビューを支えるsaddler

こんにちは、むらはし こと sanemat です。 rubocopをコード増分だけに適用して通知したい。lintを増分だけ掛けたい。あると思います。

曰く「増分だけに対応してほしい」 曰く「テスト遅くなるのは嫌だ」 曰く「引っかかってもテストは落ちないで欲しい」 卜部「大量にwarningでるとやる気が尽きるのでは」

いやーテキ屋とサクラかな、とおもった。 rubocopを増分だけに適用してGitHubのpull requestに通知する、便利なツールがあります。  

rubocopを増分だけに適用してGitHubのpull requestに通知する、便利なツール

こんな感じに通知できます。

overcommitでもいいんだけど、bundlerなどで固定してるバージョンで、やりたいですね。

マネーフォワードではCIにJenkinsを使っているので、ここではJenkinsです。設定はCI as a Serviceのほうが便利なのですが、金突っ込んだら強いマシンが使えるのでJenkinsは強い。あとGitHub pull request builder pluginアリを前提にします。

さて、jenkins上では、コミット差分でdiff取りたい。CI用に直接sedなどで設定書き換えてたりもあるし。ローカルでは、コミット前のものも検出したい。

では、こちらでどうでしょう。

#!/bin/bash
# Usage:
#
# on Jenkins (post build task on post build actions)
#
# ```
# cd path/to/project
# NOTIFY_TO_PULL_REQUET="./notify-to-pull-request.sh"
# if [ -f $NOTIFY_TO_PULL_REQUET ]; then
#   bash $NOTIFY_TO_PULL_REQUET
# fi
# ```
#
# Add access token. E.g. Environment Injector Plugin
# GITHUB_ACCESS_TOKEN=write_your_access_token_here
#
#
# on local
# NOTE: This is too slow, please use editor's checker or IDE's one.
# ```
# NOTIFY_BASE=upstream/release bash ./notify-to-pull-request.sh
# ```
#
# Dependencies:
#
# Gemfile
# group :development, :test do
#   gem "checkstyle_filter-git", require: false
#   gem "rubocop", require: false
#   gem "rubocop-checkstyle_formatter", require: false
#   gem "rubocop-select", require: false
#   gem "saddler", require: false
#   gem "saddler-reporter-github", require: false
# end

set -eu

# http://qiita.com/ngyuki/items/b2e291e07f6d2b2c353e
if [ -n "${JENKINS_URL-}" ]
then
  NOTIFY_BASE=origin/$ghprbTargetBranch
  DIFF_RANGE=$NOTIFY_BASE..
  SADDLER_ARGS=' --require saddler/reporter/github --reporter Saddler::Reporter::Github::PullRequestReviewComment'
else
  DIFF_RANGE=$NOTIFY_BASE:./
  SADDLER_ARGS=' --require saddler/reporter/text --reporter Saddler::Reporter::Text'
fi

TARGET_FILES=$(git diff -z --name-only $DIFF_RANGE \
             | xargs -0 bundle exec rubocop-select)

if [ "${TARGET_FILES}" == "" ]; then
  echo "no rubocop target found"
  exit 0
fi

git diff -z --name-only $DIFF_RANGE \
  | 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 $DIFF_RANGE \
  | bundle exec saddler report $SADDLER_ARGS

ローカルではこんな感じに実行する。 $ NOTIFY_BASE=upstream/release bash ./notify-to-pull-request.sh 起動おっそ! ローカルはエディタやIDEでチェックしてください。

jenkins上では post build actionsのpost build taskで

cd path/to/project
NOTIFY_TO_PULL_REQUET="./notify-to-pull-request.sh"
if [ -f $NOTIFY_TO_PULL_REQUET ]; then
  bash $NOTIFY_TO_PULL_REQUET
fi

こんな感じで。

Environment Injector Plugin かなにかでaccess tokenをつっこんでおく。 GITHUB_ACCESS_TOKEN=write_your_access_token_here

jenkinsのプラグイン周りに思ったより苦戦しましたね。まだ動かないケースあるようです。すまん。 fatal: Not a valid object name (Git::GitExecuteError) on Jenkins · Issue #44 · packsaddle/ruby-saddler  

展望

xargs

xargs 使ってるので、必然mac or linuxなのはのちのち。

gitlab

gitlab? おっ そうだな。 マネーフォワード社は多くのプロダクトはGitHubに移行済み。いくつかのプロダクトはセキュリティ要件的に自社Gitlabなので、reporter作らないと。reporterだけ作ればいけるはずだけど、gitlabのapiドキュメントまだ読んだこと無いのでまたいつか。

手作業

botを確認するのにリリース前にあちこち手作業で確認している(!) のは何を言っているかわからないので、いい感じに確認できるようにしたい。そろそろgithub hook受けられる確認用の割とまっさらなjenkins server立てようかと。

test

めっちゃテスト書きにくいところはテスト書いてないので変更がツライ。  

参考URL

以上デース  

最後に

マネーフォワードでは、botが気になって夜しか眠れないエンジニアを募集しています。 ご応募お待ちしています。

【採用サイト】 ■マネーフォワード採用サイトWantedly | マネーフォワード

【プロダクト一覧】 ■家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 iPhone,iPad家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 Androidクラウド型会計ソフト『MFクラウド会計』クラウド型請求書管理ソフト『MFクラウド請求書』クラウド型給与計算ソフト『MFクラウド給与』経費精算システム『MFクラウド経費』消込ソフト・システム『MFクラウド消込』マイナンバー対応『MFクラウドマイナンバー』創業支援トータルサービス『MFクラウド創業支援サービス』お金に関する正しい知識やお得な情報を発信するウェブメディア『マネトク!』