Keep WordPress core patched automatically with Dependabot
A tiny Dependabot config
that watches WordPress core (installed via Composer as
roots/wordpress)A and opens a
pull request whenever a patch release ships — which is how WordPress
delivers security fixes (e.g. 6.8.7 → 6.8.8).
Minor and major releases (e.g. 6.8 → 6.9) are ignored on purpose — those
are plugin/theme compatibility decisions you make by hand.
Requirements
Section titled “Requirements”-
A repository hosted on GitHub (Dependabot version updates are free and run on GitHub’s infrastructure — they do not use your Actions minutes).
-
WordPress core installed through Composer using
roots/wordpress. This is the common Bedrock-style layout. Yourcomposer.jsonshould have something like:{"require": {"roots/wordpress": "~6.8.7"},"config": {"allow-plugins": {"roots/wordpress-core-installer": true}},"extra": {"wordpress-install-dir": "public/wp"}} -
roots/wordpress-core-installerallowed as a plugin (shown above) so Dependabot can resolve the dependency tree.
The pattern works with any Composer-packaged WordPress core, but the dependency name must match what your composer.json directly requires.
Other good candidates:
Section titled “Other good candidates:”- roots/wordpress-full — core plus bundled themes/plugins
- roots/wordpress-no-content — core only, if required directly
- johnpbloch/wordpress — alternative meta-package
- johnpbloch/wordpress-core — core only, if required directly
Not using Composer for core (plain
wp-admin/wp-includeschecked into the repo, or WordPress managed by the built-in updater)? Then this file won’t do anything — Dependabot only sees dependencies declared in a manifest it understands. See “Alternatives” below.
Install
Section titled “Install”- Copy
dependabot.ymlto.github/dependabot.ymlin your repository root. - Commit and push to your default branch.
- Done. Dependabot picks it up automatically — no toggle to flip, no secrets.
You can watch it run under Insights → Dependency graph → Dependabot in your repo, and trigger a manual run with “Check for updates”.
What each setting does
Section titled “What each setting does”version: 2updates: - package-ecosystem: composer # read composer.json / composer.lock directory: / # manifest lives in the repo root schedule: interval: daily # scan every day (see "How often?" below) allow: - dependency-name: "roots/wordpress" # ONLY watch WordPress core cooldown: default-days: 0 # take a new patch immediately, no waiting commit-message: prefix: build # commit/PR title -> "build: bump ..." ignore: - dependency-name: "roots/wordpress" update-types: - version-update:semver-major # skip 6.x -> 7.x - version-update:semver-minor # skip 6.8 -> 6.9| Setting | Why it’s there |
|---|---|
package-ecosystem: composer | WordPress core is a Composer package here. |
directory: / | composer.json is at the repo root. |
allow: roots/wordpress | A real project has dozens of deps; this limits Dependabot to only core so you don’t get flooded with unrelated PRs. |
cooldown.default-days: 0 | Dependabot normally waits a few days before proposing a new release. Security patches shouldn’t wait. |
commit-message.prefix: build | Keeps titles consistent (handy for Conventional Commits / changelogs). |
ignore semver-minor/major | Core patches are safe to automate; a minor/major is a compatibility decision. This pins Dependabot to 6.8.x patches only. |
The result
Section titled “The result”When WordPress releases a patch, you get a PR titled like:
build: bump roots/wordpress from 6.8.7 to 6.8.8Review, let CI run, merge. Nothing auto-merges or auto-deploys — Dependabot only
proposes the bump. The actual install happens when your build/deploy runs
composer install after the merge.
How often should it run? Is daily expensive?
Section titled “How often should it run? Is daily expensive?”daily is free — Dependabot version updates don’t consume Actions minutes.
WordPress patches only ship every few weeks, so daily mostly means empty scans
and simply shortens the worst-case delay before a security-patch PR appears.
Prefer fewer scans? Use weekly:
schedule: interval: weeklyThe only thing that consumes CI minutes is your own workflows running on the PR — and those run per PR (release frequency), not per scan.
Auto-merge (optional)
Section titled “Auto-merge (optional)”If you trust core patches enough to merge without a human, add a small workflow that enables auto-merge for these PRs (requires branch protection with passing checks):
name: Dependabot auto-mergeon: pull_requestpermissions: contents: write pull-requests: writejobs: automerge: runs-on: ubuntu-latest if: github.actor == 'dependabot[bot]' steps: - uses: dependabot/fetch-metadata@v2 id: meta - if: steps.meta.outputs.update-type == 'version-update:semver-patch' run: gh pr merge --auto --squash "$PR_URL" env: PR_URL: ${{ github.event.pull_request.html_url }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}Adapting it
Section titled “Adapting it”- Different install dir / constraint: no change needed — Dependabot reads
whatever is in
composer.json. - Also want plugins/themes patched: add more
allowentries (e.g.wpackagist-plugin/*) or dropallowentirely to watch everything. Expect more PRs. - Group core + plugins into one PR: see Dependabot
groups.
Alternatives (when core isn’t a Composer dependency)
Section titled “Alternatives (when core isn’t a Composer dependency)”- Standard WordPress install: enable automatic background updates (WordPress
applies minor/security updates itself), or set
define( 'WP_AUTO_UPDATE_CORE', 'minor' );. - wpackagist: WordPress core isn’t on wpackagist; use
roots/wordpressas above.