Simple script to increment artifact version from within Jenkins pipeline

Simple script to increment artifact version from within Jenkins pipeline

Requirement

One important requirement when creating a new build in a continuous integration setup is to generate a unique automated artifact version in an increasing order for better tracking. While working from a Jenkins project, the easiest way to create a version is to use the build number. However, this does not always suffice the purpose. Our project might need to create a new version only once all the tests have run successfully, however the build no. gets incremented even when the build fails during any pipeline stage.

Let us consider a use case below :

We have created a Jenkins pipeline project which has the following stages

  1. Code checkout
  2. Compile and unit testing
  3. Static code analysis
  4. Deploy to test server
  5. Functional testing
  6. Packaging
  7. Deploy to the production server

Here we want to increment a version only when we have passed the functional testing phase.

If we use the job build number from the environment variable BUILD_NUMBER for version tagging, we will not be able to accomplish this. Because this will not be a consistently incremented number. There will be gaps in the version number after each build failure.

Another way is to append the build number in a subsequent project. This new project will be called once all the stages of the first project are successful. This could be a pipeline or a freestyle project or any other Jenkins project. This, even though can solve our problem of a consistent build number, is not an appropriate solution as moving to a different project is not the real project need, it is more of a workaround.

Now, the question arises, how to meet this need of a consistent and automatically generated version no. from within Jenkins pipeline.

Solution

Below is a simple script where we will store a count as a text file in the Jenkins workspace and increment it every time a new version needs to be created.

We can use this script from pipeline project as well as freestyle project.

Create File

First we will create a file either manually or by running this groovy script only for the first time.

def counter = 0
def data = "Version" + counter
writeFile(file: 'version.txt', text: counter.toString())

The above code will create a file named version.txt in the Jenkins workspace. We can also create the file at a different location by providing the path before the file name. Remember to run this script only one time, else it will reset the counter.

Read the File

Then we will check that the file exists at the path specified.

 if (fileExists()) {
   ---
   ---
} //if condition
else {
currentBuild.result = "FAILURE" 
} //else condition

Every time we reach the stage where we want to increment the version, we will read the value from the file, store it in a variable, increment the value and append text β€œVersion” to it to create a new version. Then we can use this version for our new release artifact.

To accomplish this in the script, we will read the counter value from the file, convert it into integer and increment by 1. In the third line in the following script snippet, we will append β€œVersion” to the counter value and then print the new value just to confirm.

def readcounter = readFile(file: 'version.txt')
readcounter=readcounter.toInteger() +1
def version= "Version" + readcounter
println(version)

Version Tagging

Now we will tag this version to our new build artifact. For our example, we are using a maven project and we can append the version as follows.

bat 'mvn package -Dartifactversion=' + "${version}"

Replace bat with sh for linux.

For our maven project, we will need to setup the property artifactversion and append the artifactversion property to the artifact name inside the <finalName> tag in pom.xml before running this command as shown below.

<properties>
	<artifactversion>Version0</artifactversion>
  </properties>
  <build>
    <finalName>myProjectName-${artifactversion}</finalName>
    <!--<finalName>myProjectName</finalName> -->
    - - - 
    - - - 

Update version

Once we are done with version tagging, we will update the version.txt with the new version as follows

writeFile(file: 'version.txt', text:readcounter.toString())

Usage in Scripted Pipeline project

We can write the code within a stage in a scripted pipeline.Do not forget to replace bat with sh on linux machine.

If you want to learn to write a simple scripted pipeline you can refer to the post Structure of a Scripted Pipeline in Jenkins with sample code

stage ('Build and Package' ) {
//begin common code 
if (fileExists()) {
  def readcounter =    readFile(file: 'version.txt')
  readcounter = readcounter.toInteger() +1
  def version= "Version" + readcounter
  println(version)
  bat 'mvn package -Dartifactversion=' + "${version}"
  writeFile(file: 'version.txt', text:readcounter.toString())
} //if condition
else {
currentBuild.result = "FAILURE" 
  } //else condition
//end common code
  echo "Build and Package Completed" 
} //stage

Usage in Declarative Pipeline project

We will insert the code below marked as common code in the above code for scripted pipeline and insert it as it is within a stage in the declarative pipeline as below. And again do not forget to replace bat with sh on linux machine

stage (Build and Package') {
  steps {
    script {
      //begin common code 
      if (fileExists()) {
        def readcounter =    readFile(file: 'version.txt')
        readcounter = readcounter.toInteger() +1
        def version= "Version" + readcounter
        println(version)
        bat 'mvn package -Dartifactversion=' + "${version}"
        writeFile(file: 'version.txt',    text:readcounter.toString())
      } //if condition
      else {
        currentBuild.result = "FAILURE" 
      } //else condition
//end common code
    } //script
    echo "Build and Package Completed" 
  } //steps
} //stage

Please let us know if you found this post useful.


You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *