All the relevant files are included below, but here is the gist of it. I have a master branch from which I make various feature branches before merging to master. I have marked every merge to master branch as a minor update. This is fully automated via the code below. Build number is also automated and updated with every new commit regardless of which branch I am on. Finally, patch numbers and major number updates are semi-automatic via a trigger in BB pipelines.
I store the version number in a version.txt file and every build I update the number and run a commit and push from within that build, but skip the build process for that secondary commit using [skip CI] or it would loop infinitely. Happy to explain anything further if need be.
Part of the version.sh script was sourced from an answer on linux - simplify semantic versioning script
This is what my bitbucket-pipelines.yml
file looks like:
image: python:3.6
pipelines:
default:
- step:
script: # Modify the commands below to build your repository.
# Linting check
- pip3 --version
- pip3 install -r requirements.txt
- pylint backend
- bash version.sh build $BITBUCKET_BUILD_NUMBER $BB_AUTH_STRING
branches:
master:
-step:
name: Minor version update
script:
# Linting check
- pip3 --version
- pip3 install -r requirements.txt
- pylint backend
# Increase minor version number
- bash version.sh minor $BITBUCKET_BUILD_NUMBER $BB_AUTH_STRING
-step:
trigger: manual
name: Major version update
script:
- bash version.sh major $BITBUCKET_BUILD_NUMBER $BB_AUTH_STRING
-step:
trigger: manual
name: Patch version update
script:
- bash version.sh patch $BITBUCKET_BUILD_NUMBER $BB_AUTH_STRING
and version.sh
:
#!/bin/bash
#CONFIG
USER=""
REPO=""
USERNAME=""
EMAIL=""
major() {
if IFS=. read -r major rest <version.txt || [ -n "$major" ]; then
echo "$((major + 1)).0.0.$1" >"version.txt"
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi
}
minor() {
if IFS=. read -r major minor patch build <version.txt || [ -n "$major" ]; then
echo "$major.$((minor + 1)).0.$1" >"version.txt"
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi
}
# Need to substract one from minor because automatically runs
patch() {
if IFS=. read -r major minor patch build <version.txt || [ -n "$major" ]; then
echo "$major.$((minor - 1)).$((patch + 1)).$1" >"version.txt"
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi
}
build() {
if IFS=. read -r major minor patch build <version.txt || [ -n "$major" ]; then
echo "$major.$minor.$patch.$1" >"version.txt"
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi
}
update() {
echo "New version = $(<version.txt)"
git config --global push.default simple
git remote set-url origin https://${1}@bitbucket.org/${USER}/${REPO}.git
git config user.name $USERNAME
git config user.email $EMAIL
git config -l
git add version.txt
git commit -m "[skip CI]"
git push
}
case "$1" in
major)
major $2
update $3
;;
minor)
minor $2
update $3
;;
patch)
patch $2
update $3
;;
build)
build $2
update $3
;;
*)
echo "Usage: bash version.sh {major|minor|patch|build} build_number bb_auth_string"
exit 1
esac
exit 0
Finally version.txt
is a simple text file with four numbers separated by a dot such as 4.3.2.1
Happy to take any suggestions on how to improve my method of doing this.