Updates the dependencies of your project with pnpm, keeps the pinned
pnpm (packageManager / devEngines.packageManager) and Node.js
(devEngines.runtime) versions fresh — by default within their current major
versions — and opens a pull request with the result. It can optionally update
the GitHub Actions pinned in your workflow files too. By default the lockfile
is regenerated from scratch, so transitive dependencies of unchanged packages
are refreshed too.
The default setup needs no secrets: the built-in GITHUB_TOKEN is enough to
update dependencies, pnpm, and Node.js, validate them with your own verify
commands, and open a pull request.
Unlike external dependency bots, this action runs pnpm itself, so it supports every feature of your workspace: catalogs, patched dependencies, config dependencies, overrides, and anything pnpm learns in the future.
The action expects pnpm (and a runtime, if your project needs one for
verification) to already be set up — pair it with pnpm/setup.
name: Update Dependencies
on:
schedule:
- cron: '0 0 * * 1' # Every Monday at midnight UTC
workflow_dispatch: {}
permissions:
contents: write
pull-requests: write
concurrency:
group: update-dependencies
cancel-in-progress: false
jobs:
update-dependencies:
if: github.repository == 'your-org/your-repo' # Don't run on forks
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
# Installs the pnpm version from `packageManager` and the runtime
# from `devEngines.runtime`.
- uses: pnpm/setup@v1
- uses: pnpm/update@v0
with:
verify: |
pnpm build
pnpm testThe action can also bump the GitHub Actions pinned in .github/workflows/*.yml
and action.yml (via pnpm update --include-github-actions). This is opt-in
(github-actions: true) because GitHub does not let the default GITHUB_TOKEN
push changes to workflow files — you must pass a token that carries the
workflow scope (a PAT) or workflows: write (a GitHub App). Without such a
token the push fails as soon as an action needs updating.
- uses: pnpm/update@v0
with:
github-actions: true
token: ${{ secrets.UPDATE_TOKEN }} # PAT with `repo` + `workflow`GitHub Actions updates ride along with the dependency update, so they only
happen when update-deps is latest or ranges (not false).
To refresh the lockfile to the latest versions matching your package.json
ranges without touching any manifests (and, in this example, follow pnpm's
prereleases while propagating updated versions into other files):
- uses: pnpm/update@v0
with:
update-deps: false
update-pnpm: next-12
# Follow prereleases as soon as they are published: pnpm 12's
# default 24-hour minimumReleaseAge would otherwise hold a
# same-day release back from self-update.
update-pnpm-minimum-release-age: 0
post-update: pnpm update-manifests
token: ${{ secrets.UPDATE_TOKEN }}The action's logic lives in scripts/ so it can be tested outside of a live
workflow:
scripts/lib.sh— pure helpers (update-argument construction,update-depsvalidation, Node.js-major extraction), unit-tested intest/lib.bats.scripts/update.sh— the whole "Update dependencies" step, driven end-to-end intest/update.batsagainst a stubbedpnpm(test/stubs/pnpm) that records the commands it would run.
Run the checks with shellcheck and bats:
shellcheck scripts/*.sh
bats test/CI runs both on every push and pull request.
