0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dependabotで依存パッケージの更新確認と自動マージ

Last updated at Posted at 2024-08-10

先に結論だけ

Dependabotと自動マージを併用することで、依存パッケージの更新作業を簡略化でき、手作業によるミスを防げます。パッケージ更新作業を負担に感じる方はぜひ導入を検討してください。

マージの権限をワークフローに与えるのは、抵抗感があるかもしれません。例えば、開発環境にしか影響を与えないパッケージのパッチバージョンの更新のみ許可する設定から始めてみましょう。

はじめに

この記事は、Dependabotを使って依存パッケージの更新を自動化する方法を共有するためのものです。

対象とする読者

  • GitHubのリポジトリを運用しているエンジニア
  • すでにテスト自動化は導入している
  • GitHub Actionsを使ったことがある
  • 依存関係の更新や管理が作業負担に感じる人

テスト自動化に関する内容はこの記事では取り扱いません。

対象とする環境

  • 2024/08/09時点のGitHubおよびDependabot
  • node.js v20.16.0
  • npm v10.8.2

この記事ではパッケージマネージャーにnpmを利用しています。他のパッケージマネージャーを利用している場合は、適宜読み替えてください。

Dependabotとは

Dependabotは、GitHubが提供する依存関係スキャニングツールです。この記事で対象となるのはDependabotのバージョンアップデートですが、Dependabotには他にも以下の機能があります。

Dependabotアラート

Dependabotアラートは、脆弱性のある依存関係を検出し、リポジトリの所有者に通知するツールです。

Dependabotアラートはすべてのリポジトリで有効になっています。

Dependabotセキュリティアップデート

Dependabotセキュリティアップデートは、脆弱性を修正するプルリクエストを作成するツールです。

この機能は、ユーザーが設定しない限り有効になりません。

リポジトリのSettingタブ→Code security and analysisDependabotセクション→Dependabot security updatesEnableボタンで設定できます。

Dependabotバージョンアップデート

Dependabotバージョンアップデートは、依存パッケージの最新バージョンを確認し、プルリクエストを作成するツールです。セキュリティアップデートとは異なり、脆弱性の有無には関係なく更新のたびにプルリクエストが作成されます。

Dependabotバージョンアップデートは、ユーザーがdependabot.ymlという設定ファイルを設置すると有効化されます。設定した期間ごとにパッケージの更新を確認し、プルリクエストを発行します。

GitHubのAuto Merge機能

Auto mergeは、ブランチプロテクションルールのチェックをパスしたプルリクエストを自動でマージする機能です。

Auto merge機能を有効化する手順は自動マージを有効化するのセクションで解説します。

Dependabotで自動マージ

Dependabotバージョンアップデートと、GitHubの自動マージ機能を組み合わせることで、依存パッケージの更新を自動化できます。

自動テスト環境を整える

まずは、依存パッケージの更新による影響を確認するための自動テスト環境を整えます。node.jsには、以下のようなテストランナーがあります。

この記事ではテストそのものの実装は割愛します。依存パッケージの更新によって機能が破壊されないか、自動テストで検出できるようになるのが理想です。

自動テストをGitHub Actionsで実行する

GitHub Actionsを使って、プルリクエストが作成されたときに自動テストを実行するワークフローを設定します。

name: Run tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [20.x, 22.x]

    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"
      - run: npm ci
      - run: npx test

このワークフローは、デフォルトブランチにプルリクエストが作成されたときにnpm testコマンドで自動テストを実行します。

より詳細な設定方法は以下のリンクを参照してください。

ブランチプロテクションルールを有効化する

テストが失敗した場合、デフォルトブランチへのマージを阻止する設定を追加します。

GitHubのSettingsタブ→RulesRulesetsNew rulesetNew branch rulesetでブランチプロテクションルールを作成します。

add new ruleset.png

以下のスクリーンショットの手順にそって、プロテクションルールを設定します。

set protection rule.png

ポイントになるのはRequire status checks to passRequire branches to be up to date before mergingの設定です。この設定で、テストが失敗した場合、デフォルトブランチへのマージが阻止されるようになります。

この設定は、Auto mergeを機能させるための最低限のものです。皆さんのプロジェクトに合わせて、Require linear history(線形履歴の強制)やRequire a pull request before merging(プルリクエストを経由しないマージを禁止)などより厳密な設定を検討してください。

