ツナ缶雑記

ぐうたらSEのブログです。主にマイクロソフト系技術を中心に扱います。たまに技術と関係ないことも書きます。

dependabotを使って.NETのパッケージ更新をLTSのバージョンに限定する方法

この記事のまとめ

  • dependabot は依存関係を自動で管理し、更新が必要な場合にプルリクエストを作成します。
  • .github/dependabot.yml ファイルを作成して、dependabot の設定を行います。
  • 複数のライブラリの更新をグループ化して、 1 つのプルリクエストにまとめることができます。
  • .NET の STS バージョンを無視して、 LTS バージョンのみのプルリクエストを作成することができます。

dependabot とは

dependabot は、GitHub が提供する依存関係管理ツールです。 プロジェクトの依存関係を自動的にチェックし、更新が必要な場合にプルリクエストを作成してくれます。 常に最新のライブラリを使用し続けることができる、現代のシステム開発にはうってつけのツールだと思います。

お仕事でも必ず導入するようにしています。 ライブラリの更新が自動化されることで、より開発に集中できるようになります。 また、セキュリティが保たれた状態を保つことにも役立ちます。

dependabot の構成方法

dependabot を構成するには、リポジトリの .github ディレクトリに dependabot.yml ファイルを作成します。 このファイルには、dependabot が管理するパッケージシステムや、対象のディレクトリなどを指定します。 リファレンスは以下にあります。

docs.github.com

.NET のパッケージを管理する dependabot.yml の作成

とりあえず動かす、という目的であれば、 dependabot.yml を以下のように設定しましょう。

version: 2
updates:
  - package-ecosystem: "nuget"
    directory: "/"
    schedule:
      interval: "daily"

これで、 1 日 1 回 NuGet パッケージの更新がないか確認し、更新があれば自動的にプルリクエストを作成してくれます。

プルリクエストをグループ化する

.NET のパッケージは、月次の .NET SDK の更新にあわせて、更新の有無にかかわらず一括でリリースが行われています。 バージョニングポリシーの異なるライブラリを除き、原則としてバージョン番号をそろえなければなりません。 前述の設定では、ライブラリ個別にプルリクエストが作成されるため、バージョン差異が生じてしまい、 CI が成功しなくなります。 このような「まとめて一括アップデート」を行いたい場合は、 dependabot のグループ化機能を利用します。

前述の設定に対して、 groups を追加することで、プルリクエストをグループ化できます。 以下に例を示します。

version: 2
updates:
  - package-ecosystem: "nuget"
    directory: "/"
    schedule:
      interval: "daily"
    groups:
      dotnet-packages:
        patterns:
          - "Microsoft.AspNetCore*"
          - "Microsoft.EntityFrameworkCore*"
          - "Microsoft.Extensions*"
      nswag-packages:
        patterns:
          - "NSwag*"

groups 直下には、任意のグループの名前を設定します。 この例では、 dotnet-packages と nswag-packages の 2 グループを作成しています。 各グループには、そのグループに属するパッケージ名のパターンを patterns に定義します。 これにより、 Microsoft.AspNetCore / Microsoft.EntityFrameworkCore / Microsoft.Extensions で始まるライブラリと、 NSwag で始まるライブラリの更新が、それぞれひとつずつのプルリクエストにまとめられます。 特に dotnet-packages にあげたパッケージは、依存関係を持つものが多いので、依存関係の崩れによる CI の失敗が大幅に減らせるはずです。

なお条件に合致しない NuGet パッケージはグループ化されず、パッケージごとに個別のプルリクエストが作成されます。

特定バージョンへの更新を除外する

これだけでもだいぶいい感じになるのですが、 .NET は毎年 STS と LTS を交互にリリースする仕組みになっています。 特に STS のリリースされた年は、最新版が STS となり、前述の設定では dependabot も STS のバージョンのライブラリを拾ってきます。 本番適用する前提だと、どうしても STS のバージョンを採用するのは難しく、基本的には LTS のバージョンを採用すると思います。 このように、特定のバージョンへの更新を除外する設定も、 dependabot ではできるようになっています。 以下に例を示します。

version: 2
updates:
  - package-ecosystem: "nuget"
    directory: "/"
    schedule:
      interval: "daily"
    groups:
      dotnet-packages:
        patterns:
          - "Microsoft.AspNetCore*"
          - "Microsoft.EntityFrameworkCore*"
          - "Microsoft.Extensions*"
      nswag-packages:
        patterns:
          - "NSwag*"
    ignore:
      - dependency-name: "Microsoft.AspNetCore*"
        versions: ["9.*"]
      - dependency-name: "Microsoft.EntityFrameworkCore*"
        versions: ["9.*"]
      - dependency-name: "Microsoft.Extensions*"
        versions: ["9.*"]

前述の dependabot.yml に ignore セクションを追加し、 STS である 9.* 系のパッケージへの更新をしないよう設定しています。 これにより、 dependabot は、 8.* 系の最新バージョンを拾ってプルリクエストを作成するようになります( 2024 年 12 月現在)。