bump-my-version rewrites your version strings and can commit the result
A small command line tool to simplify releasing software by updating all version strings in your source code by the correct increment and optionally commit and tag the changes.
At a glance
- What is it?
- bump-my-version is a Python command line tool that parses a version from your source files, works out the next one, replaces every occurrence, and optionally commits and tags the change, configured through a parse and serialize pair that supports SemVer, CalVer and custom schemes. It is a maintained refactor of the old bumpversion, and it is a build tool that writes to your repository.
- Who is it for?
- bump-my-version suits a Python project that keeps its version in more than one place and wants a single command that updates the files, commits and tags, with the versioning scheme expressed as configuration rather than a convention.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A refactor of bumpversion, and why that matters to you
The README opens with a lineage note that tells you what kind of project this is. It is a maintained refactor of the bump2version fork of the excellent bumpversion project, and the main goals of the refactor are listed: support for pyproject.toml configuration files, a conversion to click for the CLI interface and rich for the interface itself, better configuration validation using Pydantic, and code and tests that are easier to read and maintain. Two of those are decision relevant. The pyproject.toml support is the practical one, since the project you are versioning almost certainly keeps its metadata there, and the tool being able to read and write that file without a separate configuration format removes a whole class of setup friction. The Pydantic validation is the one that changes behaviour, because a configuration that is validated is a configuration that fails loudly at startup rather than silently doing the wrong thing at release time. The package metadata confirms the stack, with pydantic and pydantic-settings for configuration, rich-click and rich for the command line, tomlkit for editing TOML without losing formatting, wcmatch for glob matching over the files you configure, and click as the CLI framework. The licence is MIT, the package requires Python 3.10 or newer, and the console script is registered as bump-my-version.
The two configuration keys that define your versioning scheme
The mechanism is a parse and a serialize pair, and once you see it the design is obvious. The parse option is a regular expression that extracts the version components from the current version, and the serialize option is a list of format templates that turn those components back into a string. The default configuration uses a simplified version of semantic versioning, with a parse pattern of three named groups, major, minor and patch, and a serialize list of a single template, {major}.{minor}.{patch}. The search and replace options are what tie the version to your files: search is {current_version} and replace is {new_version}, so the tool finds the old string and substitutes the new one, with regex set to false for plain text matching. Everything else in the default configuration is a policy decision you can change. ignore_missing_version is false, so the tool complains when it cannot find the version it expected. tag is false and sign_tags is false, so tagging is opt in. allow_dirty is false, so the tool refuses to run when you have uncommitted changes. commit is false, so the commit step is opt in too. The tag name template is v{new_version} and the tag and commit messages are Bump version: {current_version} → {new_version}. The default configuration is generated, not written by hand.
$ bump-my-version sample-config --no-prompt --destination .bumpversion.tomlThat command writes a working configuration you can edit, which is the right way to start rather than assembling the options from documentation.
See the version paths before you commit to one
The show-bump subcommand is the feature that makes this tool pleasant to use, because it shows the consequences of a bump before you apply it. You can see the potential versioning paths with it, and the output is a tree of the possible next versions.
$ bump-my-version show-bump
0.1.0 ── bump ─┬─ major ─ 1.0.0
├─ minor ─ 0.2.0
╰─ patch ─ 0.1.1The same subcommand accepts a starting version, so you can ask what would happen from a version that is not the current one, which is how you plan a release train before you are in it. There is also a show method for scripts, which is what you want when a build step needs the next version number rather than a bump. The show command prints the current version, and with an increment flag it prints the version a bump would produce.
$ bump-my-version show current_version
1.2.3
$ bump-my-version show --increment minor new_version
1.3.3Two things about this shape the tool's role. It is designed to be part of an automated build system, and it is designed to work with the project's source control system, committing changes, tagging releases and reading version numbers from tags. That is the difference between a version string editor and a release tool, and it is why the tool is MIT licensed and packaged with a Docker image and a GitHub Action in the same repository.
Adding pre-release labels, and the part values list
The default configuration only allows bumping the major, minor or patch version, and the README walks through extending it for pre-release versions in a way that is worth following as a template. You change the parse pattern to an extended regular expression that captures an optional pre-release section with a dash separator, a pre_l label and a pre_n number, and you change serialize into a list of two templates, the pre-release form first and the plain form second, so the tool knows which to use. Then you add a configuration section for the label part with a list of values, dev, rc and final, and an optional_value of final.
[tool.bumpversion.parts.pre_l]
values = ["dev", "rc", "final"]
optional_value = "final"Once that is in place, show-bump grows new branches, and it refuses to bump a part that is already at its maximum. Running it on the default version, the pre_l branch reports that the part has already the maximum value among the list and cannot be bumped, while pre_n can still move. On a dev version the pre_l branch advances to rc0, and on an rc version the pre_l branch drops the pre-release suffix entirely, which is the transition to the final release. The README then spells out the full development and release path as a list of bump operations, and the two rules it attaches are the ones to remember: you must decide on the next version before you start developing, and development versions increase with the pre_n bump while switching from development to release candidate uses the pre_l bump.
Configuration files, and how the tool finds your project
The tool ships with several ways to be configured, and the choice matters because the tool is typically invoked from a release script. The default file written by sample-config is a .bumpversion.toml, and the configuration sections in the examples use the [tool.bumpversion] prefix, which is the pyproject.toml convention. Beyond that, the repository listing shows a configuration surface that is broader than one file. There is a pyproject.toml for the tool itself, a .changelog-config.yaml, a .composition.yaml, a .codacy.yaml, a justfile with the commands the maintainers use, a devenv.nix and devenv.yaml for a Nix development environment, and a .pre-commit-config.yaml, which is a natural place to run a check that the version in the source matches the version in the tag. The package metadata shows the same tool is exposed as a console script, and the justfile shows the maintainers' own usage, where the bump recipe adds everything to the index, runs the tool with a type argument and a tag flag, and defaults to a dry run, which is a sensible default for a command that rewrites your repository.
[tool.bumpversion]
current_version = "0.1.0"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}"
replace = "{new_version}"
regex = false
ignore_missing_version = false
tag = false
sign_tags = false
tag_name = "v{new_version}"The default configuration printed above is the detail to notice. A tool that rewrites files, commits and tags is exactly the kind of command you want to be able to see through before it runs, and the dry run default in the maintainers' own recipe is the same instinct applied.
How it compares to the older tools and to a manual edit
The obvious comparison is with the tool it replaces, and the difference is the refactor rather than a new idea. bumpversion, the original, is a small script that finds and replaces a version string; bump2version was a widely used fork; bump-my-version takes that line and rebuilds it on click, rich and Pydantic, adding pyproject.toml configuration support along the way. So the difference in approach is the same operations in a modern configuration system with validation, a nicer interface and better configuration validation. The other comparison is doing it by hand, or with a two line shell script, and for a project with one version in one file that is the better answer, because a configuration file with a parse pattern and a serialize list is more machinery than the problem deserves. The other axis is tooling philosophy. There are general purpose release tools that manage changelogs, build artefacts and publication, and they are the right choice if you want a whole release pipeline. This tool deliberately does not, and stays on the narrow job of version strings, file replacement, and the commit and tag that follow. It also ships as a Docker image with the entrypoint set to the tool, which makes it usable from a CI container, and it is MIT licensed with the licence file in the repository root.
Editorial conclusion
bump-my-version suits a Python project that keeps its version in more than one place and wants a single command that updates the files, commits and tags, with the versioning scheme expressed as configuration rather than a convention. It is the wrong tool if your version lives in one place, because the configuration overhead then exceeds the work it saves, and it is the wrong tool if you do not want a tool writing to your working tree, since the commit and tag steps are part of the design. Before you adopt it, run the show-bump subcommand on your current version to see the paths it would take, and set allow_dirty to false so the tool refuses to work in a tree with uncommitted changes.
Frequently asked questions
How do I install bump-my-version?
The README says to use uv to install it on your system with uv tool install bump-my-version. The package is also published on PyPI as bump-my-version and requires Python 3.10 or newer.
How do I make bump-my-version support pre-release versions?
Change the parse pattern to an extended regular expression that captures the pre_l label and pre_n number, change serialize into a list with the pre-release template first, and add a parts section for pre_l listing its values and an optional_value. The README shows the pattern for dev, rc and final.
What is the difference between bump-my-version and the original bumpversion?
bump-my-version is a maintained refactor of the bump2version fork of bumpversion. The stated goals were pyproject.toml configuration support, a conversion to click and rich for the CLI, better configuration validation using Pydantic, and code and tests that are easier to read and maintain.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/callowayproject-bump-my-version)Was this useful?