Skip to content
Permalink
Browse files

[FIXED JENKINS-18846] Update symlinks for Maven module builds.

  • Loading branch information
jglick committed Aug 20, 2013
1 parent a89edff commit a92e9da978262c6a7e4d74d3b2750319cbc748fb
@@ -55,7 +55,9 @@
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
<li class=bug>
Build number symlinks and permalinks not updated for Maven module builds.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18846">issue 18846</a>)
</ul>
</div><!--=TRUNK-END=-->

@@ -37,7 +37,6 @@
import hudson.matrix.MatrixConfiguration;
import hudson.model.Fingerprint.BuildPtr;
import hudson.model.Fingerprint.RangeSet;
import hudson.model.PermalinkProjectAction.Permalink;
import hudson.model.listeners.RunListener;
import hudson.model.listeners.SCMListener;
import hudson.scm.ChangeLogParser;
@@ -59,7 +58,6 @@
import hudson.tasks.test.AggregatedTestResultAction;
import hudson.util.*;
import jenkins.model.Jenkins;
import jenkins.model.PeepholePermalink;
import jenkins.model.lazy.AbstractLazyLoadRunMap.Direction;
import jenkins.model.lazy.BuildReference;
import org.kohsuke.stapler.HttpResponse;
@@ -477,23 +475,6 @@ public String getHudsonVersion() {
return hudsonVersion;
}

/**
* Backward compatibility.
*
* We used to have $JENKINS_HOME/jobs/JOBNAME/lastStable and lastSuccessful symlinked to the appropriate
* builds, but now those are done in {@link PeepholePermalink}. So here, we simply create symlinks that
* resolves to the symlink created by {@link PeepholePermalink}.
*/
private void createSymlink(TaskListener listener, String name, Permalink target) throws InterruptedException {
String targetDir;
if (getProject().getBuildDir().equals(new File(getProject().getRootDir(), "builds"))) {
targetDir = "builds" + File.separator + target.getId();
} else {
targetDir = getProject().getBuildDir() + File.separator + target.getId();
}
Util.createSymlink(getProject().getRootDir(), targetDir, name, listener);
}

/**
* @deprecated as of 1.467
* Please use {@link hudson.model.Run.RunExecution}
@@ -724,9 +705,6 @@ public void defaultCheckout() throws IOException, InterruptedException {
public final void post(BuildListener listener) throws Exception {
try {
post2(listener);

createSymlink(listener, "lastSuccessful", Permalink.LAST_SUCCESSFUL_BUILD);
createSymlink(listener, "lastStable", Permalink.LAST_STABLE_BUILD);
} finally {
// update the culprit list
HashSet<String> r = new HashSet<String>();
@@ -121,6 +121,7 @@
import static java.util.logging.Level.*;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import jenkins.model.PeepholePermalink;
import jenkins.model.RunAction2;

/**
@@ -1597,8 +1598,7 @@ protected final void execute(RunExecution job) {

RunListener.fireStarted(this,listener);

// create a symlink from build number to ID.
Util.createSymlink(getParent().getBuildDir(),getId(),String.valueOf(getNumber()),listener);
updateSymlinks(listener);

setResult(job.run(listener));

@@ -1674,6 +1674,40 @@ protected final void execute(RunExecution job) {
}
}

/**
* Creates a symlink from build number to ID.
* Also makes sure that {@code lastSuccessful} and {@code lastStable} legacy links in the project’s root directory exist.
* Normally you do not need to call this explicitly, since {@link #execute} does so,
* but this may be needed if you are creating synthetic {@link Run}s as part of a container project (such as Maven builds in a module set).
* You should also ensure that {@link RunListener#fireStarted} and {@link RunListener#fireCompleted} are called.
* @param listener probably unused
* @throws InterruptedException probably not thrown
* @since 1.530
*/
public final void updateSymlinks(TaskListener listener) throws InterruptedException {
Util.createSymlink(getParent().getBuildDir(), getId(), String.valueOf(getNumber()), listener);
createSymlink(listener, "lastSuccessful", PermalinkProjectAction.Permalink.LAST_SUCCESSFUL_BUILD);
createSymlink(listener, "lastStable", PermalinkProjectAction.Permalink.LAST_STABLE_BUILD);
}
/**
* Backward compatibility.
*
* We used to have $JENKINS_HOME/jobs/JOBNAME/lastStable and lastSuccessful symlinked to the appropriate
* builds, but now those are done in {@link PeepholePermalink}. So here, we simply create symlinks that
* resolves to the symlink created by {@link PeepholePermalink}.
*/
private void createSymlink(TaskListener listener, String name, PermalinkProjectAction.Permalink target) throws InterruptedException {
File buildDir = getParent().getBuildDir();
File rootDir = getParent().getRootDir();
String targetDir;
if (buildDir.equals(new File(rootDir, "builds"))) {
targetDir = "builds" + File.separator + target.getId();
} else {
targetDir = buildDir + File.separator + target.getId();
}
Util.createSymlink(rootDir, targetDir, name, listener);
}

