こんにちは、 Classi でソフトウェアエンジニアやってます koki です。
この記事では、 Renovate によって Classi の社内向け npm package を自動アップデートさせるために行った設定についてまとめます。
概要
Classi では、社内向けの共通ライブラリや Docker イメージなどを GitHub Packages で管理しています。
この GitHub Packages の利用により、それらのプライベートなパッケージを社内の様々なシステムから安全且つ効率的に利用することを実現しています。
例えば、今年の 6 月にプレスリリースが出された学習トレーニング機能を裏で支えているコンテンツ管理システムで利用している GraphQL Schema は GitHub Packages の npm registry でプライベートな npm package として管理しています。
こちらについて詳しくは下記記事をご参照ください。
また、各システムの GitHub リポジトリでは依存ライブラリの自動アップデートのために Renovate を利用しています。 下記記事では Renovate が作成したライブラリアップデートの PR のマージを自動化した仕組みについても解説していますので、よければこちらもご参照ください。
Renovate はデフォルトではプライベートな GitHub Packages への参照権限を持っていません。 そのため、社内向け npm package に依存しているリポジトリの Renovate Dashboard には次のような Warning が表示されます。
Renovate failed to look up the following dependencies: Failed to look up npm package <パッケージ名>
上記の Warning を解消するための Renovate の設定をしていきます。
設定手順
Renovate 用の Personal Access Token ( Classic ) を発行する
Renovate にプライベートな GitHub Package を読み取らせるためには、まず Personal Access Token を発行する必要があります。 2023 年 10 月時点で Fine-grained token は GitHub Packages に対応していないため、トークンの種類は Classic を選択する必要があることに注意してください。
必要な権限は次の通りです。
repo
read:packages
Personal Access Token を暗号化する
先ほど発行した Personal Access Token は暗号化した上で設定ファイルに埋め込む必要があります。 下記ページを使用して Personal Access Token を暗号化することができます。 ( ここで暗号化したトークンは Renovate のみが復号できます。詳細については後述の「暗号化済みトークンをハードコーディングして大丈夫なの?」をご参照ください。 )
項目 | 値 |
---|---|
Organization |
GitHub Organization 名 |
Repository (Optional) |
暗号化済みトークンを使用できるリポジトリ名 省略した場合は Organization 内の全てのリポジトリから暗号化済みトークンを使用できる |
Raw Value |
「Renovate 用の Personal Access Token ( Classic ) を発行する」手順で発行した Personal Access Token |
それぞれ入力して Encrypt
をクリックすると Encrypted value
に暗号化されたトークンが表示されます。
この値は後ほど Renovate の設定に使用するため、控えておきます。
Renovate の設定を作成
続いて Renovate の設定ファイルを作成します。
次のような内容で renovate.json
を作成します。
{ "hostRules": [ { "matchHost": "https://npm.pkg.github.com/", "hostType": "npm", "encrypted": { "token": "<ENCRYPTED_PERSONAL_ACCESS_TOKEN>" } } ], "npmrc": "@<ORGANIZATION_NAME>:registry=https://npm.pkg.github.com/" }
<ENCRYPTED_PERSONAL_ACCESS_TOKEN>
: 「Personal Access Token を暗号化する」手順で取得した暗号化済みトークン。<ORGANIZATION_NAME>
: GitHub Organization 名。
この設定を GitHub に push して Renovate を再実行することで、 Renovate により GitHub Packages の npm package を自動アップデートできるようになります。
設定ファイルを分ける場合
先ほど作成した設定ファイルは renovate.json
ではなく別のファイルに分けたい場合もあると思います。
例えば、「Renovate の設定を作成」手順で作成した JSON を renovate-github-packages.json
という名前で保存する場合、 renovate.json
の extends
に次のように追記します。
{ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ // ...その他の設定, + "local><ORGANIZATION_NAME>/<REPOSITORY_NAME>:renovate-github-packages", ], // ...その他の設定 }
<ORGANIZATION_NAME>
: GitHub Organization 名。<REPOSITORY_NAME>
: リポジトリ名。
こうすることで renovate.json
から renovate-github-packages.json
を読み込むことができます。
設定ファイルの共有方法について詳しくは下記ドキュメントをご参照ください。
Appendix
これらの設定は必要なくなるかも ( GitHub Packages を使用している場合 )
GitHub Packages への参照権限を自動で設定する機能が Renovate に追加されたようです。 これにより、この記事で紹介した手順は不要になるかもしれません。
- Support automatic GitHub Packages permissions with platform token · Issue #17705 · renovatebot/renovate
- feat(github): set package registry credentials automatically by rarkins · Pull Request #25214 · renovatebot/renovate
ただしこれはあくまで GitHub Packages でパッケージを管理している場合なので、 npmjs.org 等のレジストリを使用してプライベートなパッケージを管理している場合は引き続きこの記事と同じような手順で適切な認証トークンを暗号化して設定ファイルに埋め込む必要があります。
暗号化済みトークンをハードコーディングして大丈夫なの?
先ほど紹介した下記ページを使用することで、 Personal Access Token は Renovate の公開鍵を使用して暗号化されます。
この方法で暗号化されたトークンは Renovate のみが復号できる = Renovate 用途でしか使えません。 暗号化済みトークンを使用できる Organization と Repository も制限できるので、暗号化済みトークン自体はもし漏洩しても大きな問題はありません。 特に Organization は必須項目なので、少なくとも組織外のリポジトリから使うことはできません。
とはいえ、万が一 Renovate 側に悪い人がいたり秘密鍵漏洩等のセキュリティインシデントが発生したりした場合は Personal Access Token が漏洩する可能性はもちろんあります。
そうなったら、かなり広い権限 ( 特に repo
Scope ) を持っている Personal Access Token なので結構大変です。
なので「Renovate には専用の Personal Access Token を割り当てて他のものを流用しない」等の運用を行い、万が一何かがあったときにすぐ Revoke できるようにしておくことが大切です。