Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-8999] Add TriggeredBuildSelector
  • Loading branch information
alanharder committed Apr 16, 2011
1 parent 595614f commit a8a0840
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 10 deletions.
12 changes: 7 additions & 5 deletions src/main/java/hudson/plugins/copyartifact/BuildSelector.java
Expand Up @@ -44,12 +44,14 @@ public abstract class BuildSelector extends AbstractDescribableImpl<BuildSelecto
* @param job Source project
* @param env Environment for build that is copying artifacts
* @param filter Additional filter; returned result should return true (return null otherwise)
* @param parent Build to which artifacts are being copied
* @return Build to use, or null if no appropriate build was found
*/
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter) {
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter, Run<?,?> parent) {
// Backward compatibility:
if (Util.isOverridden(BuildSelector.class, getClass(), "getBuild", Job.class, EnvVars.class)) {
Run<?,?> run = getBuild(job, env);
if (Util.isOverridden(BuildSelector.class, getClass(), "getBuild",
Job.class, EnvVars.class, BuildFilter.class)) {
Run<?,?> run = getBuild(job, env, filter);
return (run != null && filter.isSelectable(run, env)) ? run : null;
}

Expand All @@ -64,8 +66,8 @@ public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter) {
* Older version of API.
*/
@Deprecated
public Run<?,?> getBuild(Job<?,?> job, EnvVars env) {
return getBuild(job, env, new BuildFilter());
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter) {
return getBuild(job, env, filter, null);
}

/**
Expand Down
Expand Up @@ -160,7 +160,7 @@ public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListene
console.println(Messages.CopyArtifact_MissingProject(expandedProject));
return false;
}
Run run = selector.getBuild(job.job, env, job.filter);
Run run = selector.getBuild(job.job, env, job.filter, build);
if (run == null) {
console.println(Messages.CopyArtifact_MissingBuild(expandedProject));
return isOptional(); // Fail build unless copy is optional
Expand Down
Expand Up @@ -48,8 +48,9 @@ public String getParameterName() {
}

@Override
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter) {
return BuildSelectorParameter.getSelectorFromXml(env.get(parameterName)).getBuild(job, env, filter);
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter, Run<?,?> parent) {
return BuildSelectorParameter.getSelectorFromXml(env.get(parameterName))
.getBuild(job, env, filter, parent);
}

@Extension(ordinal=-20)
Expand Down
Expand Up @@ -51,7 +51,7 @@ public PermalinkBuildSelector(String id) {
}

@Override
public Run<?,?> getBuild(Job<?, ?> job, EnvVars env, BuildFilter filter) {
public Run<?,?> getBuild(Job<?, ?> job, EnvVars env, BuildFilter filter, Run<?,?> parent) {
Permalink p = job.getPermalinks().get(id);
if (p==null) return null;
Run<?,?> run = p.resolve(job);
Expand Down
Expand Up @@ -47,7 +47,7 @@ public String getBuildNumber() {
}

@Override
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter) {
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter, Run<?,?> parent) {
Run<?,?> run = job.getBuildByNumber(Integer.parseInt(env.expand(buildNumber)));
return (run != null && filter.isSelectable(run, env)) ? run : null;
}
Expand Down
@@ -0,0 +1,60 @@
/*
* The MIT License
*
* Copyright (c) 2011, Alan Harder
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.copyartifact;

import hudson.EnvVars;
import hudson.Extension;
import hudson.model.Descriptor;
import hudson.model.Cause;
import hudson.model.Cause.UpstreamCause;
import hudson.model.Job;
import hudson.model.Run;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* Copy artifacts from the build that triggered this build.
* @author Alan Harder
*/
public class TriggeredBuildSelector extends BuildSelector {
@DataBoundConstructor
public TriggeredBuildSelector() { }

@Override
public Run<?,?> getBuild(Job<?,?> job, EnvVars env, BuildFilter filter, Run<?,?> parent) {
String jobName = job.getFullName();
for (Cause cause : parent.getCauses()) {
if (cause instanceof UpstreamCause
&& jobName.equals(((UpstreamCause)cause).getUpstreamProject())) {
Run<?,?> run = job.getBuildByNumber(((UpstreamCause)cause).getUpstreamBuild());
return (run != null && filter.isSelectable(run, env)) ? run : null;
}
}
return null;
}

@Extension(ordinal=25)
public static final Descriptor<BuildSelector> DESCRIPTOR =
new SimpleBuildSelectorDescriptor(
TriggeredBuildSelector.class, Messages._TriggeredBuildSelector_DisplayName());
}
Expand Up @@ -13,6 +13,7 @@ PermalinkBuildSelector.DisplayName=Specified by permalink
StatusBuildSelector.DisplayName=Latest successful build
SavedBuildSelector.DisplayName=Latest saved build (marked "keep forever")
SpecificBuildSelector.DisplayName=Specific build
TriggeredBuildSelector.DisplayName=Upstream build that triggered this job
ParameterizedBuildSelector.DisplayName=Specified by a build parameter
BuildSelectorParameter.DisplayName=Build selector for Copy Artifact
WorkspaceSelector.DisplayName=Copy from WORKSPACE of latest completed build
21 changes: 21 additions & 0 deletions src/test/java/hudson/plugins/copyartifact/CopyArtifactTest.java
Expand Up @@ -52,6 +52,7 @@
import hudson.slaves.DumbSlave;
import hudson.slaves.SlaveComputer;
import hudson.tasks.ArtifactArchiver;
import hudson.tasks.BuildTrigger;
import hudson.tasks.Builder;
import hudson.util.VersionNumber;
import java.io.IOException;
Expand Down Expand Up @@ -440,6 +441,26 @@ public void testSpecificBuildSelectorParameter() throws Exception {
assertFile(false, "subdir/subfoo.txt", b);
}

public void testTriggeredBuildSelector() throws Exception {
FreeStyleProject other = createArtifactProject(),
p = createFreeStyleProject();
p.getBuildersList().add(new CopyArtifact(other.getName(),
new TriggeredBuildSelector(), "*.txt", "", false, false));
other.getPublishersList().add(new BuildTrigger(p.getFullName(), false));
hudson.rebuildDependencyGraph();
assertBuildStatusSuccess(other.scheduleBuild2(0, new UserCause()));
// p#1 was triggered, now building.
FreeStyleBuild b = p.getBuildByNumber(1);
for (int i = 0; b == null && i < 1000; i++) { Thread.sleep(10); b = p.getBuildByNumber(1); }
assertNotNull(b);
while (b.isBuilding()) Thread.sleep(10);
assertBuildStatusSuccess(b);
assertFile(true, "foo.txt", b);
assertFile(false, "subdir/subfoo.txt", b);
// Verify error if build not triggered by upstream job:
assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0, new UserCause()).get());
}

public void testFlatten() throws Exception {
FreeStyleProject other = createArtifactProject(),
p = createProject(other.getName(), "", "newdir", false, true, false);
Expand Down

0 comments on commit a8a0840

Please sign in to comment.