Building software with version numbers

continuous integrationversioning

This is not a question about how to number versions.

We have an application with a certain version numbering scheme. We also have a Jenkins CI server (soon to be replaced with Atlassian's Bamboo) that regularly builds our software. The application displays the version number, so it's written in one of the files in our code base.

We don't want to manually change the version number before releasing a version. Our current solution is that we have a Jenkins job that changes the version number in our code base, commits it, tags the repository with the version number, pushes it and then packages the application for distribution. The problem with that is that we have to decide to release a version before the build succeeds or fails.

What we want to do is this: have Jenkins regularly build our product and run the unit tests. Afterwards, we want to select a passing build and release it with a certain version number.

In summary, this is the process I want:

  • Jenkins builds and tests our product regularly.
  • When we want to release a version, we can select the last passing build from Jenkins and check to release it.
  • The resulting release should include the version number.
  • The commit that was built and released should be tagged with the release number.

What is the best practice for releasing product versions? Is there a process that will meet my demands?

Best Answer

We have a similar situation, and I setup our build/release process like this:

  • Our version numbers consist of four parts (major, minor, build, revision). The first two parts are only changed after a release, the other two change for every build. In our case, the major & minor version come from Jenkins build parameters, the revision number comes from subversion and the build version is the build number of the Jenkins job that performs the build. You could also read the major & minor version number from a file in the repository.
  • Jenkins writes a file that the software uses to determine its version number.
  • This file is archived within Jenkins as a build artifact, but it is not committed to the repository. This way, each build has a unique version number that can be retrieved later, but the version numbers are not tracked in the repository.

  • For making a release, we have a Release Jenkins job. This job doesn't actually build anything, but it takes as parameter which build we want to release and tags the repository at the revision for that build and marks the build in Jenkins as a release (using the build promotions feature). The file with version information can be used to determine the version number that should be encoded in the tag name.