🤖

renovateの共有設定presetsでパッケージ管理体制を整えた話

2022/06/13に公開

ファンタラクティブのエンジニアの村上です。

なにこれ?

現在社内では、パッケージ管理botのrenovateを利用したパッケージ管理の半自動化を進めています。

パッケージ管理体制を整えるために共有設定presetsを作成して一般公開したので、その経緯とpresetsの内容を共有します。

公開した共有設定presetsのレポジトリはこちらから確認できます。

https://github.com/funteractive-inc/renovate-config

この記事で解決したいこと

社内の案件毎にrenovateの設定を毎回ゼロから作成していると、label設定の名称や付与条件などといった設定内容が案件によって異なりがちです。

この際、例えば以下のような課題を感じます。

  • 担当案件が変わる度、パッケージ管理の設定内容とそれに基づいた管理フローを理解する手間が発生する。
  • ある案件でrenovateの設定を改善できても、他案件に横展開しづらい。

課題の原因

このような課題の原因として、以下が挙げられると思います。

  • renovateの設定の構築は、案件の開発初期にアサインされたエンジニアの意向に依存している。
  • 設定内容を改善した際に、他案件や他エンジニアに共有する仕組みがない。

解決方法

共有設定presets(Shareable Config Presets)を利用して課題解決を図りました。

作成した共有設定presetsは各案件のリポジトリで以下のように参照でき、案件間の設定のバラつきを軽減できます。

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["github>funteractive-inc/renovate-config"]
}

また、共有設定presetsに対して変更を加えれば、参照している案件すべてに対して内容を反映させられる恩恵も受けられるのが素敵です。

共有設定presets内容抜粋

実際にどんな内容をpresetとして定義しているのか一部抜粋して紹介します。

作成したpresetは公開されているので、以下の照会内容以外が気になる方は是非のぞいてみてください。

なお、作成の際にははてなさん公開の共有設定presetsを参考にさせていただきました。[1]
この場を借りてお礼申し上げます。

automergePinPatch

{
    "packageRules": [
        {
            "matchUpdateTypes": [
                "patch",
                "pin"
            ],
            "automerge": true
        }
    ]
}

patchバージョンのアップデートに関して、CIがpassされれば自動でマージさせる設定です。
発生頻度が高く、一般に影響が大きくないことから自動マージを有効にしています。

automergeTypesMinor

{
    "packageRules": [
        {
            "matchPackagePatterns": [
                "^@types/"
            ],
            "automerge": true,
            "major": {
                "automerge": false
            }
        }
    ]
}

型定義パッケージに関してはminorバージョンアップデートにおいても、大きな影響を及ぼす可能性が低いことから自動マージの対象をpatchとminorに広げています。
なおmajorバージョンアップデートは自動マージ対象にしていません。

labelMajor

{
    "packageRules": [
        {
            "matchUpdateTypes": "major",
            "addLabels": [
                "major"
            ]
        }
    ]
}

自動マージの対象とならないminorとmajorバージョンアップデートの違いが際立つよう、majorバージョンアップデートのPRにのみmajorラベルを付与しています。


ラベル付与によってmajorアップデートを強調した結果

groupLinters

{
    "packageRules": [
        {
            "groupName": "linters",
            "extends": [
                "packages:linters"
            ],
            "matchPackageNames": [
                "prettier"
            ],
            "matchPackagePatterns": [
                "^@typescript-eslint/"
            ]
        }
    ]
}

lint関連のパッケージアップデートを1つのPRにまとめるための設定です。
renovateが提供するgroup presetgroup:lintersを拡張し、prettierとtypescript-eslintもグループ化対象に含めています。

このほか、jestやreact関連パッケージも同様にグループ化する設定を設けて利用しています。

schedule

{
    "extends": [
        ":timezone(Asia/Tokyo)"
    ],
    "schedule": [
        "before 8am every weekday",
        "after 8pm every weekday"
    ]
}

