Dependabot Configuration Example¶
- How to use this document
- Key concepts
- One grouped PR per ecosystem
- The 30-day cooldown
target-branchdoes not accept wildcards- File header
- Default branch entries
- npm
- GitHub Actions
- Docker
- Go modules
- Cargo
- Release branch entries
- Complete file
- References
How to use this document¶
This is an annotated walkthrough of a .github/dependabot.yml that projects can
copy as a starting point. Each section explains one block of the file; the
complete file at the end can be copied verbatim.
Adjust the ecosystem list to match what the repository actually uses — an entry for an ecosystem that is not present in the repository is harmless but noisy in the Dependabot job logs.
Key concepts¶
One grouped PR per ecosystem¶
Each ecosystem below groups all of its updates into a single pull request per run. Both regular version updates and security fixes are grouped, so Dependabot opens at most one PR per ecosystem. This matters because security updates are otherwise opened individually and ungrouped by default, which is how a repository ends up with a dozen open Dependabot PRs. Every grouped PR lands on its own Dependabot branch.
Grouping is expressed with two named groups per ecosystem, split by
applies-to:
groups:
npm:
applies-to: version-updates
patterns: ["*"]
npm-security:
applies-to: security-updates
patterns: ["*"]
patterns: ["*"] puts every dependency in that ecosystem into the group.
open-pull-requests-limit: 1 keeps the ecosystem to a single outstanding PR.
The 30-day cooldown¶
Every ecosystem sets a 30-day cooldown: a newly published version is not
proposed until it has been on the registry for 30 days. That window is the one
in which a compromised or typosquatted release is usually yanked, so waiting it
out avoids pulling a malicious release into the repository.
Two properties of cooldown are worth being explicit about:
- It applies to version updates only. Security updates driven by a published advisory are never delayed by it, so a real CVE fix still arrives immediately.
- A dependency still inside its cooldown is simply left out of that run's group PR and picked up on a later run once it becomes eligible. Nothing is lost.
Ecosystems with semver-aware version data can also set per-bump-type windows; where they are set below they use the same 30 days as the default:
target-branch does not accept wildcards¶
Dependabot does not support wildcards in target-branch. It accepts exactly one
branch name, and the repository default branch when omitted.
To run on release/* branches, every release branch needs its own duplicated
set of entries with target-branch set. The example below defines the
default-branch entries (no target-branch) plus one release branch; copy the
release block and change target-branch for any additional release branch.
File header¶
version: 2 is the only supported configuration version. Everything else lives
under updates: as a list of ecosystem entries.
Default branch entries¶
These entries omit target-branch, so they run against the repository's default
branch.
npm¶
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
semver-major-days: 30
semver-minor-days: 30
semver-patch-days: 30
groups:
npm:
applies-to: version-updates
patterns: ["*"]
npm-security:
applies-to: security-updates
patterns: ["*"]
directory: "/" (singular) points at a single manifest location — here the
package.json at the repository root. Use directories: (plural) instead when
the manifests are spread across the tree.
GitHub Actions¶
- package-ecosystem: github-actions
directories:
- "/"
- "/.github/actions/*"
- "/.github/workflows/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
groups:
github-actions:
applies-to: version-updates
patterns: ["*"]
github-actions-security:
applies-to: security-updates
patterns: ["*"]
The three directories cover the reusable workflows and composite actions a
repository may define in addition to the workflows themselves. Action versions
are not semver-addressable in the way registry packages are, so only
default-days is set.
Docker¶
- package-ecosystem: docker
directories:
- "**/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
groups:
docker:
applies-to: version-updates
patterns: ["*"]
docker-security:
applies-to: security-updates
patterns: ["*"]
directories: ["**/*"] searches the whole repository for Dockerfiles, which
avoids having to enumerate them. As with GitHub Actions, image tags are not
reliably semver, so only default-days is set.
Go modules¶
- package-ecosystem: gomod
directories:
- "**/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
semver-major-days: 30
semver-minor-days: 30
semver-patch-days: 30
groups:
gomod:
applies-to: version-updates
patterns: ["*"]
gomod-security:
applies-to: security-updates
patterns: ["*"]
directories: ["**/*"] picks up every go.mod in the repository, which covers
multi-module layouts without listing each module.
Cargo¶
- package-ecosystem: cargo
directories:
- "**/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
semver-major-days: 30
semver-minor-days: 30
semver-patch-days: 30
groups:
cargo:
applies-to: version-updates
patterns: ["*"]
cargo-security:
applies-to: security-updates
patterns: ["*"]
Same shape as the Go entry: a repository-wide search for Cargo.toml, weekly,
one grouped PR, 30-day cooldown on version updates.
Release branch entries¶
Because target-branch takes a single branch name,
supporting release branches means duplicating the entries above with
target-branch added. For example, for release/1.0:
- package-ecosystem: npm
directory: "/"
target-branch: "release/1.0"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
semver-major-days: 30
semver-minor-days: 30
semver-patch-days: 30
groups:
npm:
applies-to: version-updates
patterns: ["*"]
npm-security:
applies-to: security-updates
patterns: ["*"]
Repeat for each ecosystem the release branch uses, then copy the whole block and
change target-branch for every additional release branch. Keeping this list
pruned as release branches reach end of life avoids Dependabot jobs failing
against branches that no longer exist.
Complete file¶
# Dependabot configuration
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
#
# Each ecosystem groups ALL of its updates into a single PR per run. Both regular
# version updates and security fixes are grouped, so Dependabot opens at most one
# PR per ecosystem (security updates are otherwise opened individually and
# ungrouped by default). Every grouped PR lands on its own Dependabot branch.
#
# Every ecosystem also sets a 30-day `cooldown`: a newly published version is not
# proposed until it has been on the registry for 30 days, which is the window in
# which a compromised or typosquatted release is usually yanked. `cooldown`
# applies to version updates ONLY -- security updates driven by a published
# advisory are never delayed by it. A dependency still inside its cooldown is
# simply left out of that run's group PR and picked up once it becomes eligible.
#
# NOTE: Dependabot does not support wildcards in `target-branch` (it accepts
# exactly one branch name, and the default branch when omitted). To run on the
# release/* branches, every release branch needs its own duplicated set of
# entries with `target-branch` set. The default-branch entries (no
# `target-branch`) plus one release branch are defined below; copy the release
# block and change `target-branch` for any additional release/* branch.
version: 2
updates:
# ----------------------------------------------------------------------------
# Default branch
# ----------------------------------------------------------------------------
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
semver-major-days: 30
semver-minor-days: 30
semver-patch-days: 30
groups:
npm:
applies-to: version-updates
patterns: ["*"]
npm-security:
applies-to: security-updates
patterns: ["*"]
- package-ecosystem: github-actions
directories:
- "/"
- "/.github/actions/*"
- "/.github/workflows/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
groups:
github-actions:
applies-to: version-updates
patterns: ["*"]
github-actions-security:
applies-to: security-updates
patterns: ["*"]
- package-ecosystem: docker
directories:
- "**/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
groups:
docker:
applies-to: version-updates
patterns: ["*"]
docker-security:
applies-to: security-updates
patterns: ["*"]
- package-ecosystem: gomod
directories:
- "**/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
semver-major-days: 30
semver-minor-days: 30
semver-patch-days: 30
groups:
gomod:
applies-to: version-updates
patterns: ["*"]
gomod-security:
applies-to: security-updates
patterns: ["*"]
- package-ecosystem: cargo
directories:
- "**/*"
schedule:
interval: weekly
open-pull-requests-limit: 1
cooldown:
default-days: 30
semver-major-days: 30
semver-minor-days: 30
semver-patch-days: 30
groups:
cargo:
applies-to: version-updates
patterns: ["*"]
cargo-security:
applies-to: security-updates
patterns: ["*"]