目录

GitHub Dependabot:自动化依赖更新

GitHub Dependabot:自动化依赖更新

Dependabot 解决的真正问题是把依赖更新的责任从人的记忆力转移到系统上,而非自动发 PR。漏洞出现后小时级响应、版本落后自动追平,这些靠人盯 RSS 或手动 npm outdated 做不到。下面先把 Dependabot 的三条机制拆开,再逐条看怎么配、怎么用。

机制触发方式产物典型场景
Dependabot AlertsGitHub Advisory Database 匹配到漏洞Security 标签页告警 + 修复建议发现 lodash CVE,知道该升到哪个版本
Version Updates.github/dependabot.yml 中配置的 schedule自动创建依赖更新 PR每周检查 npm 依赖,把 react 从 18.2 升到 18.3
Security Updates检测到 Critical/High 漏洞紧急 PR,绕过正常 scheduleexpress 出现 RCE(远程代码执行)漏洞,不等下周直接发 PR

三条线独立运作,但在一个仓库里会同时生效。理解这个边界之后,再看细节就不会混。

一、Dependabot 是什么

Dependabot 是 GitHub 官方出品的自动化依赖更新工具,支持的生态系统包括 npm、Maven、pip、Go、Cargo、NuGet、GitHub Actions 等。

Dependabot 在 GitHub.com 上分两层:

  1. GitHub 内置功能(Dependabot alerts + version updates + security updates)—— 在仓库 Settings 中开启即用
  2. Dependabot Actiongithub/dependabot-action)—— 用于 GHES(GitHub Enterprise Server)手动同步,或运行自定义 Dependabot 工作流

内置功能是大多数团队日常使用的部分,Action 只在企业私有部署场景下才需要关注。

二、核心功能

1. Dependabot Alerts

当依赖出现已知漏洞时,GitHub 自动在 Security 标签页生成告警:

  • 漏洞数据库:来自 GitHub Advisory Database、NVD 和生态伙伴
  • 严重程度分级:Critical、High、Medium、Low
  • 直接修复建议:显示受影响版本范围,给出应升级的目标版本

Alerts 只负责"告诉你出事了"和"该升到哪个版本"。它不创建 PR——那个是 Security Updates 的事。

2. Dependabot Version Updates

按 schedule 定期扫描依赖,检测到新版本就创建更新 PR:

# .github/dependabot.yml
version: 2
updates:
  # npm 每月检查一次
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "monthly"
    open-pull-requests-limit: 5
    commit-message:
      prefix: "deps"
    labels:
      - "dependencies"
    reviewers:
      - "@org/devops"

  # GitHub Actions 每周检查
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
    commit-message:
      prefix: "ci"

3. Security Updates

Security Updates 绕过正常 schedule,只在出现 Critical 或 High 级漏洞时触发:

  • 自动发起紧急 PR,不等待 schedule
  • 在 Branch Protection 允许的前提下直接合并
  • 通过 Dependabot security updates 接口自动修复

Security Updates 默认依赖 .github/dependabot.yml 中的 security-updates 配置;没配的话,Alerts 照常触发,但不会自动生成修复 PR。

三、详细配置

基础配置

创建 .github/dependabot.yml

# .github/dependabot.yml
version: 2

updates:
  - package-ecosystem: "pip"
    directory: "/backend"
    schedule:
      interval: "weekly"
      day: "wednesday"
    open-pull-requests-limit: 10
    commit-message:
      prefix: "py"
    ignore:
      # 忽略 patch 版本更新(如 1.2.3 → 1.2.4)
      - dependency-name: "*"
        update-types: ["version-update:semver-patch"]
    groups:
      production-dependencies:
        dependency-type: "production"
      development-dependencies:
        dependency-type: "development"

按生态详细配置

npm:

- package-ecosystem: "npm"
  directory: "/frontend"
  schedule:
    interval: "weekly"
  versioning-strategy: "increase"
  commit-message:
    prefix: "npm"
  allow:
    - dependency-name: "react"
    - dependency-name: "react-dom"
  ignore:
    - dependency-name: "typescript"
      versions: ["4.9.0", "4.9.5"]

GitHub Actions:

- package-ecosystem: "github-actions"
  directory: "/"
  schedule:
    interval: "daily"
    time: "09:00"
  open-pull-requests-limit: 3
  commit-message:
    prefix: "ci"
  labels:
    - "github-actions"
  ignore:
    - dependency-name: "actions/checkout"
      update-types: ["version-update:semver-patch"]

Maven:

- package-ecosystem: "maven"
  directory: "/"
  schedule:
    interval: "daily"
  commit-message:
    prefix: "mvn"
  target-branch: "develop"
  allow:
    - dependency-name: "org.springframework.boot:*"

四、在 GitHub Actions 中运行 Dependabot

GitHub.com 上的 Dependabot 通过 github/dependabot-action 运行。对于 GitHub Enterprise Server,需要手动同步此 Action。

