【Ruby on Rails】Gemの依存関係を監視させる　～ GitHub Dependabot ～

# 環境

Rails 6.1.4
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
Amazon Linux2
# Dependabotとは

Gem(パッケージ)の依存関係を更新してくれます！

具体的には…
1. Gem側でバージョン更新される(gem'otinu'1.22 から gem'otinu'1.3がリリースされる等)
2. DependabotがGemの更新を検知
3. 更新されたGemに関連するその他のGemも含め、確認をする
4. 確認後、更新された内容をGitHubのプルリクエストとして上げてくれる

数か月Gem放置して、あるときbundle叩いたらアプリが動かない…??
Gemのバージョン管理が大変だから今まで放置してしまってた!!

特にGemの入り組んだRailsは想像に難くないですね…。

そんな問題をDependabotは大幅に改善してくれます！

---

# 2種類のDependabot

**「Dependabotを知ったばかり」の方、必見**ですので前置きとしてご紹介します。

ネット上の色々な記事を見てみると、どうやら現在の世の中には2種類のDependabotがあるようです。

理由は[Dependabot](https://dependabot.com/)が**GitHubに買収された**とのこと。
(リンク先、最下行)

2021/08/11現在 Dependabotには
1. 買収前Ver
2. 買収後ver

2種類が存在する様子です。

この2種類のうち、①は8月に使えなくなるようで、①を使っていたユーザーは②への移行が必要とのことです。

<font color="red">この関係で公式ドキュメントやネット上の投稿記事にも新旧Dependabotの記事が入り混じっていました。</font>
この時点までお読みの方は、Dependabotについて他の記事を検索する際もこの点はお気をつけください。

無難なのはGitHub(買収後)の公式ドキュメントを参照されるのがよろしいかと思います！
[依存関係の更新の設定オプション - GitHub Docs](https://docs.github.com/ja/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates#ignore)

---

### 手順

①GitHubのご自身のリポジトリから、上部タブの「Insights」を選択
②サイドバーより「Dependency graph」を選択
③画面中央部のタブより「Dependabot」を選択
④画面中央の緑色ボタン「Enable Dependabot」をクリック
![](https://i.imgur.com/drsEH3I.png)
⑤緑色ボタン「Create config file」をクリック
![](https://i.imgur.com/YFMgL1Q.png)

⑥ここで、Dependabot用のYMLファイルにコードを記述します。

「とりあえず、Dependabotを入れたい」方は後述の【記述した内容】をご参照ください！

ーーーーー

⑦YMLファイルの記述が終わりましたら、「dependabot」を作成します。
今回の場合、YMLファイルに`target-branch: "dependabot"`と記述をしたため、このブランチがないとDependabotは「dependabotブランチがないよ」と、エラーを返します。
![](https://i.imgur.com/P91r6oB.png)

⑧再度、GitHubの画面から手順③～⑤の画面に戻ると「Gemのアイコン + 'bundler'」と中央バー左端に表示され、反対の右端がリンクになっているので、クリックします。

![](https://i.imgur.com/q1FQXha.png)

⑨画面中央、赤色領域内のボタン「Check for updates」をクリック
![](https://i.imgur.com/iRiiRCG.png)

⑩何も問題がなければ、下記のような画面が表示されます。
今後は依存関係の更新をDependabotが検知した際にプルリクエストを発行してくれます。
![](https://i.imgur.com/aG7pcaz.png)

⑪実際にDependabotが機能してポートフォリオにプルリクエストを発行してくれました。
今回はBootstrapをバージョン4.6から5.1にバージョンアップをする内容でした。
<font color="gree">テスト</font>用のトピックブランチで<font color="gree">確認したところ、レイアウトが大幅に崩れ、ハンバーガーメニューが動かなかった</font>ので、承認を却下しました💦

![](https://i.imgur.com/L6uIOL9.png)

![](https://i.imgur.com/agXnlIw.png)

⑪(注意点)
もし、⑪のように2回目のプルリクエストを却下した場合は1回目のプルリクエスト承認をなかったことにする(Revert)必要があります。
プルリクエストの履歴を辿っていただき、Revertボタンをクリックします。
![](https://i.imgur.com/AzBbkTT.png)

#### 注意点

手順⑩の後の説明となりますが、今回の記述内容では1回目のプルリクエストはそのまま承認しても、本命ブランチには何も影響がありません。
1回目のプルリクエストを承認後、2回目のプルリクエストとして「dependabotブランチを本命ブランチとマージしますか？」との旨が発行されます。
2回目のプルリクエストを許可する前に、<font color="red">1回目のプルリクエストを承認したdependabotブランチ</font>をご自身のテスト環境などに<font color="red">クローンして、テストすることを推奨</font>致します。

GitHubもバージョン戦略(`versioning-strategy`)を用意しているように、「Dependabotがあればパッケージの依存関係はもう放置で大丈夫」という訳ではありません。
一生懸命作ったアプリケーションが大事にならないように、<font color="red">最後には人の目で確認する</font>ことが不可欠です。

---

### 記述した内容

今回は制作したポートフォリオで記述した内容を使用しました。

```yaml
version: 2
updates:
  - package-ecosystem: "bundler"
    directory: "/"
    target-branch: "dependabot"
    open-pull-requests-limit: 10
    versioning-strategy: increase
    schedule:
      interval: "daily"
      timezone: "Asia/Tokyo"
    ignore:
      - dependency-name: "rails"
        update-types: ["version-update:semver-major"]
      - dependency-name: "puma"
        update-types: ["version-update:semver-major"]
```

<br>
`target-branch: "dependabot"`
初めから本命ブランチにプルリクエストを発行することはせず、指定したトピックブランチ(今回はdependabotブランチ)にプルリクエストが発行されるようにします。
この場合であれば、仮にdependabotブランチへのプルリクエストを承認しても本命ブランチにマージしなければ問題はありません。


`open-pull-requests-limit: 10`
プルリクエストの発行数の上限を設定します。AWS関連のGemなど更新頻度の高いGemを入れていると、プルリクエストもドンドン溜まっていくので、ある程度の数で抑えるようにしています。

`versioning-strategy: increase`
RailsやPumaといった主要なGemの更新をマイナーバージョンのみにした関係でDependabotが余り動かないのではないかと考えました。
Dependabotがしっかりと動作することを確認する目的で、頻繁にプルリクエストを発行してくれるであろう、`increase`をバージョン戦略に選びました。

```yaml
ignore:
      - dependency-name: "rails"
        update-types: ["version-update:semver-major"]
      - dependency-name: "puma"
        update-types: ["version-update:semver-major"]
```
railsとpumaのメジャーバージョン(5.xから6.xなど)の更新を無効にしたのは、私事です。
皆様のプロジェクトにもよると思いますが、できればRailsやPumaそのものもメジャーバージョン管理をするのがベターかと思います。

<br>

ちなみに、下記の記述をするか検討しましたが、記述はしませんでした。
`insecure-external-code-execution: deny`

[Dependabotの詳細設定(公式)](https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates)を見る限り、デフォルトはallowになっていて、これを明示的に拒否設定にすることで悪意あるGemなどを遮断してセキュリティ面が向上できるのかと自分なりに読み解きました。
ただし、この場合だと自動更新に失敗する可能性があるとのことです。

餅は餅屋。Gemのセキュリティチェックといった部分はRubyGemsさんにお任せしようと考えました。

---

### 参考にさせていただいたサイト
[Dependabot 導入 - Qiita](https://qiita.com/ty_1592/items/a8c325b5a316bd285169)

[DependabotをGitHub公式Dependabotに移行させた - Hack Your Design!](https://blog.toshimaru.net/github-dependabot/)

[依存関係の更新の設定オプション - GitHub Docs](https://docs.github.com/ja/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates#ignore)

[Dependabotの詳細設定(公式)](https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates)

[Dependabot](https://dependabot.com/)

[Dependabot Preview を Github 公式版に移行してみた | giftee engineer blog](https://blog.giftee.dev/2021-05-17-migrate-dependabot-to-github-native-version/)

[Dependabotのバージョンアップデートでメジャー/マイナー/パッチリリースを無視できるようになりました| GitHub変更ログ](https://github.blog/changelog/2021-05-21-dependabot-version-updates-can-now-ignore-major-minor-patch-releases/)