Skip to main content

renovate-apply

MIT License Python 3.15+ PyPI version Documentation tests CodeQL Quality Gate Status codecov Ruff uv prek

Apply the dependency updates Renovate finds, in your working copy, without a pull request. One commit per group, the same grouping your Renovate configuration gives a pull request. Nothing is pushed.

Full documentation: https://jbsilva.github.io/renovate-apply/

$ rnv
renovate-apply: scanning /home/you/infra ...
applied  deps: update the atuin images
    ghcr.io/atuinsh/atuin  v18.13.3 -> 18.22.0
    postgres               18-alpine, new digest
applied  deps: update the hook revs
    astral-sh/ruff-pre-commit  v0.16.5 -> v0.16.8
    crate-ci/typos             v1.50.1 -> v1.50.2

Committed. Nothing is pushed.

Why this exists

Renovate can read a local working copy. renovate --platform=local finds every pending update and reports it. It cannot write one: the local platform turns the run into a lookup-only dry run as it starts, so the run ends after the lookup, before the step that edits a file. No flag turns that off, because the clamp is inside the platform, not in the configuration.

So the updates Renovate finds on your laptop can only be applied by hand, or by merging the pull requests it opens on the server. This tool is the missing half: it runs that same scan, reads the JSON report, and makes the replacement the report describes for each update.

The edit is not guesswork. For every dependency, the report carries replaceString, the exact text the manager found in the file, and autoReplaceStringTemplate, how to write that text again with the new version or digest in it. That pair is Renovate's own auto-replace, handed over as data.

Highlights

  • Works with everything Renovate's own managers report: image tags and digests in compose files and Dockerfiles, GitHub Actions SHA pins with their version comment, pre-commit and prek hook revs, versions matched by a custom regex manager, and the rest
  • One commit per Renovate branch, so a grouped pull request and a local run produce the same commits
  • Refreshes uv.lock when it raises a floor in pyproject.toml, and commits the two together, the way Renovate's own pull request carries them
  • Reads your repository's Renovate configuration by running Renovate itself, so grouping, holds, package rules and versioning schemes all apply without being restated here
  • Holds every major back until you ask for it
  • Never skips your git hooks, and never commits anything it did not write
  • Never leaves a pyproject.toml that does not lock: such a group is undone and held back
  • --dry-run to read first, --no-commit or --stage to review everything at once

Requirements

  • Python 3.15+
  • git
  • Either renovate on PATH (npm i -g renovate) or Node.js, for npx to fetch it
  • Optional: gh, logged in, or GITHUB_TOKEN in the environment. Without a token, everything Renovate looks up on GitHub is rate limited, and updates can silently go missing. Prefer either to --token, which puts the token in argv and in your shell history.

Installation

uv tool install renovate-apply

Or run it without installing:

uvx renovate-apply --dry-run

Usage

$ renovate-apply --help
Command What it does
rnv Scan, apply, one commit per group
rnv --dry-run Say what would change and write nothing
rnv --no-commit Write the files and stop, for one review of everything
rnv --stage Write and stage the files, and commit nothing
rnv --major Include the major updates, which are held back by default
rnv --skip python Hold a dependency back by name, as a glob, repeatable
rnv --prefix "build(deps):" Set the first word of every commit subject
rnv --no-lock Do not refresh uv.lock after editing a pyproject.toml
rnv ~/code/other-repo Work on another repository

renovate-apply and rnv are the same command.

The working copy must be clean before a run that commits: a commit takes the whole index, not only the files this staged, so anything else in flight would be swept into a dependency commit.

Commit messages

The subject says what a person needs in git log --oneline; the body lists the group, aligned:

deps: update the action pins

astral-sh/setup-uv          v10.1.0 -> v10.2.0
github/codeql-action        v4.38.0 -> v4.38.2
docker/setup-buildx-action  v4.3.0 -> v4.4.1
actions/upload-artifact     v7.0.1 -> v7.0.2

Match --prefix to what your renovate.json5 writes, so local commits and merged pull requests read alike: deps: for commitMessagePrefix, build(deps): for semantic commits.

