Project Versions¶
As your project evolves, you might reach points where you consider it ready for
use at some level. Usually, we mark this point by generating a new release
and marking it with a version number.
Versioning is a very project oriented thing, but there are some conventions. The most common system you will see looks something like this:
- <major>.<minor>.<patch>
Where:
major
is a version significantly different from a previous versionminor
is a new version that keeps the same user interfacepatch
fixes problems in the current version
Major versions are not required to keep the old user interface. They can make significant changes to how the application is used. Minor versions always maintain the same user interface, but may add new features, being careful not to break any old features.
Patch versions are issued to fix problems. These changes do not alter the functionality of the program, they just fix bugs that should not be there.
I use some simple commands in my project Makefile
to make managing these
numbers easier.
When I use this system, I create two hidden files in the project:
.version
- tracks the current version of the project.build
- tracks the number of times I actually build something using Make_
Note
That last number is just for my interest. I like to see how my development work proceeds. It is also useful for students, since I can get some idea how they are working when they work on my projects.
Here is a part of my project Makefile that controls versioning:
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 | VERSION := $(shell cat .version)
BUILD := $(shell cat .build)
# version management
.PHONY: version
version: ## show current project version
@if ! ([ -f .version ]); then \
echo "v0.0.0" > .version; \
fi
cat .version
.PHONY: build
build: ## show current project build number
@if ! ([ -f .build ]); then \
echo "0" > .build; \
fi
cat .build
.PHONY: tag
tag: ## tag this version
@echo $(VERSION)
git tag -a $(VERSION) -m "Auto tag $(VERSION)"
.PHONY: bump-build
bump-build: ## bump version build number
./scripts/inc_version.sh build;
.PHONY: bump-feature
bump-feature: ## bump version feature number
./scripts/inc_version.sh minor
.PHONY: bump-release
bump-release: ## bump version release number
./scripts/inc_version.sh major
|
Lines 1-2 load the current version and build number into the Make_ environment so I can use those values later.
The version
and build
targets use bash
shell scripts to check if
the hidden .version
or .build
files are present. If not, they get
created. THen the contents of those files is displayed for reference.
The three targets named bump-xxx
will increment one of the version number
parts. In this example, I named the three fields release
, feature
and
build
which reflects how i use them better that the traditional names.
All of thse commands depend on a bash
script that does the hard work of
breaking the version number down, modifying it, and putting the parts back
together.
Here is that script:
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 | #!/usr/bin/env bash
if !([ -f .version ]); then
echo "v0.0.0" > .version
fi
version=`cat .version | sed -e "s/v//"`
major=$(echo $version | cut -d\. -f1);
minor=$(echo $version | cut -d\. -f2);
build=$(echo $version | cut -d\. -f3);
if [ "$1" = "major" ]; then
major=$(printf "%d" $(($major + 1))) ;
minor=0 ;
build=0 ;
fi
if [ "$1" = "minor" ]; then
minor=$(printf "%d" $(($minor + 1))) ;
build=0 ;
fi
if [ "$1" = "build" ]; then
echo "building $build"
build=$(printf "%d" $(($build + 1))) ;
fi
version=$(printf "v%d.%d.%d" $major $minor $build) ;
echo "$version" > .version
echo `cat .version`
|
The remaining target in the Makefile`` snippet runs a git tag
command to
mark the last commit. I run this after I commit and amm ready for a new version
number.
I also add a command to my main target that increments the build number. Here is the script that does this:
1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/bin/env bash
if !([ -f .build ]); then
echo "build=0" > .build
fi
build=`cat .build | sed -e "s/build=//"`
if [ "$1" = "reset" ]; then
build=0
fi
build=$(printf "%d" $(($build + 1))) ;
echo "build=$build" > .build
echo `cat .build`
|
This is yet another example of using Make_ to streamline your development process. You should explore how other developers manage their work, learn from them, then implement your own custom tools. What makes YOU more productive is what we re trying to figure out!
Warning
Of course, your boss may already have such procedures. You probably will be asked to use those. But nothing prevents you from working with your team to find better ways to do things. Your team will thank you for that, unless you try t ram your ideas down their throats! YMMV!