/**
* Handles a fatal build problem (exception) that occurred during the build.
*/
@@ -41,6 +41,7 @@
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.model.listeners.RunListener;
import hudson.remoting.Channel;
import hudson.scm.ChangeLogSet;
import hudson.scm.ChangeLogSet.Entry;
@@ -73,6 +74,7 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.CheckForNull;

@@ -497,6 +499,7 @@ public void start() {
} catch (IOException e) {
e.printStackTrace();
}
RunListener.fireStarted(MavenBuild.this, listener);
}

public void end() {
@@ -512,6 +515,12 @@ public void end() {
} catch (IOException e) {
e.printStackTrace();
}
try {
updateSymlinks(listener);
} catch (InterruptedException x) {
Logger.getLogger(MavenBuild.class.getName()).log(Level.WARNING, null, x);
}
RunListener.fireCompleted(MavenBuild.this, listener);
}

/**
@@ -1,23 +1,31 @@
package hudson.maven;

import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.Functions;
import org.junit.Assert;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.ExtractResourceSCM;
import org.jvnet.hudson.test.ExtractResourceWithChangesSCM;
import org.jvnet.hudson.test.ExtractChangeLogSet;

import hudson.Launcher;
import hudson.Util;
import hudson.maven.reporters.MavenArtifactRecord;
import hudson.maven.reporters.MavenFingerprinter;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.Job;
import hudson.model.PermalinkProjectAction;
import hudson.model.Result;
import hudson.tasks.Fingerprinter.FingerprintAction;
import hudson.tasks.Maven.MavenInstallation;
import java.io.File;

import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;
import static org.junit.Assert.*;
import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -43,6 +51,36 @@
j.buildAndAssertSuccess(m);
}

@Bug(18846)
@Test public void symlinksUpdated() throws Exception {
Assume.assumeFalse(Functions.isWindows());
j.configureDefaultMaven();
MavenModuleSet mms = j.createMavenProject();
mms.setScm(new ExtractResourceSCM(MavenMultiModuleTest.class.getResource("maven-multimod.zip")));
j.buildAndAssertSuccess(mms);
MavenModule mm = mms.getModule("org.jvnet.hudson.main.test.multimod:moduleA");
j.buildAndAssertSuccess(mms);
assertEquals(2, mms.getLastStableBuild().number);
assertEquals(mms.getLastBuild().getId(), Util.resolveSymlink(new File(mms.getRootDir(), "builds/2")));
assertEquals("2", Util.resolveSymlink(new File(mms.getRootDir(), "builds/lastStableBuild")));
assertEquals("builds/lastStableBuild", Util.resolveSymlink(new File(mms.getRootDir(), "lastStable")));
assertEquals("[lastBuild, lastStableBuild, lastSuccessfulBuild]", permalinks(mms).toString());
assertEquals(2, mm.getLastStableBuild().number);
assertEquals(mm.getLastBuild().getId(), Util.resolveSymlink(new File(mm.getRootDir(), "builds/2")));
assertEquals("2", Util.resolveSymlink(new File(mm.getRootDir(), "builds/lastStableBuild")));
assertEquals("builds/lastStableBuild", Util.resolveSymlink(new File(mm.getRootDir(), "lastStable")));
assertEquals("[lastBuild, lastStableBuild, lastSuccessfulBuild]", permalinks(mm).toString());
}
private static Set<String> permalinks(Job<?,?> j) {
Set<String> r = new TreeSet<String>();
for (PermalinkProjectAction.Permalink l : j.getPermalinks()) {
if (l.resolve(j) != null) {
r.add(l.getId());
}
}
return r;
}

@Test public void incrementalMultiModMaven() throws Exception {
j.configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = j.createMavenProject();

0 comments on commit a92e9da

Please sign in to comment.