Issue
I have spring boot application in my github public reposity. I have used gradle as a build tool for this spring boot application. I am using jenkins as CI/CD.
I have below task in my build.gradle file which is used to auto-increment the build number so that my generated executable jar will have unique version name in the generated jar file.
task versionIncr {
Properties props = new Properties()
File propsFile = new File('gradle.properties')
props.load(propsFile.newDataInputStream())
Integer nextbuildnum = ( ((props.getProperty('artifactBuildNumber')) as BigDecimal) + 1 )
props.setProperty('artifactBuildNumber', nextbuildnum.toString())
props.store(propsFile.newWriter(), null)
props.load(propsFile.newDataInputStream())
}
i am calling this task in jenkins as below.
"versionIncr bootJar docker --warning-mode=all"
this task is working perfectly. As a result of this task below is happening in jenkins server
- jenkins pulling the git $branch into the jenkins server workspace
- task =>
versionIncr
is getting executed and incrementing the version number and updating"gradle.properties"
file in the workspace that is there in jenkins server - generating executable jar file
- creating docker image with the newly generated executable jar file
problem::
the changes made to "gradle.properties
" file are left in the jenkins server workspace and the updated version number will not gets reflected in the git hub branch. since jenkins made changes locally so when i push any changes to the github and run the jenkins job then version number in "gradle.properties"
file will still remains same. I do not want to update the version number manually each time i push my commits. I want jenkins to handle the version change for me.
is there any way or gradle plugin or jenkins plugin which i can use to push the modified "gradle.properties"
file from jenkins
workspace back to "github"
repository.
Also if possible i would like to know the way of achieving using either github username/password
or by using SSH
.
let me know if i need to post any more information here.
Update:: Posting my build.gradle file just in case if some one is interested in how i am doing it. build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE")
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
}
}
plugins {
id 'org.springframework.boot' version '2.2.7.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
id 'maven-publish'
id 'com.palantir.docker' version '0.25.0'
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
//apply plugin: 'io.spring.gradle.dependencymanagement.DependencyManagementPlugin'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'
//apply plugin: 'org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin'
group 'com.javasree'
version project.properties.containsKey("releaseVersion") ? "${artifactMajorVersion}" : "${artifactMajorVersion}-${artifactBuildNumber}"
sourceCompatibility = 1.8
ext {
springCloudVersion ='Greenwich.RELEASE'
artifactName ='<artifact>'
artifactory = 'http://localhost:8081/artifactory/'
artifactoryRepo = 'gradle-lib-release'
artifactorySnapShotRepo = 'gradle-lib-snashot'
artifactoryRepo3pp = 'pub-gradle-remote'
artifactoryUser = System.getProperty("user", "")
artifactoryPassword = System.getProperty("password", "")
}
repositories {
mavenCentral()
maven {
url "${artifactory}${artifactoryRepo3pp}"
allowInsecureProtocol = true
credentials { // Optional resolver credentials (leave out to use anonymous resolution)
username = "admin" // Artifactory user name
password = "password" // Password or API Key
}
}
}
publishing.publications {
maven(MavenPublication) {
artifact bootJar
// groupId 'gatewayengine'
// artifactId artifactName
// version '1.0-SNAPSHOT'
from components.java
}
}
publishing.repositories {
maven {
allowInsecureProtocol = true
credentials {
username = "admin" // Artifactory user name
password = "password" // Password or API Key
}
if(project.version.endsWith('-SNAPSHOT')) {
url "${artifactory}${artifactorySnapShotRepo}"
} else {
url "${artifactory}${artifactoryRepo}"
}
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
//mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}
}
docker {
name "localhost:5000/${project.name}:${project.version}"
files tasks.bootJar.outputs
//tag 'localhost:5000/${project.name}:${project.version}'
dockerfile file('Dockerfile')
//buildArgs([HOST_APP_JAR_LOC: 'version'])
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web',
'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.2.2.RELEASE',
'org.springframework.cloud:spring-cloud-starter-netflix-zuul:2.2.2.RELEASE'
}
task versionIncr {
Properties props = new Properties()
File propsFile = new File('gradle.properties')
props.load(propsFile.newDataInputStream())
Integer nextbuildnum = ( ((props.getProperty('artifactBuildNumber')) as BigDecimal) + 1 )
props.setProperty('artifactBuildNumber', nextbuildnum.toString())
props.store(propsFile.newWriter(), null)
props.load(propsFile.newDataInputStream())
}
Solution
I have previously solved your proposed issue in 2 separate ways. Firstly, by using a Gradle plugin, similar to the nebula-release
plugin @sghill linked above.
However, that plugin worked by counting all the commits for a patch version, configured major and minor via a Gradle extension and appended metadata information, e.g. branch name and whether it was dirty or not. That seemed too complex a workflow for my needs and was not useful for projects that didn't use Gradle. For your case, however, it's a quick off the shelf solution.
In my case, all I needed were unique version numbers automatically tagged upon a PR being merged into develop
or master
, and unique version numbers for each commit on a branch. To do so, I did use Git tags and wrote a script for it.
The 3 cases for versioning were:
- a new, uninitialised repo => generate a new version.json file with a default branch (master, but can be changed per repo, a major and a minor version to configure those bumps)
- any commit merged into the default branch generates a new version and tags it. If the major or minor versions in
version.json
have been changed, a major or minor bump occurs and the patch version is reset to 0. - unique versions on branches: the output of
git describe
and the branch name, e.g.0.1.0-x-branch-name
wherex
is the number of commits ahead of the default branch.
You can find it here and the docker container here
As for configuring Jenkins to have write access to the repo, have you followed the instructions here? This is what I've been successfully doing in all of my repos: Git push using jenkins credentials from declarative pipeline
Answered By - afterburner