手动触发 Dependabot 循环

# .github/workflows/dependabot-trigger.yml
name: Manual Dependabot Update

on:
  workflow_dispatch:
    inputs:
      package-ecosystem:
        description: 'Package ecosystem (npm, pip, etc.)'
        required: true
        default: 'pip'

jobs:
  dependabot:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Run Dependabot
        uses: github/dependabot-action@v2
        with:
          package-ecosystem: ${{ github.event.inputs.package-ecosystem }}
          directory: "/"
          target-branch: main

GHES 手动同步步骤

如果你的企业在用 GHES,需要手动同步 Dependabot Action:

# 1. 从 GitHub.com 下载 Action
gh release download v2.40.0 -p dependabot-action -o /path/to/actions

# 2. 上传到 GHES 实例的本地 Action 存储
cp -r /path/to/actions /var/lib/ghes/actions-runner/_work/

# 3. 配置 GitHub Enterprise Server 使用本地 Action

详见 GHES 手动同步文档

五、Dependabot 与安全

配置漏洞自动修复

# .github/dependabot.yml
security-updates:
  enabled: true
  open-pull-requests-limit: 3

启用后,Critical/High 漏洞会触发紧急 PR,不受 updates 中 schedule 约束。

配合 GitHub Advisory Database

  • GitHub 自动扫描依赖树
  • 发现漏洞后立即在 Security 标签页显示
  • 同时在 Dependabot Alerts 中列出

合并策略

# 区分开发依赖和生产依赖的合并策略
- package-ecosystem: "pip"
  directory: "/"
  schedule:
    interval: "daily"
  open-pull-requests-limit: 3

  # 只有开发依赖可以自动合并
  allow:
    - dependency-name: "*"
      update-types: ["version-update:semver-patch"]
      dependency-type: "development"

  # 生产依赖必须人工审查
  labels:
    - "dependencies"
    - "requires-review"

六、分组与批量处理

大型项目中依赖很多,逐个 PR 处理太碎片化。Dependabot 支持分组:

updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      # 开发工具组(可以批量更新)
      dev-tools:
        patterns:
          - "eslint-*"
          - "prettier-*"
          - "babel-*"
      # UI 库组
      ui-libs:
        patterns:
          - "@mui/*"
          - "antd"
          - "radix-*"

七、一次安全漏洞从发现到修复的完整路径

以 Express 4.18 后端仓库为例,已开启 Security Updates:

  1. 漏洞入库:Express 4.18 的一个 RCE 漏洞被收入 GitHub Advisory Database,标记为 Critical。
  2. Alerts 触发:GitHub 扫描仓库的 package-lock.json,发现依赖树包含 express@4.18.2,在 Security 标签页生成告警,同时通知仓库管理员。
  3. Security Update PR 生成:因为配了 security-updates: enabled: true,Dependabot 不等 weekly schedule,直接创建一个 PR,把 express 升到修复版本 4.19.0,PR 标题为 build(deps): bump express from 4.18.2 to 4.19.0
  4. CI 验证:PR 触发 GitHub Actions,跑 lint → test → build。如果 CI 挂了——比如某个中间件不兼容 4.19.0——PR 不会自动合并,开发者需要手动介入。
  5. 审查与合并CODEOWNERSpackage.json 分配给 @org/backend-team,团队 review changelog、确认 CI 通过后合并。
  6. 自动化兜底:如果 CI 全绿且 allow 配置了 dependency-type: "development" 的 auto-merge 策略,patch 级更新可以直接合入——但本例是生产依赖,不走自动合并。

这条路径里的关键设计是:告警、扫描、PR 创建、CI 验证各自独立——Dependabot 不替你判断"能不能合",只负责把选择推到人面前。

八、实践建议

1. 配置合理的更新频率

依赖类型建议频率理由
生产核心依赖weekly更新越频繁,每次变更越小,出问题时回溯范围也越小
开发工具biweeklyESLint、Prettier 等工具链变更对运行时无影响,降低噪音
GitHub ActionsmonthlyAction 版本变更通常只涉及 CI 行为,不需要高频追踪
底层基础设施monthly数据库驱动、框架大版本等,稳定性优先

2. 设置合并门禁

# Branch Protection Rules 配合
require_status_checks:
  - context: "dependabot/npm/version-update"
  - context: "dependabot/maven/version-update"

rules:
  required-signature: false
  dismissal-latest: true

3. 使用 CODEOWNERS 控制审查流

# CODEOWNERS
/.github/dependabot.yml @org/devops-team
package.json @org/frontend-team
requirements.txt @org/backend-team
pom.xml @org/java-team

4. 监控 Dependabot 指标

