Ticket #1794 (closed enhancement: fixed)
Opened 2013-04-10T10:53:54-05:00
Last modified 2013-05-31T16:12:19-05:00
Improve the Stable-Fiji job
| Reported by: | dscho | Owned by: | dscho |
|---|---|---|---|
| Priority: | minor | Milestone: |
|
| Component: | Updater | Version: | |
| Severity: | minor | Keywords: | |
| Cc: | curtis | Blocked By: | |
| Blocking: | #1901 |
Description
At the moment, the Stable-Fiji job runs too often, listing even builds without any changes. Use a ScriptTrigger to avoid superfluous builds.
Speaking of changes: the Groovy Postbuild should allow us to list the changed files in the Recent Changes section by using removeSummary and createSummary (see https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin).
This was solved in a slightly different way, because the changes are *not* summary entries. Instead, Jenkins' Changes link triggers a Jelly script that accumulates the ChangeLogSets of all the Builds which are parsed by a ChangeLogParser that gets set by the current Build's SCM.
Unfortunately, all of this is not really accessible and the ChangeLogParser is persisted via its class name in the build.xml file. Therefore, we cannot simply add a ChangeLogParser class in the Groovy Postbuild script. Further, build.xml only gets written after the Groovy script is executed, and likewise, the ChangeLogParser in that file is ignored; whatever the current Build's SCM said the changes are get put into Jenkins' cache (in case of no SCM, an empty ChangeLogSet is created and the NullChangeLogParser that simply ignores anything in the changelog.xml file is persisted).
Therefore, we have to play really nasty games, pretending that we're Subversions and faking/accessing all kinds of things.
// This is a deliciously convoluted and fragile hack to force Jenkins to show the // updated files // fake a Subversion changelog.xml file updated = new File(manager.build.getRootDir(), "../../workspace/updated.txt") changelog = new File(manager.build.getRootDir(), "changelog.xml") changelog.withWriter { out -> out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?><log>" + "<logentry revision=\"" + manager.build.number + "\"><date>" + new java.util.Date() + "</date><paths>") updatedMessage = "" updated.eachLine { line -> if (line.startsWith("./")) line = line.substring(2) if (!".checksums".equals(line)) { out.println("<path action=\"M\">" + line + "</path>") updatedMessage += line + "\n" } } out.println("</paths><msg>" + updatedMessage + "</msg></logentry></log>") } // get an instance of the SubversionChangeLogParser import java.net.URL import java.net.URLClassLoader baseDir = new File(jenkins.model.Jenkins.getInstance().getRootDir(), "plugins/subversion/WEB-INF/") urls = new URL[2] urls[0] = new File(baseDir, "classes/").toURI().toURL() urls[1] = new File(baseDir, "lib/svnkit-1.3.4-hudson-2.jar").toURI().toURL() loader = new URLClassLoader(urls, manager.getClass().getClassLoader()) svn = loader.loadClass("hudson.scm.SubversionChangeLogParser").newInstance() // force the current build to take that parser, parse the changelog.xml and // force it down AbstractBuild's throat, too abstractBuildClass = manager.build.getClass().getSuperclass().getSuperclass() scmField = abstractBuildClass.getDeclaredField("scm") scmField.setAccessible(true) scmField.set(manager.build, svn) changeSet = svn.parse(manager.build, changelog) changeSetField = abstractBuildClass.getDeclaredField("changeSet") changeSetField.setAccessible(true) import java.lang.ref.WeakReference if (changeSetField.getDeclaringClass().isAssignableFrom(WeakReference.class)) changeSet = new WeakReference(changeSet) changeSetField.set(manager.build, changeSet)