summaryrefslogtreecommitdiff
path: root/bumper.md
blob: d00c08c7d66426505eb528f0bcbba818039ec1b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# 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 <jr@example.com>"]
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 <liw@liw.fi>  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",
)
~~~


---
title: bumper &ndash; set version number for a project
author: Lars Wirzenius
documentclass: report
template: python
bindings:
- subplot/bumper.yaml
- subplot/vendored/files.yaml
- subplot/vendored/runcmd.yaml
functions:
- subplot/bumper.py
- subplot/vendored/files.py
- subplot/vendored/runcmd.py
classes:
- ini
...