--- title: bumper – set version number for a project author: Lars Wirzenius documentclass: report template: python bindings: - subplot/bumper.yaml - lib/files.yaml - lib/runcmd.yaml functions: - subplot/bumper.py - lib/files.py - lib/runcmd.py classes: - ini ... # Introduction Bumper is a small utility for updating the version number when making a release of a software project. It updates the version number in the various locations in which it is stored in the source tree, commits those changes, and creates a git tag for indicating the release. The tool is used like this: ~~~{.numberLines} $ cd ~/my-project $ bumper 1.2.3 Setting version for project in /home/liw/tmp/toy Rust project set to 1.2.3 Debian package project set to 1.2.3-1 Python project set to 1.2.3 $ git push --tags ... $ ~~~ In other words: you run Bumper and tell it the version of the release you're making. Bumper sniffs out what kind of project it is, and sets the version number in the right places. It then creates a git tag for that release. It's up to you to push the changes and tag to a git server, and to build the release: Bumper only makes local changes. # Overview Bumper makes several assumptions about the project and its source tree, to keep things simple. * Version numbers for releases use a format of X.Y.Z, where each component is an integer. For example, 12.7.999. There can be any number of components. * The source is stored in git. No other version control systems are supported, since the author uses nothing else. (If you would like support for other systems, please help.) * Rust projects store the version number in the `Cargo.toml` file. The build system gets it from there. * Debian packages have a `debian/changelog`, which specifies the package's version number. Bumper assumes the file is otherwise up to date for the release, and sets the version to `X.Y.Z-1`. * Python projects have a `setup.py` file at the root of the source tree, and at least one `version.py` in a sub-directory where the version number is stored in the `__version__` variable. * Releases are marked with signed, annotated git tags named after the release version with a `v` prefix. Bumper looks for all the files mentioned above, and updates or overwrites them to set the version number, and then commits all changes. It creates a release tag for the commit. It then updates the same files to add a "`+git`" suffix to the version number, to help distinguish release versions from development versions. # Acceptance criteria This chapter has scenarios to express acceptance criteria and their verification. ## Does nothing if there are no files to update This scenario verifies that Bumper doesn't change anything if it doesn't find any files it knows about. ~~~scenario given an installed Bumper given file foo/random.txt from Cargo.toml given all files in foo are committed to git when I try to run, in foo, bumper 1.2 then command fails then only files random.txt, and .git exist in foo ~~~ ~~~{#random.txt .file} Some random text file Bumper knows nothing about. ~~~ ## Sets version for Rust project This scenario verifies that Bumper creates a git tag to mark a release for a Rust project. ~~~scenario given an installed Bumper given file foo/Cargo.toml from Cargo.toml given file foo/Cargo.lock from empty given file foo/src/main.rs from empty given all files in foo are committed to git when I run, in foo, bumper 105.12765.42 then all changes in foo are committed then in foo, git tag v105.12765.42 is a signed tag then file foo/Cargo.toml matches regex /version\s*=\s*"105\.12765\.42"/ then file foo/Cargo.lock is newer than foo/Cargo.toml then file foo/Cargo.lock is committed to git ~~~ ~~~{#empty .file} ~~~ ~~~{#Cargo.toml .file .ini} [package] name = "foo" version = "0.1.0" authors = ["J. Random Hacker "] edition = "2018" [dependencies] anyhow = "1" ~~~ ## Sets version for project with Debian packaging This scenario verifies that Bumper creates a git tag to mark a release for a project with Debian packaging. ~~~scenario given an installed Bumper given file foo/debian/changelog from changelog given all files in foo are committed to git when I run, in foo, bumper 105.12765.42 then all changes in foo are committed then in foo, git tag v105.12765.42 is a signed tag then file foo/debian/changelog matches regex / \(0\.1\.0-1\) / then file foo/debian/changelog matches regex / \(105\.12765\.42-1\) / ~~~ ~~~{#changelog .file} dummy (0.1.0-1) unstable; urgency=low * This is a debian/changelog file. Syntax is finicky. -- Lars Wirzenius Tue, 30 Mar 2021 08:33:35 +0300 ~~~ ## Sets version for Python project This scenario verifies that Bumper creates a git tag to mark a release for a Python project. ~~~scenario given an installed Bumper given file foo/setup.py from setup.py given file foo/setup.py is executable given file foo/lib/version.py from empty given all files in foo are committed to git when I run, in foo, bumper --tag=foo-%v 105.12765.42 then all changes in foo are committed then in foo, git tag foo-105.12765.42 is a signed tag then file foo/lib/version.py matches regex /__version__\s*=\s*"105\.12765\.42"/ ~~~ ~~~{#setup.py .file .python} #!/usr/bin/env python3 from distutils.core import setup setup( name="vmdb2", ) ~~~