# dependabot.yml configuration complete guide: master schedule, groups, cooldown, ignore, registries, and monorepos in real code

> A configuration complete guide for writing GitHub's dependabot.yml at production quality. Faithful to the official configuration reference (as of June 2026), it explains, with copy-pasteable real examples, the full supported list of package-ecosystem, directory and directories (glob), schedule and cooldown, groups (applies-to / group-by), the priority of allow and ignore, registries and private-registry authentication, commit-message, target-branch, and multi-ecosystem-groups.

- Published: 2026-06-28
- Author: 友田 陽大
- Tags: Dependabot, GitHub Actions, 依存関係管理, DevSecOps, サプライチェーンセキュリティ, 設定ファイル
- URL: https://tomodahinata.com/en/blog/dependabot-yml-configuration-complete-guide
- Category: Dependabot & dependency automation
- Pillar guide: https://tomodahinata.com/en/blog/dependabot-production-guide

## Key points

- dependabot.yml requires version: 2 and updates. Each updates entry's minimal unit is 'package-ecosystem × directory (or directories) × schedule.interval'.
- Structurally suppress a PR flood with groups (bundle), cooldown (let just-released ones rest), and open-pull-requests-limit (cap). groups also works on security updates with applies-to: security-updates.
- A dependency that matched both allow and ignore — 'ignore wins.' Since ignore easily becomes a hotbed of stagnation, keep it to a limited specification using update-types, and make it a stock-taking target.
- Define a private registry in the top-level registries and pass credentials with a Dependabot secret (${{secrets.NAME}}). Don't hardcode them in the repo.
- For a monorepo, consolidate into one entry with a directories glob (e.g., /packages/*), and make a cross-directory bundled PR with group-by: dependency-name. You can also bundle multiple ecosystems into one PR with multi-ecosystem-groups.

---

`dependabot.yml` is a "place it and it works" file, but **placing it carelessly floods PRs, and writing it carefully quietly automates dependency management** — almost all of that difference is packed into this file. This article, as a specific of [the Dependabot production-operation guide](/blog/dependabot-production-guide), explains **all the options of `dependabot.yml` in real code.** I wrote it as a **reference** to keep on hand and look up.

> **The rules of this article**: key names, defaults, and supported ecosystems are based on **GitHub's official configuration reference (as of June 2026).** Dependabot adds options fast, and `cooldown`, `directories` (glob), and `multi-ecosystem-groups` are relatively new features. Always confirm the latest at the [official reference](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference) before production.

---

## 0. The file's location and overall structure

The placement is **`.github/dependabot.yml` right under the repo** (YAML). There are only four top-level keys.

```yaml
version: 2          # 必須。現行スキーマは 2
updates:            # 必須。エコシステムごとの更新設定（配列）
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
registries:         # 任意。プライベートレジストリの認証情報
  # ...
multi-ecosystem-groups:  # 任意。複数エコシステムを1PRに束ねる（新機能）
  # ...
```

**Each entry** of the `updates` array is one update job. The minimal unit is the three of **`package-ecosystem` (what) × `directory` / `directories` (where) × `schedule.interval` (at what frequency).** From here, we flesh it out.

---

## 1. package-ecosystem: supported ecosystems

`package-ecosystem` specifies the target package manager to update. As of June 2026, what's supported is the following (the official list).

> Bazel, Bundler, Bun, Cargo, Composer, Conda, Deno, Devcontainers, Docker, Docker Compose, Dotnet SDK, Elm, GitHub Actions, Gitsubmodule, Gomod, Gradle, Helm, Hex, Julia, Maven, Nix flakes, NPM and Yarn, NuGet, OpenTofu, Pip, pre-commit, Pub, Rust toolchain, sbt, Swift, Terraform, UV, vcpkg

The **identifier** to write in the config file has a fixed notation. Let me list commonly-used ones.

| Ecosystem | Value of `package-ecosystem` | Main target files |
| --- | --- | --- |
| npm / yarn / pnpm | `npm` | `package.json`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml` |
| Python (pip/uv) | `pip` / `uv` | `requirements.txt`, `pyproject.toml`, `uv.lock` |
| Go modules | `gomod` | `go.mod`, `go.sum` |
| Docker | `docker` | `Dockerfile` |
| GitHub Actions | `github-actions` | `.github/workflows/*.yml` |
| Terraform | `terraform` | `*.tf` |
| Ruby | `bundler` | `Gemfile`, `Gemfile.lock` |
| Rust | `cargo` | `Cargo.toml`, `Cargo.lock` |
| Java | `maven` / `gradle` | `pom.xml` / `build.gradle` |

> **Always include `github-actions`**: the version of an action you `uses:` in a workflow (especially SHA-pinned) is also a dependency. If you don't make it an update target, you can't notice an old or compromised action that slipped into CI. From the supply-chain-defense viewpoint, it's top-priority class.

---

## 2. directory / directories: where to look

### 2.1 A single directory

```yaml
  - package-ecosystem: "npm"
    directory: "/"          # リポジトリ直下の package.json
    schedule:
      interval: "weekly"
```

### 2.2 Multiple directories, glob (the protagonist of monorepos)

`directories` (plural) is an **array,** and moreover can use a **glob (`*` / `**`).** It's powerful that in a monorepo you can **consolidate** `packages/a`, `packages/b`, ... **into one entry.**

```yaml
  - package-ecosystem: "npm"
    directories:
      - "/"
      - "/apps/*"        # apps 配下の各アプリ
      - "/packages/**"   # packages 配下を再帰的に
    schedule:
      interval: "weekly"
```

In the era without this, you wrote as many `updates` entries as the number of directories. Getting by with one glob line is DRY itself.

---

## 3. schedule: when to run

```yaml
    schedule:
      interval: "weekly"      # daily / weekly / monthly / quarterly / semiannually / yearly / cron
      day: "monday"           # interval が weekly のとき
      time: "06:00"           # HH:MM（24時間制）
      timezone: "Asia/Tokyo"  # IANA タイムゾーン
```

- `interval` can specify, in addition to **`daily` / `weekly` / `monthly`,** also **`quarterly` / `semiannually` / `yearly` / `cron`** (flexibility of the update frequency).
- Leaning to **outside business hours** with `time` + `timezone` avoids PRs lining up first thing in the morning.
- Note that security updates run on vulnerability detection **regardless of the schedule** (`schedule` is the frequency of version updates).

> A practical tip: `daily` is often too much for active repos. Start with **`weekly` + the `groups` / `cooldown` described later,** and raise the frequency if stagnation appears — that's safe.

---

## 4. groups: bundle multiple updates into one PR

The mainstay of PR-flood countermeasures. With `groups`, bundle **related updates into one PR.**

```yaml
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      # 型定義はまとめて
      types:
        patterns: ["@types/*"]
      # テスト系をまとめて
      testing:
        patterns: ["jest", "vitest", "@testing-library/*", "playwright"]
      # 上記以外の patch / minor をまとめる（major は個別PRのまま残す）
      minor-and-patch:
        update-types: ["minor", "patch"]
        exclude-patterns: ["@types/*", "jest", "vitest"]
```

The keys usable in each group under `groups`:

| Key | Meaning |
| --- | --- |
| `patterns` | the pattern of dependency names to include in the group (`*` wildcard OK) |
| `exclude-patterns` | the pattern to exclude from the group |
| `applies-to` | `version-updates` (default) or `security-updates`. **You can make the group work on security updates too** |
| `dependency-type` | `development` or `production` |
| `update-types` | which of `patch` / `minor` / `major` to include |
| `group-by` | `dependency-name`. **Bundle the same dependency cross-directory in a monorepo** |

### 4.1 Bundle security updates too

```yaml
    groups:
      security-all:
        applies-to: security-updates   # セキュリティ更新を1PRに束ねる
        patterns: ["*"]
```

But as an official constraint, **you can't group across different ecosystems, and you can't mix security updates and version updates in the same PR.**

### 4.2 Bundle cross-directory in a monorepo

```yaml
  - package-ecosystem: "npm"
    directories: ["/apps/*"]
    schedule:
      interval: "weekly"
    groups:
      react-across-apps:
        patterns: ["react", "react-dom"]
        group-by: "dependency-name"   # 全 app の react 更新を1PRに
```

---

## 5. cooldown: let just-released ones rest

`cooldown` (a newer option) is a buffer that **doesn't open a PR until a certain number of days pass from a new version's publication.** It makes you less likely to step on a version yanked right after publication or a fresh-out regression.

```yaml
    cooldown:
      default-days: 7         # 既定で7日待つ
      semver-major-days: 30   # major は30日
      semver-minor-days: 14   # minor は14日
      semver-patch-days: 3    # patch は3日
      include: ["next", "react"]   # 対象を限定（最大150）
      exclude: ["@types/*"]        # 対象から除外（最大150）
```

- You can vary the waiting days per SemVer level (the more major, the more cautious).
- `cooldown` is **applied to version updates** and not to security updates (= urgent fixes). This is reasonable and matches the operational philosophy "freshness maintenance isn't urgent, vulnerability fixes are urgent."

---

## 6. allow / ignore: narrowing the target and excluding

### 6.1 allow: explicitly make it a target

```yaml
    allow:
      - dependency-type: "direct"      # direct / indirect / all / production / development
      - dependency-name: "express"
        # update-types で粒度も指定可
```

### 6.2 ignore: take it out of the target

```yaml
    ignore:
      # この依存は完全に無視
      - dependency-name: "aws-sdk"
      # major だけ無視（patch/minorは追従する）— 実務で最も使う形
      - dependency-name: "react"
        update-types: ["version-update:semver-major"]
      # 特定バージョン範囲を無視
      - dependency-name: "lodash"
        versions: [">= 5.0.0"]
```

> **Priority (important)**: when a dependency matches **both `allow` and `ignore`, `ignore` wins** (= it's ignored). The official clearly states "first narrow the target with allow, then exclude with ignore. If it applies to both, ignore."

> **Beware of ignore stagnation**: ignoring with "I don't want to bump major now" is reasonable, but **forgetting it as-is leaves no escape when a vulnerability appears.** **Limit the range** like `update-types: ["version-update:semver-major"]` and operate with a quarterly stock-taking review. `ignore` tends to be a hideout for technical debt.

---

## 7. The PR's appearance and handling

```yaml
    open-pull-requests-limit: 10        # 同時に開くPRの上限（バージョン更新の既定は5）
    target-branch: "develop"            # 既定ブランチ以外を対象にする
    labels: ["dependencies", "automerge"]   # PRに付けるラベル（既定を置き換える）
    assignees: ["your-team-lead"]       # アサイン先
    milestone: 4                        # マイルストーン番号
    commit-message:
      prefix: "chore(deps)"             # 通常依存のコミット接頭辞（最大50文字）
      prefix-development: "chore(deps-dev)"  # 開発依存用
      include: "scope"                  # スコープ（依存名）を件名に含める
    pull-request-branch-name:
      separator: "-"                    # Dependable のブランチ名の区切り文字
    rebase-strategy: "auto"             # auto / disabled / in-range
    versioning-strategy: "increase"     # エコシステム依存（lockfile-only 等も）
```

- **`open-pull-requests-limit`**: the default for version updates is **5.** Match it to the team's review processing capacity. **Security updates are fixed at 10** (unchangeable).
- **`commit-message.prefix`**: aligning to Conventional Commits (`chore(deps):`) has good compatibility with automation like `semantic-release`.
- **`labels`**: note that it **replaces** the default labels (not adds). The design of driving an auto-merge workflow with an `automerge` label is also standard.
- **`reviewers` is being deprecated.** The current recommendation is to lean reviewer specification toward `CODEOWNERS` or branch-protection's required reviews.

---

## 8. registries: private-registry authentication

You can also update dependencies of an internal registry (Artifactory, GitHub Packages, npm Enterprise, a private PyPI, etc.). **Never hardcode credentials; pass them with a Dependabot secret.**

```yaml
version: 2
registries:
  npm-private:
    type: npm-registry
    url: https://npm.pkg.github.com
    token: ${{secrets.DEPENDABOT_NPM_TOKEN}}   # Dependabot シークレットを参照
  python-artifactory:
    type: python-index
    url: https://artifactory.example.com/api/pypi/pypi/simple
    username: ${{secrets.ARTIFACTORY_USER}}
    password: ${{secrets.ARTIFACTORY_PASSWORD}}

updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    registries:
      - npm-private        # この更新ジョブで使うレジストリを紐づける
```

Points:

- What you reference with `${{secrets.NAME}}` is the **Dependabot-dedicated secret store** (**Settings → Secrets and variables → Dependabot**). It's a **separate thing from the normal Actions secrets** — because so that a compromised dependency can't steal secrets, the Dependabot workflow by design normally can't access Actions secrets.
- For a **registry inside a network** unreachable from outside, reach it by running Dependabot on a **self-hosted runner.**

---

## 9. multi-ecosystem-groups: multiple ecosystems into one PR

`multi-ecosystem-groups` (a new feature) is a mechanism to bundle **updates of different ecosystems across into one PR.** For example, use it in a case like "I want to bump a Docker base image and the npm dependencies that run on it together."

```yaml
version: 2
multi-ecosystem-groups:
  app-stack:
    schedule:
      interval: "weekly"

updates:
  - package-ecosystem: "npm"
    directory: "/"
    multi-ecosystem-group: "app-stack"   # このジョブをグループに所属させる
  - package-ecosystem: "docker"
    directory: "/"
    multi-ecosystem-group: "app-stack"
```

Whereas a normal `groups` is a bundle **within one ecosystem,** `multi-ecosystem-groups` differs in that it **crosses ecosystems.** Since abusing it makes the PR huge and hard to review, limiting it to **strongly-related combinations** is KISS.

---

## 10. The completed form: a battle-ready dependabot.yml (Next.js × Docker × Actions)

A **production template you can use as-is,** bundling everything up to here.

```yaml
version: 2

updates:
  # ── アプリ依存（npm） ───────────────────────────
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "06:00"
      timezone: "Asia/Tokyo"
    open-pull-requests-limit: 10
    commit-message:
      prefix: "chore(deps)"
      prefix-development: "chore(deps-dev)"
      include: "scope"
    cooldown:
      default-days: 7
      semver-major-days: 30
    groups:
      types:
        patterns: ["@types/*"]
      minor-and-patch:
        update-types: ["minor", "patch"]
        exclude-patterns: ["@types/*"]
    ignore:
      # major は人間が棚卸しで判断（patch/minor は自動追従）
      - dependency-name: "*"
        update-types: ["version-update:semver-major"]
    labels: ["dependencies"]

  # ── Docker ベースイメージ ───────────────────────
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"
    commit-message:
      prefix: "chore(docker)"

  # ── GitHub Actions（サプライチェーン防御の要） ──
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    commit-message:
      prefix: "ci"
```

The intent of this configuration:

- **Auto-follow patch/minor bundled with groups,** **stop major with `ignore` and let a human do the stock-taking** — concentrate the review load on "changes with substance."
- Avoid fresh-out regressions with **cooldown.**
- Include **Docker and GitHub Actions** as targets too, protecting the base image and CI supply chain at the same time.
- Align the commit prefix to Conventional Commits, consistent with release automation.

How to auto-merge the major stopped by this `ignore` and the patch/minor flowed by groups, go to [the auto-merge × GitHub Actions automation guide](/blog/dependabot-auto-merge-github-actions-automation-guide). The vulnerability-response settings (grouped security updates / auto-triage) are handled in [the alerts / security-updates guide](/blog/dependabot-security-updates-alerts-vulnerability-management-guide).

---

## 11. FAQ

**Q. How do I use `directory` and `directories` differently?**
A. For a single one, `directory: "/"`; for multiple or a monorepo, `directories: ["/apps/*", "/packages/**"]` (glob OK). The latter avoids entry duplication.

**Q. I want to stop only major auto-updates.**
A. Specify `update-types: ["version-update:semver-major"]` in `ignore`. patch/minor follow while only major stops. Make it a stock-taking target to prevent stagnation.

**Q. What if allow and ignore conflict?**
A. **ignore takes priority** (it's ignored).

**Q. Where do I put the private-registry token?**
A. Put it in a **Dependabot secret** (Settings → Secrets and variables → Dependabot) and reference it with `${{secrets.NAME}}`. It's a separate store from Actions secrets.

**Q. I want to confirm the settings are working.**
A. In the repo's **Insights → Dependency graph → Dependabot** tab, you can confirm each ecosystem's last run and logs.