ファンタラクティブではCIの結果をslack通知しているので、勤務時間中にrenovateを動作させてしまうとパッケージ更新PRに対するCI結果通知がチャンネルを占めてしまいます。
これを避けるため、平日の08:00 ~ 20:00以外の時間帯で稼働させています。

応用事例

共有設定presetsを利用すると、案件ごとに設定を容易に拡張できます。

フレームワークにNext.jsを利用する場合

{
    "$schema": "https://docs.renovatebot.com/renovate-schema.json",
    "extends": [
        "github>funteractive-inc/renovate-config",
        ":followTag(typescript, next)"
    ]
}

typescriptのバージョンがNext.jsで利用しているtypescriptのバージョンと乖離させない設定(helpers:followTypescriptNext)を追加しています。

renovateの動作時間帯を変更する場合

{
    "$schema": "https://docs.renovatebot.com/renovate-schema.json",
    "extends": [
        "github>funteractive-inc/renovate-config"
    ],
    "schedule": [
        "after 10am and before 4pm every weekday"
    ]
}

共有設定presetsで指定した動作時間帯で不都合が生じる場合、上記のように差し替えられます。

効果

共有設定presetsの利用により設定の差分が際立ち、内容理解にかかるコストが低下しました。

たとえば、以下の2つの設定は動作時間(schedule)だけ差分のある設定ですが、応用事例で紹介した「renovateの動作時間帯を変更する場合」に比べて差分箇所の特定により時間がかかると思います。

setting1.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:base", ":timezone(Asia/Tokyo)"],
  "schedule": ["after 10am and before 6pm every weekday"],
  "packageRules": [
    {
      "matchUpdateTypes": ["patch", "pin"],
      "automerge": true
    },
    {
      "matchUpdateTypes": "major",
      "addLabels": ["major-update"]
    },
    {
      "packagePatterns": ["^@types/"],
      "automerge": true,
      "major": {
        "automerge": false
      }
    },
    {
      "groupName": "linters",
      "extends": ["packages:linters"],
      "packageNames": ["prettier"],
      "packagePatterns": ["^@typescript-eslint/"]
    },
    {
      "matchPackageNames": [
        "react",
        "@types/react",
        "react-dom",
        "@types/react-dom"
      ],
      "groupName": "react",
      "patch": {
        "automerge": true
      }
    }
  ]
}
setting2.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:base", ":timezone(Asia/Tokyo)"],
  "schedule": [
        "before 8am every weekday",
        "after 8pm every weekday"
    ],
  "packageRules": [
    {
      "matchUpdateTypes": ["patch", "pin"],
      "automerge": true
    },
    {
      "matchUpdateTypes": "major",
      "addLabels": ["major-update"]
    },
    {
      "packagePatterns": ["^@types/"],
      "automerge": true,
      "major": {
        "automerge": false
      }
    },
    {
      "groupName": "linters",
      "extends": ["packages:linters"],
      "packageNames": ["prettier"],
      "packagePatterns": ["^@typescript-eslint/"]
    },
    {
      "matchPackageNames": [
        "react",
        "@types/react",
        "react-dom",
        "@types/react-dom"
      ],
      "groupName": "react",
      "patch": {
        "automerge": true
      }
    }
  ]
}

終わりに

本記事を通して、共有設定presetsの利用によって再利用性とメンテナンス性が高まり、設定内容の差分理解が容易になることを伝えられれば幸いです。

公開している内容を参考にご自身で共有設定presetsを作成されたり、フォークして自由に変更を加えて頂いて構いません。

また、今回作成したpresetに含まれていないオススメの設定やpreset[2]があればコメント等にて共有していただけると大変うれしく思います。

脚注
  1. 紹介記事は「はてなで使用しているRenovateの設定プリセットを公開しました↩︎

  2. 公式でDefault PresetsHelper Presetsがたくさん用意されているが、常に把握しきれない... ↩︎

ファンタラクティブテックブログ

Discussion