新規リポジトリにRenovateを入れるたびにOnboarding PRを開いて、extendsに組織共通プリセットへの参照を1行足す運用にうんざりして、Mend-hostedのorg-inherited-config.jsonでOnboarding PRの中身そのものを組織側から差し替えるように切り替えました。
// LabeeHive/renovate-config/org-inherited-config.json
{
"$schema": "https://docs.renovatebot.com/renovate-inherited-schema.json",
"onboarding": true,
"onboardingConfigFileName": ".github/renovate.json5",
"onboardingConfig": {
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"github>LabeeHive/renovate-config:default.json5"
]
}
}
この記事では、Renovateの自動Onboarding PRに何が入っていないか、Renovate本体に組み込まれた<org>/renovate-config/default.jsonの自動検出、default.json5を選んだ瞬間にその自動検出が効かなくなる理由、そしてorg-inherited-config.jsonで書き換える方針までを順に書きます。
Onboarding PRはデフォルトで出る、中身が違うだけ
Renovateを新しいリポジトリで動かすと、初回にOnboarding PRが自動で立ちます。Renovate本体の挙動で、組織継承の設定があってもなくても出てきます。
問題は中身です。デフォルトのOnboarding PRに入っているのはRenovate標準の雛形で、ラビー合同会社で使いたいプリセットへの参照ではありません。新規リポジトリができるたびに、extendsに組織共通プリセットへの参照を1行足して、ファイルパスを.github/renovate.json5に直して、マージする。薄い作業ですが、触る回数だけはあるので、ファイル名のtypoや参照先の付け忘れが少しずつ積もっていきます。「Renovateが回っていない」と思って覗いたら、デフォルトのまま放置されたrenovate.jsonがリポジトリ直下にあった、というのを何度かやってからは、Onboarding PRの中身を組織側で固めたくなりました。
Renovate本体には<org>/renovate-config/default.jsonを拾う仕組みがある
ソースコードを覗くと、Renovateの初回Onboarding処理が<org>/renovate-configを探しに行く分岐があります。lib/workers/repository/onboarding/branch/config.tsのsearchDefaultOnboardingPresetが該当箇所で、新規リポジトリのパスを上から辿りながら<group>/renovate-configの存在を確認し、見つかればその参照をOnboarding PRのextendsとして埋め込みます。
// lib/workers/repository/onboarding/branch/config.ts より抜粋
// Check for group/renovate-config
const repo = `${groupName}/renovate-config`;
const preset = `local>${repo}`;
if (await getPreset({ repo })) {
foundPreset = preset;
}
getPreset({ repo })はpresetName省略時に'default'を使う実装で、内部のfetchPreset()でdefault.jsonを直接読みに行きます。
// lib/config/presets/util.ts より抜粋
if (fileName === 'default') {
try {
jsonContent = await fetch(
repo, buildFilePath('default.json'), endpoint, tag,
);
} catch (err) {
// ... fallback to deprecated renovate.json ...
}
}
つまり<org>/renovate-configのリポジトリ直下に default.json が置いてあれば、新規Onboarding PRにはextends: ["local><org>/renovate-config"]が自動で差し込まれます。org-inherited-config.jsonを書かなくても、Onboarding PRのextendsを毎回手作業で足す必要がなくなります。
default.json5を選ぶと自動検出は効かない
問題はここからです。組織共通プリセットには「なぜこの設定を入れているか」をコメントで残したい背景があります。JSON5ならコメントを書けるため、ファイルをdefault.json5にしたい。
ところが上のsearchDefaultOnboardingPresetはgetPreset({ repo })経由でdefault.jsonを直接探しに行く実装なので、default.json5しか置いていないリポジトリはマッチしません。fetchPreset()のfileName === 'default'の分岐はbuildFilePath('default.json')に決め打ちで降りていきます。自動検出が空振りすると、Onboarding PRには組織プリセットへの参照が入らず、Renovate標準の雛形がそのまま書き込まれてしまいます。
回避するには、Onboarding PRの中身を上書きするためのorg-inherited-config.jsonを別途用意し、onboardingConfig.extendsにファイル名つきの参照(github>LabeeHive/renovate-config:default.json5)を明示的に書きます。fetchPreset()は拡張子に.json5が付いたfilePresetが渡された場合はその名前で取りに行く分岐に入るため、こちらは問題なく解決します。
ラビー合同会社では、default.json5でコメントを残すことを優先して、org-inherited-config.jsonを併設する方式を取りました。「Onboarding PRの中身を制御したい」「プリセットにコメントを書きたい」という2つの目的が、結果として同じファイル(org-inherited-config.json)で実現できる構造です。
// LabeeHive/renovate-config/org-inherited-config.json
{
"$schema": "https://docs.renovatebot.com/renovate-inherited-schema.json",
"onboarding": true,
"onboardingConfigFileName": ".github/renovate.json5",
"onboardingConfig": {
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"github>LabeeHive/renovate-config:default.json5"
]
}
}
Mend-hostedはリポジトリ名とファイル名を固定で見る
org-inherited-config.jsonが読まれる側の仕組みはMend-hosted Renovate Appに書かれています。Mend-hostedのバックエンドは毎回のRenovate実行のたびに<org>/renovate-config/org-inherited-config.jsonを自動で読みに行き、対象リポジトリの設定にマージしてから動きます。
有効化に必要なのは3点です。
- リポジトリ名が
renovate-configであること - ファイル名が
org-inherited-config.jsonであること - Renovate Appがこのリポジトリにもインストールされていること
リポジトリ名もファイル名もハードコードされていて、.github/org-inherited-config.jsonのような別配置にしても見てもらえません。renovate-configを独立したリポジトリとして切ったのはこの規約に従うためで、Renovate関連だけを抱えるリポジトリにすると、.githubリポジトリと役割を切り分けられます。
org-inherited-config.jsonのonboardingConfigにextendsを書いておくと、Renovateが新規リポジトリのOnboarding PRを開くときに、その内容がそのままrenovate.json5として書き込まれます。onboardingConfigFileNameを.github/renovate.json5に向けているのはリポジトリのルートを汚さないためで、Renovate関連の設定を.github/配下に集めておくと、ファイルツリーやlsの結果がすっきりします。
既存リポジトリの参照は手動で揃える
org-inherited-config.jsonを置いた後も、すでにOnboarding済みのリポジトリのrenovate.json5は古い参照先を指したままです。onboardingConfig.extendsを新しい参照に切り替えても、これは新規リポジトリ向けの雛形を上書きするだけで、既存ファイルには触れません。
既存リポジトリでgithub>LabeeHive/.github:default.json5のような古い参照を使っているものは、新しいrenovate-config側に向け直すPRを別途出して回します。対象の洗い出しはgh search codeで済みます。
gh search code --owner LabeeHive 'extends "github>LabeeHive/.github:default.json5"' --json repository,path
返ってきたパスごとにextendsの参照先を書き換えるPRを出し、マージし切ってから古い.github/default.json5本体を削除します。切り替えが完了するまでは新旧両方のdefault.json5が並走するため、中身を一時的に同じ内容に揃えておけばRenovateの挙動は変わりません。