PHPプロジェクトのComposerパッケージをRenovateで定期アップデートする

こんにちは！ @takoba といいます。 [9日目](https://qiita.com/takoba/items/8f2d231303bcfdfd50bd) に続いて登場です🍛
改めて自己紹介すると、現在は [コネヒト株式会社](https://connehito.com/) でサーバーサイドを主戦場にしたエンジニアとして働いています。 CakePHP を主に触っています〜〜🙋‍♀️

このエントリは、 [PHP Advent Calendar 2021](https://qiita.com/advent-calendar/2021/php) の19日目のエントリです。
18日目は @tzmfreedom さんによる [PHPからGoを呼び出す方法](https://tech.yappli.io/entry/php_go) でした。


## 前提

### Renovate is 何
[WhiteSource Renovate](https://renovatebot.com/) は各種アプリケーションプロジェクトの依存パッケージを自動でアップデートするためのツールです。トップページには、

> Save time and reduce risk by automating dependency updates in software projects.

といったように、「ソフトウェアプロジェクトの自動依存パッケージアップデートによって、時間を節約しセキュリティリスクを軽減します」と記されています。 Renovate は [2019年11月 WhiteSource に買収](https://twitter.com/teppeis/status/1198828047861829635) されたこともあって、プライベート repo でも無料で使えるツールとなりました。

ちなみに実装は [renovatebot/renovate](https://github.com/renovatebot/renovate) にあります。  Renovate は TypeScript で実装されていて、割と実装も一通り読めるかんじになっています。

npm でパッケージ管理している JavaScript / TypeScript のプロジェクトにおいては、導入は簡単です。設定を記述する REPO_ROOT/renovate.json に以下のように書けばよしなに動きます。便利〜〜〜🙌

```json
{
  "extends": ["config:base"]
}
```

### 過去に一度調べたんですが、Composerパッケージのアップデートツールとしては要件を満たせなかった
そんな Renovate なんですけど、実は2020年3月に一度 PHP プロジェクトにおける Renovate の採用を見送った経緯がありました。

理由は、（GitHubのプライベートrepoなどの）認証が必要なhostにアクセスするための情報を renovate.json にベタ書きしなくちゃいけなくて、ちょっとセキュアではないな〜〜となったためです。

cf. [RenovateでPrivate Packagistを使いたい \- 角谷鵜技術五十三次](https://scrapbox.io/kadoyau/Renovate%E3%81%A7Private_Packagist%E3%82%92%E4%BD%BF%E3%81%84%E3%81%9F%E3%81%84)

### 時は2021年12月、Renovateが最強のパッケージアップデートツールとなった
しかし、1年半以上の時が経ち、 2021年11月に改めて調べたところ、 **公式に `hostRules` という hostname に応じた設定を書くプロパティに、暗号化したパラメータを埋め込めるような対応** がなさてれました！

cf. [Private packages | PHP Composer Support \- Renovate Docs \| Renovate Docs](https://docs.renovatebot.com/php/#private-packages)

Renovate は多彩なパッケージ管理ツールに対応しているところや、 renovate.json での多彩な表現方法を用いることができるところなど、他の自動パッケージアップデートツールに比べても「これを用いれば便利に活用できる〜〜」と思い、本腰を入れて調べることを決意しました。


## 結局どんなかんじになったか

結論、以下のような設定になりました。 `extends` は `"config:base"` という便利な preset から必要なものだけを抜き出すかんじにしました。

```json
{
  "timezone": "Asia/Tokyo",
  "extends": [
    ":dependencyDashboard",
    ":ignoreModulesAndTests",
    ":autodetectPinVersions",
    ":prHourlyLimit2",
    ":prConcurrentLimit10"
  ],
  "packageRules": [
    {
      "matchManagers": ["composer"],
      "matchUpdateTypes": ["patch", "minor", "major"],
      "matchDepTypes": ["require", "require-dev"],
      "groupName": "Composer dependencies",
      "groupSlug": "composer-dependencies",
      "extends": ["schedule:weekly"],
      "reviewers": ["takoba", "team:devs"],
      "labels": ["dependencies"]
    }
  ]
}
```

今回は、簡単に Composer パッケージをまとめてひとつの Pull Request にする技をご紹介します。


## Composer パッケージをまとめてアップデートする設定
renovate.json では、 `packageRules.groupName` をつけてあげることで、グループ化が可能になります。

とある repo で実際に設定してみたのがこんなかんじです。`packageRules.groupName` がタイトル（`"Update ${packageRules.groupName}"`）に作用するし 、 `packageRules.groupSlug` がブランチ名で `"renovate/${packageRules.groupSlug}"` ってかんじに作用します。
![7b215718d69e2a555d469f183311eba8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9856/c0371846-bf15-ee5e-85d6-bd11b8646c1d.png)

最初は上記の画像みたく `require` と `require-dev` を分ける戦略にしようとしてたんですが、よくよく考えたら composer.lock はひとつしかないし、 composer.lock の依存関係が複数のPRで管理することになってconflictが起きやすいじゃん、と思い、まとめることにしました。

とはいえ、実は group をまとめていても depType が `"patch"` と `"minor"` のやつと `"major"` のやつで分けてくれる戦略に自動でなってる（たぶん `"rangeStrategy": "auto"` のおかげだと思う）ので、そこは気が利いたかんじになってるはずです〜〜🙌

## [PR] 詳しい話はコネヒト社のテックブログで書くよ！

この辺、掘り下げていくといろんな話が出てきたので、三部作くらいにまとめられそうだな〜〜という気持ちになっています！例えば `"config:base"` って具体的にどういう preset になってるの？とか、具体的にプライベートなパッケージの `hostRules` をどう書くの？？とか📝

以上は、来月あたりに [コネヒト社のテックブログ](https://tech.connehito.com/) でご紹介しようかな！と思ってるので要チェックや！:eyes:


## おわりに
実際に、上記で紹介したような renovate.json をそのまま導入してみると、割とサクッと導入完了できるので、ぜひ利用してみてね！🙋‍♀️
（そのままサクッと導入しちゃうと @[takoba](https://github.com/takoba) にレビューが飛んでくることになりかねないので、それだけ気をつけてね🙏）

明日は @ockeghem さんのエントリです！おたのしみに〜〜👋


## [PR] 最後に宣伝

[コネヒト株式会社](https://connehito.com/) では [ママリ](https://mamari.jp/) を中心に「あなたの家族像が実現できる社会をつくる」ためのプロダクトを鋭意開発しております！
サーバーサイドは CakePHP とか Go で書いていることが多いのですが、このあたりをぼくらと一緒にバリバリ進めてくれるエンジニアを大募集しています〜〜🙏

興味のある方がいらっしゃれば、以下からご応募いただくか、 Twitter で [@takoba_](https://twitter.com/takoba_) までご連絡いただけますと幸いです🤝

- [PHPとAWSでユーザーを支えるサービスをつくるバックエンドエンジニア募集！ \| コネヒト株式会社](https://hrmos.co/pages/connehito/jobs/00b)
- [家族向けサービス運営テックカンパニーをさらにデータドリブンな組織へと導いてくれる、サーバーサイドエンジニア募集！ \| コネヒト株式会社](https://hrmos.co/pages/connehito/jobs/00k)

また、コネヒト社のメンバーが執筆している [コネヒト Advent Calendar 2021](https://qiita.com/advent-calendar/2021/connehito) もぜひチェックしてくれよな！🙏


## 参考
- [renovatebot/renovate: Universal dependency update tool that fits into your workflows\.](https://github.com/renovatebot/renovate)
- [Teppei SatoさんはTwitterを使っています 「WhiteSourceがRenovateを買収。privateレポもオンプレ版も無料になった。今後はBitbucket, Azure DevOpsへの対応や、WhiteSourceのラインナップに参加、エンタープライズサポートなどが計画されている / “Renovate is now part of WhiteSource \- WhiteSource” https://t\.co/EiHGQ4rq3Q」 / Twitter](https://twitter.com/teppeis/status/1198828047861829635)
- [Renovateによるnpmパッケージ定期更新 \- 一休\.com Developers Blog](https://user-first.ikyu.co.jp/entry/2018/05/07/193755)
- [RenovateでPrivate Packagistを使いたい \- 角谷鵜技術五十三次](https://scrapbox.io/kadoyau/Renovate%E3%81%A7Private_Packagist%E3%82%92%E4%BD%BF%E3%81%84%E3%81%9F%E3%81%84)
- [Renovate を取り入れて、バージョンアップを自動化しました \- TORANA TECH](https://tech.torana.co.jp/entry/2021/07/16/110139)