Dependabotバージョンアップデートを有効化する

Dependabotのバージョンアップデート機能を有効化します。リポジトリに/.github/dependabot.ymlというファイルを作成します。

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

Dependabotはこの設定ファイルを読み込んで、依存パッケージの監視を開始します。

自動マージを有効化する

GitHubリポジトリのAuto merge機能を有効化します。リポジトリのSettingsタブ→GeneralPull Requestsセクション→Allow auto-mergeをチェックします。

enable auto merge.png

この時点でGitHubのWeb画面から自動マージが可能です。プルリクエストを作成して、テストが完了する前にEnable auto-mergeボタンをクリックすると自動マージが予約されます。テストにパスした時点で、そのプルリクエストがデフォルトブランチにマージされます。

Pull Requestを自動マージする

マージをGitHub Actionsで自動化します。以下のワークフローを設定します。

.github/workflows/dependabot-auto-merge.yml

name: Dependabot auto-merge
on: 
  pull_request:
    branches:
      - main
      
permissions:
  contents: write
  pull-requests: write

jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: github.actor == 'dependabot[bot]'
    steps:
      - name: Dependabot metadata
        id: metadata
        uses: dependabot/fetch-metadata@v2
        with:
          github-token: "${{ secrets.GITHUB_TOKEN }}"
      - name: Enable auto-merge for Dependabot PRs
        if: steps.metadata.outputs.dependency-type == 'direct:development' && steps.metadata.outputs.update-type == 'version-update:semver-patch'
        run: gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GH_TOKEN: ${{secrets.GITHUB_TOKEN}}

このワークフローでは、package.jsonのdevDependenciesに登録されているモジュールが、パッチ更新された場合に自動マージを行います。マイナー以上のバージョンアップデートや、dependenciesに登録されているモジュールのアップデートはユーザーの判断を待ちます。

Dependabotが作成したプルリクエストの内容は、dependabot/fetch-metadataというアクションで取得できます。

  • dependency-type : dependenciesdevDependenciesのどちらの更新か
  • update-type : セマンティックバージョンの種類

などの情報がメタデータに格納されます。

メタデータのより詳細な情報は公式サイトを参照してください。

自動マージ後のトリガーに関する問題と対処方法

問題 : 自動マージ後にワークフローがトリガーされない

Dependabotが作成したプルリクエストを、rebase and mergeでデフォルトブランチにマージすると、GitHub Actionsのpushpull_request:closedイベントがトリガーされません。

問題の原因

Dependabotはプルリクエストが解決された場合、即座に自分自身が作ったブランチを削除します。私の現在の理解では、自動マージとブランチ削除が同時に行われた場合pull_request:closedイベントはトリガーされないようです。また、Dependabotがrebase and mergeでマージした場合、デフォルトブランチのpushイベントもトリガーされませんでした。

影響

このトリガーの取りこぼしは、たとえばデフォルトブランチが更新されるたびにデモページを更新し、GitHub Pagesにデプロイするというユースケースで問題を引き起こします。

  • ドキュメントが最新状態に維持されていない
  • 依存パッケージの更新によってドキュメントのビルドに失敗しても気づけない

対処方法

この問題に対して私は

  • Dependabotがrebase and mergeした場合、処理を取りこぼすことがある
  • プルリクエストの作成イベントは正常にトリガーされるため、デフォルトブランチのpushおよびpull_requestイベントでドキュメントのビルドワークフローを実行する
  • if: ${{ github.ref == 'refs/heads/main' }}を利用して、デフォルトブランチのheadを参照しているときだけデプロイする

という方法で対処しました。

具体的なワークフローは以下の通りです。

.github/workflows/publish-github-pages.yml

name: Publish github pages

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]


jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: write #デプロイのための書き込み許可を与える
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
      - run: npm ci
      - run: npm run buildPages #ドキュメントビルドコマンド
      - name: Deploy Github pages
        uses: peaceiris/actions-gh-pages@v4
        if: ${{ github.ref == 'refs/heads/main' }} #デフォルトブランチのheadを参照しているときだけデプロイする
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public

この対処方法が最適か、他に良い方法があればぜひコメントをお寄せください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?