GitHub Dependabotが作る脆弱性を修正するプルリクエストをグルーピングする

記事タイトルとURLをコピーする

こんにちは。
アプリケーションサービス部、DevOps担当の兼安です。
お盆が近づき、実家の草刈りに追われる毎日を過ごしています。
今年は空調服を着て作業していますが、それでも凄まじく体力を消耗します。
みなさまも外での作業をされる場合はお気をつけてください。

さて、今回はGitHubのDependabotについてお話しします。

本記事のターゲット

  • GitHubの基礎知識がある方
  • プログラミング言語のパッケージ管理と脆弱性の関係の知識がある方
  • パッケージの脆弱性対策に関心がある方

GitHub Dependabotとは

GitHub Dependabotは、GitHubが提供する機能で、リポジトリ内の依存関係の脆弱性を検出し、修正するための自動化ツールです。
リポジトリの設定のAdvanced Securityで、Dependabot security updatesを有効にすることで、脆弱性のある依存関係を検出し、プルリクエストを自動で作成するようになります。

docs.github.com

GitHub Dependabotの有効化

脆弱性の検知とプルリクエストの作成は、リポジトリのデフォルトブランチに対してプッシュした時や、定期的なスケジュールに基づいて行われます。

次項から、GitHub DependabotはDependabot、プルリクエストはPRと記述します。

検証用のサンプルコード

/
├── python-1/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
├── python-2/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
└── ts/
    ├── app.ts
    ├── package.json
    └── package-lock.json

PythonとTypeScriptで脆弱性を持つサンプルコードを用意しました。
Pythonはフォルダを2つ用意しています。

Dependabotが作成するPR

上記コードをGitHubにプッシュすると、Dependabotが脆弱性のある依存関係を検出し、PRを作成します。

Dependabotが作成したPR群

自動でPRを作成してくれる時点で大変便利ではありますが、PRが多くなると対応が大変になります。

PRのグループ化

Advanced Securityで、Dependabot security updatesの下にある、Grouped security updatesを有効にすると、PRのグループ化が有効になります。

docs.github.com

PRのグループ化の有効化

すると、次にPRが作成される際に、同じパッケージ管理システムの脆弱性をまとめて1つのPRにグループ化してくれます。

グループ化されたPR

PRを開くと、複数の脆弱性の修正が含まれていることがわかります。

グループ化されたPRには複数の修正が含まれる

dependabot.ymlによるグループ化の制御

PRのグループ化を細かく制御したい場合は、.github/dependabot.ymlを使用します。

docs.github.com

今回の検証用のサンプルコードに、.github/dependabot.ymlを追加します。

/
├── .github/
│   └── dependabot.yml
├── python-1/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
├── python-2/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
└── ts/
    ├── app.ts
    ├── package.json
    └── package-lock.json

.github/dependabot.ymlの内容は以下の通りです。
Pythonのフォルダを2つに対し、django系以外に関するPRをpyグループに、django系のPRをdjangoグループに分けています。
TypeScriptのフォルダに関するPRはtsグループにまとめています。

version: 2
updates:
  - package-ecosystem: "uv"
    directory: "/python-1"
    schedule:
      interval: "daily"
    groups:
      py:
        patterns:
          - "*"
        exclude-patterns:
          - "django*"
      django:
        patterns:
          - "django*"
  
  - package-ecosystem: "uv"
    directory: "/python-2"
    schedule:
      interval: "daily"
    groups:
      py:
        patterns:
          - "*"
        exclude-patterns:
          - "django*"
      django:
        patterns:
          - "django*"
  
  - package-ecosystem: "npm"
    directory: "/ts"
    schedule:
      interval: "daily"
    groups:
      ts:
        patterns:
          - "*"

このYAMLを作成後、完成したPRは以下のようになります。

dependabot.yml作成後にできたPR

python-1python-2は同じpyグループを指定しましたが、同じ名前のグループを作っても、フォルダ別にPRが作成されるようです。
django系のPRは想定通り独立したグループとして作成されています。

tornadocertifiのPRは、単独のPRとして作成されました。
これらに関しては特に指定していないのですが、優先度の高い修正は.github/dependabot.ymlで定めたルールから外れて個別のPRとして作成されることがあるようです。

今回試したグループ化のパターン以外の例は、下記のページを参考にするとよいでしょう。

github.com

dependabot.ymlを設定した時に気になった点

PRのグループ化は、Grouped security updates.github/dependabot.ymlで設定できますが、この2つには依存関係はないようです。
Grouped security updatesを有効にしていなくても、.github/dependabot.ymlでグループ化の設定を行うことでPRはグループ化されます。

.github/dependabot.ymlは、ファイルのグループ化ルールを編集すると、プッシュした時点でPRが再グルーピングされる動きをします。

まとめ

  • Dependabotは、GitHubが提供する依存関係の脆弱性を検出し、PRを自動で作成することができるツールです。
  • DependabotのPRは、Advanced SecurityGrouped security updatesを有効にすることで、同じパッケージ管理システムの脆弱性をまとめて1つのPRにグループ化できます。
  • .github/dependabot.ymlを使用することで、PRのグループ化を細かく制御できます。

脆弱性対策は、セキュリティの観点から非常に重要ですが、気持ちだけでは継続的に行うことは難しいです。
Dependabotを利用することで効率的な脆弱性対策が可能になります。
本記事がDependabotの運用のヒントになれば幸いです。

余談

Dependabotの前に、そもそも脆弱性をちゃんと仕込めているのかを検証するために、GitHub ActionsでTrivyを動かしていました。

github.com

その時気付いたのですが、本記事執筆時点(2025年8月)でのTrivyは、uvに対応していないようです。
uv exportrequirements.txtを生成してからTrivyを動かせば検知できるので、やり方を共有しておきます。
下記のYAMLのGenerate requirements.txt for Python1Generate requirements.txt for Python2の部分をご覧ください。

このYAMLのワークフローは、検知できているかを調べるコードなので、Trivyが脆弱性を検知しても正常終了させています。
exit-code: '0'の部分がその設定です。
本来はここはexit-code: '1'にして、脆弱性を検知したらエラーコードを返すようにするのが正しいです。

name: Trivy Vulnerability Scan
on:
  push:
    branches:
    - main
  pull_request:
jobs:
  build:
    name: Build
    runs-on: ubuntu-24.04
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.13'
    
    - name: Install uv
      run: pip install uv
    
    - name: Generate requirements.txt for Python1
      run: |
        cd python-1
        uv export --format requirements-txt --output-file requirements.txt
    
    - name: Generate requirements.txt for Python2
      run: |
        cd python-2
        uv export --format requirements-txt --output-file requirements.txt
    
    - name: Scan Python-1
      uses: aquasecurity/trivy-action@0.28.0
      with:
        scan-type: 'fs'
        scan-ref: './python-1'
        format: 'table'
        output: 'python-1-results.txt'
        exit-code: '0'
        severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
    
    - name: Scan Python-2
      uses: aquasecurity/trivy-action@0.28.0
      with:
        scan-type: 'fs'
        scan-ref: './python-2'
        format: 'table'
        output: 'python-2-results.txt'
        exit-code: '0'
        severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
    
    - name: Scan TypeScript
      uses: aquasecurity/trivy-action@0.28.0
      with:
        scan-type: 'fs'
        scan-ref: './ts'
        format: 'table'
        output: 'ts-results.txt'
        exit-code: '0'
        severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
    
    - name: Check all results
      run: |
        echo "=== Python1 results ==="
        cat python-1-results.txt || echo "No Python1 results"
        echo "=== Python2 results ==="
        cat python-2-results.txt || echo "No Python2 results"
        echo "=== TypeScript results ==="
        cat ts-results.txt || echo "No TypeScript results"
    
    - name: Upload Trivy scan results
      uses: actions/upload-artifact@v4
      if: always()
      with:
        name: trivy-results
        path: |
          python-1-results.txt
          python-2-results.txt
          ts-results.txt

兼安 聡(執筆記事の一覧)

アプリケーションサービス部 DS3課所属
2025 Japan AWS Top Engineers (AI/ML Data Engineer)
2025 Japan AWS All Certifications Engineers
2025 AWS Community Builders
Certified ScrumMaster
PMP
広島在住です。今日も明日も修行中です。