提交 28deae77 编写于 作者: K Kohsuke Kawaguchi

Merge branch 'mvnwithbuildsteps'

......@@ -31,6 +31,7 @@ import hudson.EnvVars;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.FilePath;
import hudson.Functions;
import hudson.Indenter;
import hudson.Util;
import hudson.maven.settings.GlobalMavenSettingsProvider;
......@@ -38,12 +39,12 @@ import hudson.maven.settings.MavenSettingsProvider;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.BuildableItemWithBuildWrappers;
import hudson.model.Result;
import hudson.tasks.Builder;
import hudson.model.DependencyGraph;
import hudson.model.Descriptor;
import hudson.model.Descriptor.FormException;
import hudson.model.Executor;
import hudson.model.TaskListener;
import jenkins.model.Jenkins;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.Job;
......@@ -52,6 +53,7 @@ import hudson.model.Queue.Task;
import hudson.model.ResourceActivity;
import hudson.model.SCMedItem;
import hudson.model.Saveable;
import hudson.model.TaskListener;
import hudson.model.TopLevelItem;
import hudson.search.CollectionSearchIndex;
import hudson.search.SearchIndexBuilder;
......@@ -60,7 +62,6 @@ import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrappers;
import hudson.tasks.Fingerprinter;
import hudson.tasks.JavadocArchiver;
import hudson.tasks.Mailer;
import hudson.tasks.Maven;
import hudson.tasks.Maven.MavenInstallation;
......@@ -87,6 +88,7 @@ import java.util.Stack;
import javax.servlet.ServletException;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.apache.commons.lang.math.NumberUtils;
......@@ -111,6 +113,8 @@ import org.kohsuke.stapler.export.Exported;
* @author Kohsuke Kawaguchi
*/
public class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,MavenModuleSetBuild> implements TopLevelItem, ItemGroup<MavenModule>, SCMedItem, Saveable, BuildableItemWithBuildWrappers {
/**
* All {@link MavenModule}s, keyed by their {@link MavenModule#getModuleName()} module name}s.
*/
......@@ -254,6 +258,18 @@ public class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,MavenMod
private DescribableList<BuildWrapper,Descriptor<BuildWrapper>> buildWrappers =
new DescribableList<BuildWrapper, Descriptor<BuildWrapper>>(this);
/**
* List of active {@link Builder}s configured for this project.
*/
private DescribableList<Builder,Descriptor<Builder>> prebuilders =
new DescribableList<Builder,Descriptor<Builder>>(this);
private DescribableList<Builder,Descriptor<Builder>> postbuilders =
new DescribableList<Builder,Descriptor<Builder>>(this);
private Result runPostStepsIfResult;
/**
* @deprecated
* Use {@link #MavenModuleSet(ItemGroup, String)}
......@@ -266,6 +282,39 @@ public class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,MavenMod
super(parent,name);
}
/**
* Builders that are run before the main Maven execution.
*
* @since 1.433
*/
public DescribableList<Builder,Descriptor<Builder>> getPrebuilders() {
return prebuilders;
}
/**
* Builders that are run after the main Maven execution.
*
* @since 1.433
*/
public DescribableList<Builder,Descriptor<Builder>> getPostbuilders() {
return postbuilders;
}
/**
* {@link #postbuilders} are run if the result is better or equal to this threshold.
*
* @return
* never null
* @since 1.433
*/
public Result getRunPostStepsIfResult() {
return Functions.defaulted(runPostStepsIfResult,Result.FAILURE);
}
public void setRunPostStepsIfResult(Result v) {
this.runPostStepsIfResult = Functions.defaulted(v,Result.FAILURE);
}
public String getUrlChildPrefix() {
// seemingly redundant "./" is used to make sure that ':' is not interpreted as the scheme identifier
return ".";
......@@ -595,16 +644,27 @@ public class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,MavenMod
this.sortedActiveModules = getDisabledModules(false);
}
if(reporters==null)
if(reporters==null){
reporters = new DescribableList<MavenReporter, Descriptor<MavenReporter>>(this);
}
reporters.setOwner(this);
if(publishers==null)
if(publishers==null){
publishers = new DescribableList<Publisher,Descriptor<Publisher>>(this);
}
publishers.setOwner(this);
if(buildWrappers==null)
if(buildWrappers==null){
buildWrappers = new DescribableList<BuildWrapper, Descriptor<BuildWrapper>>(this);
}
buildWrappers.setOwner(this);
if(prebuilders==null){
prebuilders = new DescribableList<Builder,Descriptor<Builder>>(this);
}
prebuilders.setOwner(this);
if(postbuilders==null){
postbuilders = new DescribableList<Builder,Descriptor<Builder>>(this);
}
postbuilders.setOwner(this);
updateTransientActions();
}
......@@ -660,6 +720,8 @@ public class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,MavenMod
publishers.buildDependencyGraph(this,graph);
buildWrappers.buildDependencyGraph(this,graph);
prebuilders.buildDependencyGraph(this,graph);
postbuilders.buildDependencyGraph(this,graph);
}
public MavenModule getRootModule() {
......@@ -677,7 +739,9 @@ public class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,MavenMod
activities.addAll(super.getResourceActivities());
activities.addAll(Util.filter(publishers,ResourceActivity.class));
activities.addAll(Util.filter(buildWrappers,ResourceActivity.class));
activities.addAll(Util.filter(buildWrappers, ResourceActivity.class));
activities.addAll(Util.filter(prebuilders,ResourceActivity.class));
activities.addAll(Util.filter(postbuilders,ResourceActivity.class));
return activities;
}
......@@ -935,6 +999,10 @@ public class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,MavenMod
buildWrappers.rebuild(req,json,BuildWrappers.getFor(this));
settingConfigId = req.getParameter( "maven.mavenSettingsConfigId" );
globalSettingConfigId = req.getParameter( "maven.mavenGlobalSettingConfigId" );
runPostStepsIfResult = Result.fromString(req.getParameter( "post-steps.runIfResult"));
prebuilders.rebuildHetero(req,json, Builder.all(), "prebuilder");
postbuilders.rebuildHetero(req,json, Builder.all(), "postbuilder");
}
/**
......
......@@ -47,7 +47,6 @@ import hudson.model.Computer;
import hudson.model.Environment;
import hudson.model.Executor;
import hudson.model.Fingerprint;
import jenkins.model.Jenkins;
import hudson.model.ParameterDefinition;
import hudson.model.ParametersAction;
import hudson.model.ParametersDefinitionProperty;
......@@ -58,6 +57,7 @@ import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
import hudson.scm.ChangeLogSet;
import hudson.tasks.BuildStep;
import hudson.tasks.BuildWrapper;
import hudson.tasks.MailSender;
import hudson.tasks.Maven.MavenInstallation;
......@@ -71,6 +71,7 @@ import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
......@@ -85,6 +86,8 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.BuildFailureException;
......@@ -123,6 +126,7 @@ import org.sonatype.aether.transfer.TransferListener;
* @author Kohsuke Kawaguchi
*/
public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,MavenModuleSetBuild> {
/**
* {@link MavenReporter}s that will contribute project actions.
* Can be null if there's none.
......@@ -555,12 +559,13 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
private Map<ModuleName,MavenBuild.ProxyImpl2> proxies;
protected Result doRun(final BuildListener listener) throws Exception {
PrintStream logger = listener.getLogger();
Result r = null;
Result r = null;
PrintStream logger = listener.getLogger();
FilePath remoteSettings = null, remoteGlobalSettings = null;
try {
EnvVars envVars = getEnvironment(listener);
MavenInstallation mvn = project.getMaven();
if(mvn==null)
......@@ -601,9 +606,18 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
e.buildEnvVars(envVars); // #3502: too late for getEnvironment to do this
}
if(!preBuild(listener, project.getPublishers()))
return Result.FAILURE;
// run pre build steps
if(!preBuild(listener,project.getPrebuilders())
|| !preBuild(listener,project.getPostbuilders())
|| !preBuild(listener,project.getPublishers())){
r = FAILURE;
return r;
}
if(!build(listener,project.getPrebuilders().toList())){
r = FAILURE;
return r;
}
String settingsConfigId = project.getSettingConfigId();
if (!StringUtils.isBlank(settingsConfigId)) {
......@@ -779,9 +793,17 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
r = Executor.currentExecutor().abortResult();
throw e;
} finally {
// only run post build steps if requested...
if (r==null || r.isBetterOrEqualTo(project.getRunPostStepsIfResult())) {
if(!build(listener,project.getPostbuilders().toList())){
r = FAILURE;
}
}
if (r != null) {
setResult(r);
}
// tear down in reverse order
boolean failed=false;
for( int i=buildEnvironments.size()-1; i>=0; i-- ) {
......@@ -794,6 +816,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
}
}
return r;
} catch (AbortException e) {
if(e.getMessage()!=null)
......@@ -830,6 +853,17 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
}
}
private boolean build(BuildListener listener, Collection<hudson.tasks.Builder> steps) throws IOException, InterruptedException {
for( BuildStep bs : steps ){
if(!perform(bs,listener)) {
LOGGER.fine(MessageFormat.format("{1} failed", bs));
return false;
}
}
return true;
}
/**
* Returns the modules which have not been build since the last successful aggregator build
* though they should be because they had SCM changes.
......
......@@ -38,6 +38,15 @@ THE SOFTWARE.
<p:config-upstream-pseudo-trigger />
</p:config-trigger>
<f:section title="${%Pre Steps}">
<f:block>
<f:hetero-list name="prebuilder" hasHeader="true"
descriptors="${h.getBuilderDescriptors(it)}"
items="${it.prebuilders}"
addCaption="${%Add pre-build step}"/>
</f:block>
</f:section>
<f:section title="${%Build}">
<j:set var="mavens" value="${it.descriptor.mavenDescriptor.installations}" />
<j:if test="${empty(mavens)}">
......@@ -129,6 +138,22 @@ THE SOFTWARE.
</f:advanced>
</f:section>
<f:section title="${%Post Steps}">
<f:entry description="${%criteriaDescription}">
<f:radio name="post-steps.runIfResult" value="success" checked="${instance.runPostStepsIfResult.toString() =='SUCCESS'}" title="${%runIfStable}"/>
<st:nbsp />
<f:radio name="post-steps.runIfResult" value="unstable" checked="${instance.runPostStepsIfResult.toString() =='UNSTABLE'}" title="${%runIfSuccessful}"/>
<st:nbsp />
<f:radio name="post-steps.runIfResult" value="failure" checked="${instance==null || instance.runPostStepsIfResult.toString() =='FAILURE'}" title="${%runAlways}"/>
</f:entry>
<f:block>
<f:hetero-list name="postbuilder" hasHeader="true"
descriptors="${h.getBuilderDescriptors(it)}"
items="${it.postbuilders}"
addCaption="${%Add post-build step}"/>
</f:block>
</f:section>
<j:invokeStatic var="reporters" className="hudson.maven.MavenReporters" method="getConfigurableList" />
<j:if test="${!empty(reporters)}">
<f:descriptorList title="${%Build Settings}"
......@@ -136,6 +161,7 @@ THE SOFTWARE.
instances="${it.reporters.toMap()}" />
</j:if>
<p:config-buildWrappers />
<p:config-publishers />
</j:jelly>
......@@ -21,4 +21,8 @@
# THE SOFTWARE.
Maven\ Version.error.1=Jenkins needs to know where your Maven2 is installed.
Maven\ Version.error.2=Please do so from <a href="{0}/configure" target="_new">the system configuration</a>.
\ No newline at end of file
Maven\ Version.error.2=Please do so from <a href="{0}/configure" target="_new">the system configuration</a>.
criteriaDescription=Should the post-build steps run only for successful builds, etc.
runIfStable=Run only if build succeeds
runIfSuccessful=Run only if build succeeds or is unstable
runAlways=Run regardless of build result
\ No newline at end of file
......@@ -40,3 +40,8 @@ Resolve\ Dependencies\ during\ Pom\ parsing=Effectue la r\u00e9solution de d\u00
Process\ Plugins\ during\ Pom\ parsing=Analyse les plugins pendant la lecture du POM
Maven\ Validation\ Level=Niveau de validation du POM Maven
Goals=Goals
Add\ post-build\ step=Ajouter une \u00E9tape pr\u00E9-build
Add\ pre-build\ step=Ajouter une \u00E9tape pr\u00E9-build
Post-Build\ Run\ Criteria=Crit\u00E8re pour ex\u00E9cuter le post-build
Steps\ to\ run\ after\ mvn\ build=\u00C9tapes \u00E0 lancer apr\u00E8s le build maven
Steps\ to\ run\ before\ mvn\ build=\u00C9tapes \u00E0 lancer avant le build maven
\ No newline at end of file
......@@ -23,10 +23,12 @@
*/
package hudson.maven;
import hudson.model.Result;
import hudson.tasks.Maven.MavenInstallation;
import java.io.File;
import hudson.tasks.Shell;
import org.junit.Assert;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.ExtractResourceSCM;
......@@ -151,4 +153,30 @@ public class MavenProjectTest extends HudsonTestCase {
project.setGoals("install");
buildAndAssertSuccess(project);
}
/**
* Config roundtrip test around pre/post build step
*/
public void testConfigRoundtrip() throws Exception {
MavenModuleSet m = createMavenProject();
Shell b1 = new Shell("1");
Shell b2 = new Shell("2");
m.getPrebuilders().add(b1);
m.getPostbuilders().add(b2);
configRoundtrip(m);
assertEquals(1, m.getPrebuilders().size());
assertNotSame(b1,m.getPrebuilders().get(Shell.class));
assertEquals("1",m.getPrebuilders().get(Shell.class).getCommand());
assertEquals(1, m.getPostbuilders().size());
assertNotSame(b2,m.getPostbuilders().get(Shell.class));
assertEquals("2",m.getPostbuilders().get(Shell.class).getCommand());
for (Result r : new Result[]{Result.SUCCESS, Result.UNSTABLE, Result.FAILURE}) {
m.setRunPostStepsIfResult(r);
configRoundtrip(m);
assertEquals(r,m.getRunPostStepsIfResult());
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册