DangerでPull Requestの確認を効率化した

この記事は[レコチョク Advent Calendar 2022](https://qiita.com/advent-calendar/2022/recochoku)の23日目の記事となります。

# はじめに

初めまして、新卒2年目の後藤です。
株式会社レコチョクでiOSアプリ開発に携わっています。

自分はスキマスイッチさんが好きで、よくライブにも足を運びます。昨日行われた「スキマスイッチ “Live Full Course 2022” 〜 20年分のライブヒストリー 〜」のライブも最高でした！

現在、タワーレコード株式会社と弊社が共同で開発している音楽サブスクリプションサービスのTOWER RECORDS MUSICのiOSアプリを開発しています。

https://music.tower.jp/

その開発の中で[Danger](https://github.com/danger/danger)というGitHubでのコードレビューを便利にするツールを導入しました。
本記事では、実際に導入しているルールの一部と利用した感想を紹介したいと思います。


# Dangerとは

Dangerとは、Pull Request（以下PR）を提出する際にチェックすべき項目をルール化し、指摘を自動化するツールです。確認するルールはDangerfileというファイルに定義します。
Dangerを使用することで、チェックすべき項目を抜け漏れなく確認でき、コードレビューを効率よく行うことができます。

TOWER RECORDS MUSICのiOSアプリでは、PRを提出した際にBitrise上でビルドを実行しています（Bitriseとはモバイルアプリ開発に特化したCI/CDプラットフォームのことです）。
その中で同時にDangerでのチェックを行い、PRの形式がルールに沿っていなかった場合にGitHub上にコメントで指摘が残るようにしています。

![SwiftLint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279002/98310c1a-1d07-54be-3f00-0ec5705990b8.png)


# 使用しているルール

Dangerfileに記載している内容の一部を紹介します。

## マイルストーンの設定有無のチェック

GitHubで提出するPRにはマイルストーンを設定することができます。
マイルストーンを設定していない場合は指摘します。

```
warn("@#{AUTHOR_NAME} PRにマイルストーンが設定されていないようです。") unless github.pr_json["milestone"] != nil
```

## PRの差分量チェック

PRの差分の行数が一定量を超えた場合に警告を出すこともできます。以下の例では、1000行を超過した場合に警告を出すルールを記述しています。

```
LINES_TO_SPLIT = 1000
modified_lines = git.lines_of_code

if modified_lines > LINES_TO_SPLIT
  warn("PRの変更量が多すぎます。可能であればPRを分割しましょう。")
end
```

## SwiftLintの指摘チェック

Swiftの静的解析ツールに[SwiftLint](https://github.com/realm/SwiftLint)というものがあります。
SwiftLintを使うことで、[特定のコーディングパターン](https://realm.github.io/SwiftLint/rule-directory.html)に該当していた場合、XcodeでRunした時にWarningとして警告を出すことができます。

SwiftLintをDangerで使うためのプラグインに[Danger SwiftLint](https://github.com/ashfurrow/danger-ruby-swiftlint)があります。
Danger SwiftLintを使うことで、SwiftLintで検出されるようなコードがPRの差分に含まれていた場合、GitHub上のコメントとして残すことができます。

また、SwiftLintには開発中に残したTODOコメントを違反パターンとして検出するルールがありますが、TODOコメントへの警告はDangerが指摘しないようにDanger側で対象から除外することもできます。

```
ignored_rule_ids = [
  "todo"
]
swiftlint.config_file = ".swiftlint.yml"
swiftlint.lint_files(inline_mode: true) do |violation|
  !ignored_rule_ids.include?(violation["rule_id"])
end
```

## Visual Regression Testingの実装有無のチェック

[レコチョク Advent Calendar 2022の10日目の記事](https://techblog.recochoku.jp/8669)で「Visual Regression Testingを導入してみた(iOSアプリ)」の内容を紹介しています。

Visual Regression Testing（以下VRT）とは、以下のような内容です（詳しくは記事をご覧ください）。
>特定の時点でのUIのスクリーンショットをピクセル単位で比較し、差分を検知する回帰テストです。

開発の中で、ViewControllerを新規作成する際に、VRTを実装することを必須としています。
例えばHogeViewController.swiftを実装した際に、HogeViewControllerSnapshotTest.swiftが実装されていなかったら指摘を出すようにしています。

このようにすることで、VRTの実装漏れを防ぐことができます。

```
ADDED_FILES = git.added_files

ADDED_FILES.each do |filename|
  if filename.end_with?("ViewController.swift") then
    snapshot_test_view_controller_name = File.basename(filename, ".swift") + "SnapshotTest.swift"
    next if !ADDED_FILES.grep(/#{snapshot_test_view_controller_name}/).empty?
    warn("#{snapshot_test_view_controller_name}を作成する必要がありそうです。")
  end
end
```

## 設定ファイルの変更有無のチェック

開発をしていると様々な設定ファイルを変更することがあります。
しかし、これらを不用意に変更すると開発環境を破壊しかねないため、注意深くレビューする必要があります。
そのため、これらを変更している場合にメッセージを出すことで、レビュアにリマインドをしています。

```
SETTING_FILES =["Podfile", "Makefile", "Dangerfile", "Gemfile", "swiftgen.yml", ".gitignore", ".swiftlint.yml"]

PROTECTED_FILES.each do |filename|
  next if MODIFIED_FILES.grep(/#{filename}/).empty?
  message("#{filename}に変更が加えられています。")
end
```

# 終わりに

本記事では、Dangerで使用しているルールの一部を紹介しました。

Dangerを導入した結果、「マイルストーンが設定されているか」などの実装に関係ない箇所の指摘をなくすことができました。また、SwiftLintの違反パターンに該当したままコードレビューを依頼したり、VRTの実装が漏れたりすることを防げるようになりました。

これからも指摘を自動化できる仕組みを増やし、プロダクトの品質に直接関わるような部分のレビューに時間をかけるようにしていきたいです。

明日の[レコチョク Advent Calendar](https://qiita.com/advent-calendar/2022/recochoku)は24日目「Swift 5.7の新機能を用いて、複数サービスを扱うアプリをリアーキテクチャする」です。お楽しみに！

---

この記事はレコチョクのエンジニアブログの記事を転載したものとなります。

https://techblog.recochoku.jp/8938