project version from maven to sonar using hudson

2019-02-21 03:30发布

问题:

i am using maven2 , hudson and sonar while doing sonar analysis - i would like some way to append the Hudson build# to the maven version of the project

The project version changes every 2 weeks - so take an example in the first 2 weeks :

<version>abc-SNAPSHOT</version>

after two weeks the next version could be something like :

<version>xyz-SNAPSHOT</version>

what I want is to append the build# to the version already present in pom - which is being picked up and passed to sonar

NOTE:

-Dsonar.projectVersion=xyz-SNAPSHOT-${BUILD_NUMBER}

Here - I am hardcoding the version and dynamically passing the build#

what I want is to be able to dynamically pick up the version from maven ( without changing it ) and simply appending the build# dynamically

any ideas of how this can be achieved ? Thanks, satish

回答1:

You can use Groovy script to read the version and put on environment variable: Getting Maven Version in Jenkins

I used this script on time to parse the version:

def project = new XmlParser().parse("/pom.xml")
def artifactId =  project.artifactId.text().trim()
def version = project.version.text().trim()
println "ArtifactId: [" + artifactId + "]"
println "Version: [" + version + "]"

After set "Additional properties" field with: -Dsonar.projectVersion=${MAVEN_VERSION}-${BUILD_NUMBER}

If Jenkins don't get the variable, try install: https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin



回答2:

You can use this Jenkins feature: https://github.com/jenkinsci/jenkins/pull/933/files

Basically you can access env variables at build, mapped by Jenkins from Maven GAV info

  • POM_DISPLAYNAME
  • POM_DISPLAYNAME
  • POM_VERSION
  • POM_GROUPID
  • POM_ARTIFACTID
  • POM_PACKAGING
  • POM_RELATIVEPATH


回答3:

This is not really a Sonar issue. It's Maven project versioning.

Snaphots are designed to be dynamic. You'll discover under the hood that Maven is saving time-stamped versions in your Maven repository (I don't know how these time-stamps could be passed onto Sonar, which perhaps is what you'd like). Snapshot builds are ideal for CI jobs. software that is never used by non-developers.

What's I'd recommend is either stop using snapshots (build a "release" each time), or just accept the fact that there are two kinds of build in Maven. My rule is that if the code is being used by others then it's no longer a snapshot and should be treated as a release. This creates challenges for emerging methodologies like continuous deployment..... If every build goes to production (or production copy) then snapshots become irrelevant.

Building a release everytime is not that bad. First of all naming convention, I'd recommend:

<major>.<minor>.<patch>.<hudson build num>

The Maven's release plugin will automate most of the pain in managing the details of the release (updating the POM, tagging your SCM system). Finally there is also a useful M2_Release plugin that enables you to trigger a release from Hudson GUI.



回答4:

Thanks To Andre for pointing me to the other link I did try it but was running into some issues as noted in the comments Assuming what I have done is just a workaround and there is a better solution ? ( I am using Hudson ) So I defined a new Job in Hudson ( Build a Maven 2/3 project (Legacy) ) Here I defined a "Groovy PostBuild" Copied the code in the link that Andre pointed me to :

import hudson.model.*;
import hudson.util.*;

def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def mavenVer = currentBuild.getParent().getModules().toArray()[0].getVersion();
def newParamAction = new hudson.model.ParametersAction(new           
hudson.model.StringParameterValue("MAVEN_VERSION", mavenVer));
currentBuild.addAction(newParamAction);

I then "Trigger parameterized build on other projects " and mentioned the job in which I wanted the maven version as mentioend in the pom

Defined a parameter - ${MAVEN_VERSION}

I was then able to get the value of this parameter in the "other" job

So first thanks to Andre - he provided me a solution I am curious to know if this is a good approach another question I have is ( which maybe I will start a new thread ) is - how does a Hudson "Free style" job differ from a "Maven 2/3 legacy project"

The reason I ask is the same Groovy script failed in a "free style" while it worked in a "Maven legacy"

Thanks, satish



回答5:

Had the same need and solved as suggested with Groovy parsing the pom.

import jenkins.util.*;
import jenkins.model.*;

def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def workspace = currentBuild.getModuleRoot().absolutize().toString();

def project = new XmlSlurper().parse(new File("$workspace/pom.xml"))

def param = new hudson.model.StringParameterValue("project.version", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));

Add this script as a post step of type "Execute system Groovy script" (so it's not needed to install Groovy) and paste the code in the "Groovy command".