Mirrativ Tech Blog

株式会社ミラティブの開発者(バックエンド,iOS,Android,Unity,機械学習,インフラ, etc.)によるブログです

アプリ開発を支える10個のDangerレシピ

 こんにちわ。shogo4405です。普段は、ミラティブで開発しながら、余暇にOSSのHaishinKit*1をつくっています。本エントリーは普段UI開発を行なっているクライアントエンジニア向けに、ミラティブで導入しているDangerの実践レシピを公開いたします。

はじめに

 Dangerとは「Pull Requestの作法を形式化して指摘を自動化」するツールであり、採用している開発者の方も多いのではないでしょうか。Dangerの導入にあたってはDangerで始めるPull Requestチェック自動化 - コネヒト開発者ブログを参考にして導入いたしました。ありがとうございます。

 ミラティブ社でも形式的なチェックは基本的にDangerに任せるにようしています。本エントリーでは、開発現場のあるある指摘内容をレシピ集という形でまとめました。

レシピ1:githubの更新があった箇所のみ指摘する

 定番。githubの更新があった箇所のみDanger指摘するためのレシピです。

github.dismiss_out_of_range_messages

レシピ2:PR担当者を該当PRの起票者に割り当てたい

 開発者がどのようなPRを抱えているのかの把握。リリース後の変更経緯確認などの目的でPRのAssignee機能を活用しています。PRの起票者がPR作成時に自身をアサインするという運用している環境も多いのでは無いでしょうか。PR担当者を割り当てるレシピはこちらです。

## assigneeが未割り当てかのチェック
if github.pr_json['assignee'] == nil
  ## github.api 経由で GitHubの操作可能
  github.api.add_assignees(
    github.pr_json['base']['repo']['full_name'],
    github.pr_json['number'],
    [github.pr_author] ## <- 起票者は github.pr_author
  )
end

レシピ3:masterブランチからhotfixブランチを作成していないことを指摘したい

 GitFlowにおけるホットフィックス対応をつくるとき、間違ってdevelopから切ってしまって危うく事故を起こしかけた経験はありませんか?僕はあります。ブランチがmasterから切られているか確認するためのレシピはこちらです。

# 多くの場合は releaseブランチは例外
unless github.branch_for_head.start_with?('release')
  # ホットフィックス対応時に適切にブランチが切られているか確認する
  if github.branch_for_base == 'master' ||
         github.branch_for_base.start_with?('hotfix')
      # 切り出し基のブランチを取得する
      parent_branch =
        `git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -1 | awk -F'[]~^[]' '{print $2}'`
      if parent_branch != 'master' && parent_branch != github.branch_for_head
        fail(
          '意図しないコードの反映を防ぐため`master`や`hotfix`に対してrebaseしてください。'
        )
      end
  end
end

レシピ4:JIRAのリンクを掲載したい

 機能開発しているときに出した不具合の修正でどの程度対応したか確認できるようにしておくと便利です。関連するJIRAの一覧をリンク表示するレシピはこちらです。

git.commits.each do |commit|
  # コミットメッセージからJIRAの番号を抜き出しています。"MIR-"の部分は自社でお使いのJIRA IDに置き換えてください。
  match = commit.message.match /(MIR-\d+)/ 
  if match
    message(
      ":paperclip: <a href='https://xxx.atlassian.net/browse/#{match[1]}'>#{match[1]}</a>"
    )
  end
end

レシピ5:[WIP] 運用より Draft PullRequest機能を推奨したい

 ついつい[WIP]として使るPRですが、GitHubにはDraft PR機能がありそちらの利用を推奨しています。Draft PRを推奨するためのレシピはこちらです。

  if github.pr_title.include? 'WIP'
    markdown(
      "@#{github.pr_author} タイトルの[WIP]は非推奨です。GitHubのDraft Pull Request機能を使ってください。途中からでもDraftにできます。"
    )
  end

レシピ6:意図しないgit submoduleの更新を防ぎたい

 作業ブランチの行き来をしているうちにgit submoduleの更新に気づかずにデグレしてしまうことがありました。特にUnity*2の更新頻度が高くうっかりミスをすることがありました。git submoduleのうっかり更新を防ぐレシピはこちらです。

  if !git.modified_files.grep("/path/to/submodule/").empty?
    if !github.pr_labels.include? 'Unity'
      fail(
        'Unityのフレームワークを更新する場合は、ラベルにUnityを指定してください。意図せず差分が入ってしまっている場合は、フレームワークの差分を解消してください。'
      )
    end
  end
  • 尚、運用として。GitHubの「任意のラベル」をつけて意図していることを明示してあります

レシピ7:releaseブランチの向き先を指摘したい

 普段はdevelopブランチに向けてPRを作成しているため。つい手ぐせでreleaseブランチをdevelopに向けてしまうことがありました。releaseブランチの向き先がmasterに向いているか確認するレシピはこちらです。

# releaseブランチの確認
if github.branch_for_head.start_with?('release')
  ### master向いているかの確認
  if github.branch_for_base != 'master'
    fail('releaseブランチは、masterへ向けてください。ご対応お願いします。')
  end
else

レシピ8:[iOS] SwiftLint --fix で差分がでることを指摘したい

 ついついSwiftLintをかけ忘れてマージをしてしまい。SwiftLintだけを行うPRを作ったことはありませんか?僕はあります。SwiftLint対象かどうかを確認するためのレシピはこちらです。

# Danger上でSwiftLintを実行して差分のカウントがでるか確認
lintCount =
  `./Pods/SwiftLint/swiftlint --fix 2>&1 | awk '!/^Correcting/' | wc -l | awk '{ gsub(/ /,\"\"); printf }'`
if lintCount != '1'
  warn(
    '`swiftlint --fix`に差分が出ています。マージ前に`./Pods/SwiftLint/swiftlint --fix`を実行してください。'
  )
end

レシピ9:[Android] マルチモジュールに対応したAndroidLint設定をしたい

 MirrativのAndroidはマルチモジュール構成でした。シングルモジュールの構成時ではメインのモジュールのみAndroidLintレポートが取得できずマルチモジュール構成に対応する必要がありました。マルチモジュールに対応したAndroidLint設定のレシピはこちらです。GitHub - loadsmart/danger-android_lint: A Danger plugin for Android Lintの導入をお願いします。

Dir
  .glob('**/lint-results.xml')
  .each do |report|
    android_lint.report_file = report.to_s
    android_lint.skip_gradle_task = true
    android_lint.filtering = true
    android_lint.lint(inline_mode: true)
  end

レシピ10:[Android] マルチモジュールに対応したKtlint設定をしたい

 上記と同様にktlintに対応するレシピはこちらになります。GitHub - noboru-i/danger-checkstyle_format: Danger plugin for checkstyle formatted xml file.の導入をお願いします。

checkstyle_format.base_path = Dir.pwd
Dir
  .glob('**/ktlint/ktlintMainSourceSetCheck/*.xml')
  .each { |report| checkstyle_format.report report.to_s }

おわりに

 是非「#Dangerレシピ」ハッシュタグでつぶやいて。貴社のDangerのレシピを教えてくださいね。

We are hiring!

 ミラティブでは一緒に開発してくれるエンジニアを募集しています!少しでも興味を持っていただいた方はお話を聞いていただくだけでも結構ですので、気軽にご連絡ください。

www.mirrativ.co.jp