Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I retrieve the SVN Changeset comments for a Jenkins build?

My process is that Jenkins polls SVN for a build every three minutes, performs a build when a change occurs, and creates a deployment package which it then pushes to Octopus. Once the deployment is complete, it sends a deployment report via email to everyone involved.

Right now, the build notes in the report are just typical boilerplate, i.e., Jenkins Build 35. What would be great would be if I could pull the comments for the changeset that triggered the build and build the release notes off of that.

If I can get AT the comments, getting them into the release notes is pretty simple. If anyone has any ideas on that, I would appreciate it.

UPDATE: There is a related question about how to do this with the email-ext plugin, but I'm not using that plugin, and as far as I can tell, the answer is expressed using the syntax of that plugin and I can't figure out how to adapt it. I would appreciate an answer that bears directly on my usage here.

like image 731
Chris B. Behrens Avatar asked Mar 09 '15 21:03

Chris B. Behrens


1 Answers

There are 3 ways you can get the SCM changes

Groovy

Groovy is similar to Java and is native to Jenkins, hence you can reference Jenkins object models and data directly with Groovy. You still requires plugins to execute Groovy code, such as Groovy Plugin. Here is a bit of sample code adopted from this answer:
How to get the list of changed file in SVN from Jenkins

import hudson.model.*
import hudson.util.*
import hudson.scm.*
import hudson.scm.SubversionChangeLogSet.LogEntry

// work with current build
def build = Thread.currentThread()?.executable

// for testing, use last build or specific build number
//def item = hudson.model.Hudson.instance.getItem("Update_SRC_Branch") 
//def build = item.getLastBuild()   
//def build = item.getBuildByNumber(35)   

// get ChangesSets with all changed items
def changeSet= build.getChangeSet()
List<LogEntry> items = changeSet.getItems()

From there, the items list now contains the change set. Use as you wish. This is as far as I am going to go with Groovy, cause frankly I don't use it.

Filesystem

Jenkins stores builds on the filesystem under $JENKINS_HOME/jobs/$JOB_NAME/builds/$BUILD_ID. Prior to version 1.597, the $BUILD_ID was a timestamp in the format like 2015-03-16_00-13-19. After version 1.597, the $BUILD_ID is now a build number $BUILD_NUMBER like 123 (same as what you see in the build history log).

There is a file there: $JENKINS_HOME/jobs/$JOB_NAME/builds/$BUILD_ID/changelog.xml. It contains all the same SCM changesets that you see in the UI, pulled from your SCM, all in an XML file. Parse the file, and every <msg>...</msg> element contains the comments. There may be more than one.

However, although all the variables are available to you at runtime during the build (change $VAR to %VAR% if on Windows), the specific build location is NOT created till the build is completed, so you can't access it during the current build. You can however pass all these variables to a downstream build (for example your deployment job, if it is separate), and that downstream build can extract the changelog file. You would need Parameterized Trigger Plugin to pass variables to another build.

Email

The mailer action that comes with Jenkins can do almost nothing other than the "boilerplate" message. If you want anything to do with emails, you need the Email-ext (Extended Email) Plugin. There are a ton of questions/answers on SO here about email-ext, even a tag email-ext, however I would advise searching for text email-ext rather than using a tag, as a lot of questions are not fully tagged.

Your first place to start would be the "Content Token Reference" on-page help (click the ? icon next to that text. That lists all the possible tokens that can be used in the email title/body

You wanted the "SCM comments". Those are referenced through %m of ${CHANGES_SINCE_LAST_SUCCESS} token. To get just the comments, use the following:

${CHANGES_SINCE_LAST_SUCCESS, changesFormat=" %m<br>"}

Just put the above line into the email body configuration. You can surround it with any plain text you want.

For a more nicely formatted output, use

${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="<b>Changes for Build #%n</b><br>%c<br>", changesFormat="<br>[<a href='${JENKINS_URL}/user/%a/builds'>%a</a>] - (%r) %p<br> %m<br>"}

as referenced in the close duplicate questions I provided:
How can I get the SVN log entry in Jenkins when sending email

P.S.

If your requirement is "no plugins", then you need to find a different build system than Jenkins. Jenkins is an open-source project, that provides a core and a plugin for almost everything else, maintained by the open community. Everything in Jenkins is a "plugin", even the Subversion SCM step and Freestyle and Maven projects are "plugins". Some are bundled with the installation, most need to be added after the install.

like image 93
Slav Avatar answered Oct 12 '22 23:10

Slav