Per-repository defaults

Any option can be set once, in the pyproject.toml of the repository being updated:

[tool.renovate-apply]
prefix = "build(deps):"
skip = ["python"]

The file is read from the directory being updated, so rnv ~/code/other-repo takes that repository's settings and not those of wherever you happen to be standing. Only that directory is read, never a parent of it, and a flag typed for one run wins over the file.

A repository without a pyproject.toml (an infrastructure repository, say) passes the flags instead.

What is held back

Nothing is applied silently past a hold. Whatever is held is listed at the end of the run, with the reason:

  • Majors, unless --major. Renovate can be configured to send some majors to the dependency dashboard to be approved by hand. The report does not say which ones carry that flag, so holding every major is the only reading that cannot contradict your configuration.
  • Updates Renovate would not open yet, the ones still waiting out minimumReleaseAge. A security fix bypasses that hold in Renovate, and bypasses it here too.
  • Renames, where Renovate wants to replace a dependency with a different one. That edit is not a version bump, and this tool does not write it.
  • Lock file updates, where the range in the manifest already allows the new version, so only the lock file beside it moves. There is no edit to make in the package file, and moving the lock file takes that package manager. Only uv.lock is refreshed here, after an edit to its manifest.
  • Updates that do not lock, where uv lock finds no solution for the new floor in pyproject.toml. The group is undone, uv.lock included, and uv's explanation is printed.
  • A line two managers found, when a regex manager in your Renovate configuration matches a line a built-in manager also reads. Renovate reports the line twice. The first update makes the edit, and the second is listed with it.
  • Anything named in --skip, as a glob. That is the answer to the blind spot above on an update that is not a major: a repository that keeps requires-python on the dependency dashboard writes skip = ["python"] once and stops being asked.

Limits

  • dependencyDashboardApproval is invisible. Renovate resolves it per package and the report does not carry it, so this tool cannot see which updates your configuration wants approved by hand. Holding every major covers the usual case; --skip covers the rest.
  • Lock files: uv only. A pyproject.toml with a uv.lock beside it is relocked and committed together. Any other package manager's lock file is left untouched, so run its update yourself.
  • Renovate's lock file maintenance is not applied. Those branches carry no dependency updates, so they are not in the report at all.
  • A group that cannot be applied is reported and passed over. The groups after it are still applied and committed, and the run ends non-zero. Only a failure before the first group, such as a scan that did not run or a working copy that is not clean, ends the run with nothing done.
  • The scan is a full Renovate run, so it takes as long as Renovate takes, usually under a minute.
  • A dependency Renovate cannot look up is one this cannot apply. Everything upstream of the report is Renovate's own behavior, configuration included.
  • This writes files and commits. It never pushes, never merges and never deploys.

Development

uv sync --group dev --group test
uv run pytest
uv run poe check
uv run poe docs   # preview the documentation site

License

MIT. See LICENSE.

Metadata

Release files for renovate-apply 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for renovate-apply 0.1.0
File Size Uploaded
renovate_apply-0.1.0.tar.gz 27.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for renovate-apply 0.1.0
File Interpreter ABI Platform
renovate_apply-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 58.5 kB

Release files / renovate_apply-0.1.0.tar.gz

Download URL renovate_apply-0.1.0.tar.gz
Size 27.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0ee5a2e27412a90c8e03c2bf157b4df04f070e7aaa4d0cac7b8dd7c798be394a
BLAKE2b-256 checksum
How to use checksums
0630ef883212397acd2c9cd7e9ddce2ff6bbce6d861d9fb8b85e7ec6e5bd942f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / renovate_apply-0.1.0-py3-none-any.whl

Download URL renovate_apply-0.1.0-py3-none-any.whl
Size 30.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
827998cd4344b6e1c370ce73dbf1c2e5cb0007fb5e63a6b2fb20274a4f708c9d
BLAKE2b-256 checksum
How to use checksums
586a191b3138731ab8792993797b48b4008cfdbf17875d9c0f465db93239c5ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page