-
New Feature
-
Resolution: Unresolved
-
Major
-
Powered by SuggestiMate
It would be nice, in at least the 'build step' part of the parameterized-trigger plugin, to have the option to build conditionally based on SCM polling.
- depends on
-
JENKINS-9209 Condition to demand a parameter to exist
-
- Resolved
-
- is related to
-
JENKINS-11455 Support Parameters for Downstream Projects
-
- Open
-
[JENKINS-10147] Add 'poll SCM' option to build step
I'd also like to see this feature added. The parameterized-trigger is extremely useful for my setup but the fact it's lacking SCM polling really limits what I can do with it. If huybrechts is not able to fix this could it be assigned to someone else or give any pointers as to how I'd add the feature myself?
Regards,
Tom.
I fixed the problem with a very-temporary hack in the code, waiting for an official patch.
I have added this code :
SCM scm = project.getScm(); if (scm != null) { // Check that we don't have change in SCM PollingResult res = project.poll(LogTaskListener.NULL); if (res == NO_CHANGES) { // Check that we have a sucessfull build Run success = project.getLastSuccessfulBuild(); if (success != null) { listener.getLogger().println("Skipping " + HyperlinkNote.encodeTo('/'+ project.getUrl(), project.getFullDisplayName()) + ". No change happen since last build."); continue; } } }
just before
futures.add(schedule(build, project, list));
in 'perform' method of 'BuildTriggerConfig.java'
and just before
futures.put(project, schedule(build, project, list));
in 'perform2' method of 'BuildTriggerConfig.java'
This import should be added too in this file :
import hudson.console.HyperlinkNote; import hudson.scm.SCM; import hudson.scm.PollingResult; import hudson.util.LogTaskListener; import hudson.model.Run; import static hudson.scm.PollingResult.*;
This seem to work well for me.
Caveats :
- The line 'if (futures.isEmpty())' condition in TriggerBuilder.java print a bad log in the console when all project in the trigger list doesn't need to be rebuild. Not a problem, but not beautiful.
- If the configuration of a project change but not the SCM, the build is not re-triggered.
- Probably some others things.
Caveats (2):
- There is no option in the UI to activate / deactivate this hack.
Here a git diff with a little bit cleaner implementation, with a check box in the UI to activate / deactivate this functionality.
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java b/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java index d955f4c..304337d 100644 --- a/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java +++ b/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java @@ -12,6 +12,11 @@ import hudson.model.Node; import hudson.model.Run; import org.kohsuke.stapler.DataBoundConstructor; +import hudson.scm.SCM; +import hudson.scm.PollingResult; +import hudson.util.LogTaskListener; +import static hudson.scm.PollingResult.*; + import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; @@ -27,22 +32,56 @@ import java.util.concurrent.Future; */ public class BlockableBuildTriggerConfig extends BuildTriggerConfig { private final BlockingBehaviour block; + private final boolean buildScm; + public boolean buildAllNodesWithLabel; - public BlockableBuildTriggerConfig(String projects, BlockingBehaviour block, List<AbstractBuildParameters> configs) { + public BlockableBuildTriggerConfig(String projects, BlockingBehaviour block, boolean buildScm, List<AbstractBuildParameters> configs) { super(projects, ResultCondition.ALWAYS, false, configs); this.block = block; + this.buildScm = buildScm; } @DataBoundConstructor - public BlockableBuildTriggerConfig(String projects, BlockingBehaviour block, List<AbstractBuildParameterFactory> configFactories,List<AbstractBuildParameters> configs) { + public BlockableBuildTriggerConfig(String projects, BlockingBehaviour block, boolean buildScm, List<AbstractBuildParameterFactory> configFactories,List<AbstractBuildParameters> configs) { super(projects, ResultCondition.ALWAYS, false, configFactories, configs); this.block = block; + this.buildScm = buildScm; } public BlockingBehaviour getBlock() { return block; } + + public boolean getBuildScm() { + return buildScm; + } + + @Override + public boolean needRebuild(AbstractProject project) + { + if (getBuildScm() == false) + return true; + + SCM scm = project.getScm(); + + if (scm != null) + { + // Check that we don't have change in SCM + PollingResult res = project.poll(LogTaskListener.NULL); + + if (res == NO_CHANGES) + { + // Check that we have a sucessfull build + Run success = project.getLastSuccessfulBuild(); + + if (success != null) + return false; + } + } + + return true; + } @Override public List<Future<AbstractBuild>> perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java b/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java index d5144a7..c6f52be 100644 --- a/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java +++ b/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java @@ -31,6 +31,8 @@ import hudson.plugins.parameterizedtrigger.AbstractBuildParameters.DontTriggerEx import hudson.tasks.Messages; import hudson.util.FormValidation; +import hudson.console.HyperlinkNote; + import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.AncestorInPath; @@ -201,6 +203,11 @@ public class BuildTriggerConfig implements Describable<BuildTriggerConfig> { } return actions; } + + public boolean needRebuild(AbstractProject project) + { + return true; + } /** * Note that with Hudson 1.341, trigger should be using @@ -222,7 +229,10 @@ public class BuildTriggerConfig implements Describable<BuildTriggerConfig> { for (AbstractProject project : getProjectList(build.getProject().getParent(),env)) { List<Action> list = getBuildActions(actions, project); - futures.add(schedule(build, project, list)); + if (needRebuild(project)) + futures.add(schedule(build, project, list)); + else + listener.getLogger().println("Skipping " + HyperlinkNote.encodeTo('/'+ project.getUrl(), project.getFullDisplayName()) + ". Don't need to rebuild."); } } @@ -247,7 +257,10 @@ public class BuildTriggerConfig implements Describable<BuildTriggerConfig> { for (AbstractProject project : getProjectList(build.getProject().getParent(),env)) { List<Action> list = getBuildActions(actions, project); - futures.put(project, schedule(build, project, list)); + if (needRebuild(project)) + futures.put(project, schedule(build, project, list)); + else + listener.getLogger().println("Skipping " + HyperlinkNote.encodeTo('/'+ project.getUrl(), project.getFullDisplayName()) + ". Don't need to rebuild."); } } return futures; diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java b/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java index b5b4262..fb6b100 100644 --- a/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java +++ b/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java @@ -99,7 +99,7 @@ public class TriggerBuilder extends Builder implements DependecyDeclarer { if(!projectList.isEmpty()){ //handle non-blocking configs if(futures.isEmpty()){ - listener.getLogger().println("Triggering projects: " + getProjectListAsString(projectList)); + listener.getLogger().println("Triggering or skipped projects: " + getProjectListAsString(projectList)); continue; } //handle blocking configs diff --git a/src/main/resources/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig/config.jelly b/src/main/resources/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig/config.jelly index 1c49bbd..a279ef5 100644 --- a/src/main/resources/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig/config.jelly +++ b/src/main/resources/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig/config.jelly @@ -22,9 +22,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> + <f:entry title="${%Projects to build}" field="projects"> <f:textbox /> </f:entry> + + <f:block> + <f:checkbox title="${%Build triggered projects only if there is SCM changes}" field="buildScm" checked="${instance.buildScm==true}" /> + </f:block> + <!-- TODO: replace with <f:optionalProperty> --> <f:optionalBlock field="block" title="${%Block until the triggered projects finish their builds}" checked="${instance.block!=null}"> <j:set var="descriptor" value="${app.getDescriptorOrDie(descriptor.getPropertyType(field).clazz)}" />
Hi,
This bug is assigned to huybrechts yet that user seems inactive in the Jenkins community. Can the issue be reassigned and the above patch integrated into the next release?
Tom
As this has popped to the top of the list and I am trying to look at all of these issues, I can see that this issue could be resolved when the Run condition branch is added.
In this case you could create a run condition that could poll a project for changes before triggering other builds, and this then keeps the changes needed separate from this plugin. As in most cases this is not a requirement for triggering a downstream build.
Note: I have requested reviews on the pending pull requests, and will look at getting a new release done soon.
This would make such a big difference as it would allow for a single project to be built and the project itself could check that all its dependencies are up to date instead of just always building the dependencies again and again.... Please can this be placed in a release soon as it seems to be the missing piece of the puzzle. Much appreciated
Has there been any development on getting this feature added to the plugin?
I'd like to see this feature also. There is short description of my use case here. Basically I'd like to be able to use the 'trigger build only if downstream job has SCM changes' functionality from the Downstream Ext plugin to be available when triggering downstream jobs with parameters.
If possible I'd like to raise the priority of this request (rather than creating a duplicate with the higher priority) as it's quite important for our use case.
Ta
Andy