Skip to content
Permalink
Browse files

Pass marked revision to decorateRevisionToBuild()

[FIXED JENKINS-25191]

cherry-picked 80a396f
  • Loading branch information
wannessels committed Oct 20, 2014
1 parent 6b81fcd commit a9f9d9b9ea0addf917b61bde829bf123a9633f0c
@@ -858,7 +858,7 @@ public EnvVars getEnvironment() {
Revision rev = marked;
// Modify the revision based on extensions
for (GitSCMExtension ext : extensions) {
rev = ext.decorateRevisionToBuild(this,build,git,listener,rev);
rev = ext.decorateRevisionToBuild(this,build,git,listener,marked,rev);
}
Build revToBuild = new Build(marked, rev, build.getNumber(), null);
buildData.saveBuild(revToBuild);
@@ -90,7 +90,7 @@ public FilePath getWorkingDirectory(GitSCM scm, AbstractProject<?, ?> context, F
* the chosen revision and returning it) or manipulate the state of the working tree (such as
* running git-clean.)
*
* <h3>{@link #decorateRevisionToBuild(GitSCM, Run, GitClient, TaskListener, Revision)} vs {@link BuildChooser}</h3>
* <h3>{@link #decorateRevisionToBuild(GitSCM, Run, GitClient, TaskListener, Revision, Revision)} vs {@link BuildChooser}</h3>
* <p>
* {@link BuildChooser} and this method are similar in the sense that they both participate in the process
* of determining what commits to build. So when a plugin wants to control the commit to be built, you have
@@ -101,29 +101,31 @@ public FilePath getWorkingDirectory(GitSCM scm, AbstractProject<?, ?> context, F
* control what commit to build. For example the gerrit-trigger plugin looks at
* a specific build parameter, then retrieves that commit from Gerrit and builds that.
*
* {@link #decorateRevisionToBuild(GitSCM, Run, GitClient, TaskListener, Revision)} is suitable
* {@link #decorateRevisionToBuild(GitSCM, Run, GitClient, TaskListener, Revision, Revision)} is suitable
* when you accept arbitrary revision as an input and then create some derivative commits and then build that
* result. The primary example is for speculative merge with another branch (people use this to answer
* the question of "what happens if I were to integrate this feature branch back to the master branch?")
*
* @param marked
* The revision that started this build. (e.g. pre-merge)
* @param rev
* The revision selected for this build.
* @return
* The revision selected for this build. Unless you are decorating the given {@code rev}, return the value
* given in the {@code rev} parameter.
*/
public Revision decorateRevisionToBuild(GitSCM scm, Run<?,?> build, GitClient git, TaskListener listener, Revision rev) throws IOException, InterruptedException, GitException {
public Revision decorateRevisionToBuild(GitSCM scm, Run<?,?> build, GitClient git, TaskListener listener, Revision marked, Revision rev) throws IOException, InterruptedException, GitException {
if (build instanceof AbstractBuild && listener instanceof BuildListener) {
return decorateRevisionToBuild(scm, (AbstractBuild) build, git, (BuildListener) listener, rev);
return decorateRevisionToBuild(scm, (AbstractBuild) build, git, (BuildListener) listener, marked, rev);
} else {
return rev;
}
}

@Deprecated
public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?,?> build, GitClient git, BuildListener listener, Revision rev) throws IOException, InterruptedException, GitException {
if (Util.isOverridden(GitSCMExtension.class, getClass(), "decorateRevisionToBuild", GitSCM.class, Run.class, GitClient.class, TaskListener.class, Revision.class)) {
return decorateRevisionToBuild(scm, (Run) build, git, listener, rev);
public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?,?> build, GitClient git, BuildListener listener, Revision marked, Revision rev) throws IOException, InterruptedException, GitException {
if (Util.isOverridden(GitSCMExtension.class, getClass(), "decorateRevisionToBuild", GitSCM.class, Run.class, GitClient.class, TaskListener.class, Revision.class, Revision.class)) {
return decorateRevisionToBuild(scm, (Run) build, git, listener, marked, rev);
} else {
return rev;
}
@@ -49,7 +49,7 @@ public UserMergeOptions getOptions() {
}

@Override
public Revision decorateRevisionToBuild(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener, Revision rev) throws IOException, InterruptedException {
public Revision decorateRevisionToBuild(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener, Revision marked, Revision rev) throws IOException, InterruptedException {
String remoteBranchRef = GitSCM.getParameterString(options.getRef(), build.getEnvironment(listener));

// if the branch we are merging is already at the commit being built, the entire merge becomes no-op
@@ -85,7 +85,7 @@ public Revision decorateRevisionToBuild(GitSCM scm, Run<?, ?> build, GitClient g
// record the fact that we've tried building 'rev' and it failed, or else
// BuildChooser in future builds will pick up this same 'rev' again and we'll see the exact same merge failure
// all over again.
scm.getBuildData(build).saveBuild(new Build(rev, build.getNumber(), FAILURE));
scm.getBuildData(build).saveBuild(new Build(marked,rev, build.getNumber(), FAILURE));
throw new AbortException("Branch not suitable for integration as it does not merge cleanly");
}

@@ -1002,6 +1002,37 @@ public void testMergeFailed() throws Exception {
assertBuildStatus(Result.FAILURE, build2);
assertFalse("scm polling should not detect any more changes after build", project.poll(listener).hasChanges());
}

@Bug(25191)
public void testMultipleMergeFailed() throws Exception {
FreeStyleProject project = setupSimpleProject("master");

GitSCM scm = new GitSCM(
createRemoteRepositories(),
Collections.singletonList(new BranchSpec("master")),
false, Collections.<SubmoduleConfig>emptyList(),
null, null,
Collections.<GitSCMExtension>emptyList());
project.setScm(scm);
scm.getExtensions().add(new PreBuildMerge(new UserMergeOptions("origin", "integration1", "")));
scm.getExtensions().add(new PreBuildMerge(new UserMergeOptions("origin", "integration2", "")));

commit("dummyFile", johnDoe, "Initial Commit");
testRepo.git.branch("integration1");
testRepo.git.branch("integration2");
build(project, Result.SUCCESS);

final String commitFile = "commitFile";
testRepo.git.checkoutBranch("integration1","master");
commit(commitFile,"abc", johnDoe, "merge conflict with integration2");

testRepo.git.checkoutBranch("integration2","master");
commit(commitFile,"cde", johnDoe, "merge conflict with integration1");

final FreeStyleBuild build = build(project, Result.FAILURE);

assertFalse("scm polling should not detect any more changes after build", project.poll(listener).hasChanges());
}

public void testMergeFailedWithSlave() throws Exception {
FreeStyleProject project = setupSimpleProject("master");

0 comments on commit a9f9d9b

Please sign in to comment.
You can’t perform that action at this time.