# 使用 GitHub GraphQL API 查询依赖图指标
# 将 YOUR_ORG/YOUR_REPO 替换为实际仓库
jobs:
  metrics:
    runs-on: ubuntu-latest
    steps:
      - name: Get Dependabot metrics
        run: |
          gh api graphql -f query='
            {
              repository(owner:"YOUR_ORG", name:"YOUR_REPO") {
                dependencyGraphManifests(first: 10) {
                  nodes {
                    filename
                    dependencies {
                      nodes {
                        packageName
                        requirements { requires }
                      }
                    }
                  }
                }
              }
            }'

九、常见问题

Q: 团队维护 30 个微服务仓库,Dependabot 每周创建 40+ 个 PR——低风险更新能不能自动合入?

不能直接合入,需要额外配置。Dependabot 只负责把 PR 送到你面前,合并必须过 Branch Protection Rules。想让 patch 级开发依赖自动合入,需要两步:先在 .github/dependabot.yml 中用 allow 限定范围(比如 dependency-type: "development"update-types: ["version-update:semver-patch"]),再配 GitHub Actions 或第三方 bot 在 CI 全绿时 auto-merge。生产依赖不建议走自动合并,哪怕 CI 全绿。

Q: monorepo 里 lodash@4.17.20 被一个 EOL 旧模块锁死了,在找到替代方案前不能动——怎么让 Dependabot 别再提这个 PR?

ignore 配置跳过特定版本:

ignore:
  - dependency-name: "lodash"
    versions: ["4.17.20"]
  - dependency-name: "express"
    update-types: ["version-update:semver-major"]

第一个 rule 按版本号精确跳过,第二个 rule 跳过所有大版本更新。如果你的项目不希望 Dependabot 对某个包提任何 PR,只写 dependency-name 不加 versions 即可。

Q: 公司有私有 npm registry(npm.mycompany.com),Dependabot 能扫描里面的内部包吗?

可以,但需要配 registry 认证:

registries:
  my-npm-registry:
    type: "npm-registry"
    url: "https://npm.mycompany.com"
    token: "${{ secrets.NPM_TOKEN }}"

前提是私有 registry 实现了 npm registry API(应用程序接口)且包版本遵循 semver。如果内部包不走 semver 或 registry 不兼容标准 API,Dependabot 无法解析版本,需要换 Renovate 或自定义方案。

Q: Dependabot 和 Renovate 选哪个?

Dependabot 的优势是零额外服务、GitHub 原生集成、Security Alerts 直接联动——如果你的依赖生态不超过 3 种、不需要跨仓库统一配置、Security Updates 是刚需,Dependabot 就够用。Renovate 在以下场景更强:跨仓库共享 preset 配置、需要细粒度分组规则、依赖仪表盘展示、合并策略高度自定义。简化的判断标准:全在 GitHub 生态内 → Dependabot;跨 GitLab/Bitbucket 或需要统一治理 → Renovate。

Q: PR 数量太多看不过来怎么办?

三个手段组合使用:第一,用 open-pull-requests-limit 限制同时打开的 PR 数;第二,用 groups 把同类依赖打包进一个 PR(比如所有 ESLint 插件合成一个 “update dev tools” PR);第三,调整 schedule interval ——把开发工具从 weekly 降到 monthly,减少噪音。如果 PR 仍然过多,回溯检查是否该用 ignore 跳过某些高频但不关键的依赖。

采用的优先级

Dependabot 的配置工作量和收益不是线性的。建议按以下顺序落地:

  1. 先开 Alerts(零配置,在仓库 Settings → Code security 中勾选即生效)。这是收益最高的第一步——你至少能知道哪些依赖有已知漏洞。
  2. 再配 Security Updates(一行 YAML:security-updates: enabled: true)。让 Critical/High 漏洞自动生成修复 PR,把响应时间从"下次有人想起来"缩短到小时级。
  3. 然后上 Version Updates(写 .github/dependabot.yml)。先从一个生态系统开始(比如 npm),跑两周看 PR 质量和 CI 通过率,再扩展到其他生态系统。
  4. 最后加分组和 auto-merge 策略。前提是 CI 覆盖率够高——如果测试不足以拦住回归,auto-merge 反而引入风险。

如果你的仓库依赖少、更新频率低(比如一个静态站点),Alerts 就够了,不需要配 Version Updates。Dependabot 的价值体现在依赖多、生态杂、安全要求高的项目上——配得越重,回报递减越明显。

自测

  1. 你的仓库用的是 requirements.txt,Dependabot 的 package-ecosystem 应该填什么值?directory 应该填 / 还是 /backend
  2. Dependabot Alerts 和 Security Updates 之间最本质的区别是什么?(不是"一个发告警一个发 PR"——而是时间维度上,Security Updates 绕过了什么?)
  3. 你收到一个标题为 build(deps): bump express from 4.18.2 to 4.19.0 的 PR——标题里哪两个前缀让你判断它来自 Dependabot?你能确认它是 Version Update 还是 Security Update 吗?
  4. 团队的一个 Markdown 文档站点没有任何运行时依赖——你应该只开 Alerts 还是配完整的 .github/dependabot.yml?给出理由。

相关资源: