1

I have a project that builds based on an SVN commit. When that project succeeds it triggers a project to build on a slave.

How do I get the SVN revision of the original/trigger project in the slave?

Tim
  • 20,184
  • 24
  • 117
  • 214

2 Answers2

2

You can get the upstream's revision information (and more) via Groovy. The following script in a "Execute system Groovy script" build step will do what you want:

import jenkins.model.*

// find latest upstream build that triggerd this run (there may be several iff queued)
def latestCause = build.causes.findAll {
  it.class.toString() == 'class hudson.model.Cause$UpstreamCause'
}.max( { it.getUpstreamBuild() } )

// determine upstream project name and build number
def upstreamProjectName   = latestCause.upstreamProject
def upstreamBuildNum      = latestCause.upstreamBuild
println "upstreamProject  = ${upstreamProjectName}"
println "upstreamBuildNum = ${upstreamBuildNum}"

// find corresponding upstream job and build objects
def upstreamJob   = Jenkins.instance.getItemByFullName( upstreamProjectName )
def upstreamBuild = upstreamJob.getBuildByNumber( upstreamBuildNum )

// print subversion revision info
def state = upstreamBuild.getAction( hudson.scm.SCMRevisionState.class )
state.revisions.each { location, revision ->
  println "upstream url/rev: ${location} / ${revision}"
}

Sample output:

upstreamProject  = svn-upstream-project
upstreamBuildNum = 16
upstream url/rev:  https://svn.example.com/foo/bar / 12345

You will not need to pass any "upstream" information explicitly to the downstream project. This is easier to maintain, and also the downstream queueing behavior won't change (see my comment on the other answer). This is essential if your downstream execution takes more time than what's available between to upstream executions -- you'll end up with an ever growing build queue otherwise.

You can craft particularly nice solutions if you use a script like the above and combine it with the Script SCM plugin. For example, you can synchronize downstream changelogs (and committer notifications) to upstream projects without connecting the downstream to SCM at all. This is a typical setup when you connect a "build job" and one (or more) "test jobs".

Alex O
  • 7,746
  • 2
  • 25
  • 38
  • This is exactly the behavior I want - the 'child' job is not hooked to SVN/SCM and is NOT set up as a parameterized build. And how to I refer to this upstream svn revision from the downstream? (for example i want to put it in the email notification) – Tim Feb 07 '17 at 20:42
  • 1
    See this question: http://stackoverflow.com/questions/10413936/creating-a-jenkins-environment-variable-using-groovy basically, you inject it as a parameter to the build – Jon S Feb 07 '17 at 21:02
  • I wouldn't bother about a solution that explicitly injects variables for hand-crafting changelogs and notifications. With Script SCM, you can aggregate upstream changes from multiple (queued) upstream triggers in the downstream, display those changes _as if_ the downstream was directly connected to SCM, and also notification triggers will work as usual. It's a few lines of Groovy code, but IMHO its worth the effort. – Alex O Feb 07 '17 at 21:35
  • Hmmm, I _think_ there was possibly an issue with the Script SCM plugin setting variables for the later build steps (like, setting `SVN_REVISION`). Possibly that required a modified version of the plugin. Will check tomorrow. Regarding the question in your comment, I think that if everything fails, you can write the information to a properties file and read/import that via the envinject plugin. – Alex O Feb 07 '17 at 21:43
  • Unfortunately I was right -- I think you cannot define environment variables for build steps with the standard Script SCM plugin. So you need to go via injection for now. – Alex O Feb 08 '17 at 12:26
1

When triggering the downstream job, use the Parameterized Trigger Plugin (Post-build Action called Trigger parameterized build on other projects) and supply the svn revision as a parameter. You can do this in two ways:

  1. Subversion revision parameter, it will make sure that if you check out the same source in you down stream job, it will check out the same version as in the upstream (i.e. it copies the hidden SVN Revision Action which is stored with the upstream build).
  2. If you're only interested in the revision, then you add a Predefined parameters parameter and bind the value of SVN_REVISION to a variable. That variable will then be available in the downstream job.

The trigger parameterized build post build action

Here is a related discussion which touches upon the problems with using the Subversion revision parameter, it is not 100% obvious to the user what SVN revision that has been propagated.

Community
  • 1
  • 1
Jon S
  • 15,846
  • 4
  • 44
  • 45
  • 2
    This will work, but note that introducing parameters will change the queueing behavior -- there will be a downstream build for _each and every upstream_ run. Normally (without parameters), Jenkins will aggregate multiple triggers of the downstream if its execution cannot keep up with the upstream. Such a scenario is quite common when you have a relatively fast build job with a slow downstream job for running regression tests. – Alex O Feb 07 '17 at 18:50
  • That's true, I would say that the two solutions complements each other depending on what behaviour you wan't... However, it is not clear by the question. – Jon S Feb 07 '17 at 19:32
  • unfortunately i don;t think i can use this - the downstram project is not hooked to svn nor is it a parameterized build. Sorry i wasn't so clear with my question. this is useful info to me regardless - as I can make use of it in other places. thanks – Tim Feb 07 '17 at 20:43