diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..047f44d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# editorconfig.org + +root = true + +[*] +end_of_line = crlf +indent_size = 4 +continuation_indent_size = 4 +indent_style = space +insert_final_newline = false +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[**.{js,css,less,html,htm}] +charset = utf-8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a29cd7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +target +work +workflow-multibranch.iml +.idea \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..063f4a6 --- /dev/null +++ b/pom.xml @@ -0,0 +1,211 @@ + + + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 2.12 + + + org.jenkins-ci.plugins.workflow + workflow-multibranch-def + 1.0-SNAPSHOT + hpi + Pipeline: Multibranch with defaults + https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Multibranch+Def+Plugin + Enhances Pipeline plugin to handle branches better by automatically grouping builds from different + branches. Supports enable one default pipeline + + + + MIT License + http://opensource.org/licenses/MIT + + + + scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git + scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git + https://github.com/jenkinsci/${project.artifactId}-plugin + HEAD + + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + + + 1.642.3 + + + + ${project.groupId} + workflow-multibranch + 2.9 + + + org.jenkins-ci.plugins + config-file-provider + 2.11 + + + + ${project.groupId} + workflow-basic-steps + 2.1 + test + + + ${project.groupId} + workflow-durable-task-step + 2.3 + test + + + ${project.groupId} + workflow-cps-global-lib + 2.1 + test + + + ${project.groupId} + workflow-step-api + 2.3 + tests + test + + + ${project.groupId} + workflow-support + 2.2 + tests + test + + + org.jenkins-ci.plugins.workflow + workflow-cps + 2.10 + tests + test + + + ${project.groupId} + workflow-scm-step + 2.2 + tests + test + + + org.jenkins-ci.plugins + git + 2.5.2 + test + + + org.apache.httpcomponents + httpclient + + + + + org.jenkins-ci.plugins + subversion + 2.6 + test + + + org.jenkins-ci.plugins + git + 2.5.2 + tests + test + + + org.apache.httpcomponents + httpclient + + + + + org.jenkins-ci.plugins + subversion + 2.6 + tests + test + + + ${project.groupId} + workflow-job + 2.6 + tests + test + + + org.jenkins-ci.modules + sshd + 1.6 + test + + + + org.jenkins-ci.plugins + matrix-auth + 1.4 + test + + + + + + org.jenkins-ci.tools + maven-hpi-plugin + + + FINE + + + + + maven-jar-plugin + + + + test-jar + + + + + + + diff --git a/src/main/java/org/jenkinsci/plugins/workflow/multibranch/DefMessages.java b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/DefMessages.java new file mode 100644 index 0000000..7b5e888 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/DefMessages.java @@ -0,0 +1,64 @@ +package org.jenkinsci.plugins.workflow.multibranch; + +import org.jvnet.localizer.Localizable; +import org.jvnet.localizer.ResourceBundleHolder; + +/** + * Generated localization support class. + */ +@SuppressWarnings({ + "", + "PMD", + "all" +}) +public class DefMessages { + /** + * The resource bundle reference + */ + private final static ResourceBundleHolder holder = ResourceBundleHolder.get(DefMessages.class); + + /** + * Key {@code WorkflowMultiBranchDefProject.Description}: {@code Creates a + * set of Pipeline projects according to detected branches in one SCM + * repository.}. + * + * @return {@code Creates a set of Pipeline projects according to detected + * branches in one SCM repository.} + */ + public static String WorkflowMultiBranchDefProject_Description() { + return holder.format("WorkflowMultiBranchDefProject.Description"); + } + + /** + * Key {@code WorkflowMultiBranchDefProject.Description}: {@code Creates a + * set of Pipeline projects according to detected branches in one SCM + * repository.}. + * + * @return {@code Creates a set of Pipeline projects according to detected + * branches in one SCM repository.} + */ + public static Localizable _WorkflowMultiBranchDefProject_Description() { + return new Localizable(holder, "WorkflowMultiBranchDefProject.Description"); + } + + /** + * Key {@code WorkflowMultiBranchDefProject.DisplayName}: {@code Multibranch + * Pipeline}. + * + * @return {@code Multibranch Pipeline} + */ + public static String WorkflowMultiBranchDefProject_DisplayName() { + return holder.format("WorkflowMultiBranchDefProject.DisplayName"); + } + + /** + * Key {@code WorkflowMultiBranchDefProject.DisplayName}: {@code Multibranch + * Pipeline}. + * + * @return {@code Multibranch Pipeline} + */ + public static Localizable _WorkflowMultiBranchDefProject_DisplayName() { + return new Localizable(holder, "WorkflowMultiBranchDefProject.DisplayName"); + } + +} diff --git a/src/main/java/org/jenkinsci/plugins/workflow/multibranch/DefaultsBinder.java b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/DefaultsBinder.java new file mode 100644 index 0000000..a799a2c --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/DefaultsBinder.java @@ -0,0 +1,90 @@ +package org.jenkinsci.plugins.workflow.multibranch; + +import hudson.Extension; +import hudson.FilePath; +import hudson.model.*; +import jenkins.model.Jenkins; +import org.apache.commons.io.FileUtils; +import org.jenkinsci.lib.configprovider.ConfigProvider; +import org.jenkinsci.lib.configprovider.model.Config; +import org.jenkinsci.plugins.configfiles.groovy.GroovyScript; +import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; +import org.jenkinsci.plugins.workflow.flow.FlowDefinition; +import org.jenkinsci.plugins.workflow.flow.FlowDefinitionDescriptor; +import org.jenkinsci.plugins.workflow.flow.FlowExecution; +import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.io.File; +import java.util.List; + +/** + * Checks out the local default version of {@link WorkflowBranchProjectFactory#SCRIPT} in order if exist: + * 1. From module checkout + * 1. From task workspace directory + * 2. From global jenkins managed files + */ +class DefaultsBinder extends FlowDefinition { + + @Override + public FlowExecution create(FlowExecutionOwner handle, TaskListener listener, List actions) throws Exception { + Jenkins jenkins = Jenkins.getInstance(); + if (jenkins == null) { + throw new IllegalStateException("inappropriate context"); + } + FilePath workspacePath = jenkins.getWorkspaceFor(((WorkflowRun) handle.getExecutable()).getParent()); + if (workspacePath == null || workspacePath.child(WorkflowBranchDefProjectFactory.SCRIPT).exists()) { + throw new IllegalStateException("inappropriate context"); + } + + Queue.Executable executable = handle.getExecutable(); + File rootDir; + if (executable != null) { + WorkflowJob workflowJob = ((WorkflowJob) handle.getExecutable().getParent()); + rootDir = workflowJob.getParent().getRootDir(); + if (rootDir != null) { + File localConfig = new File(rootDir + File.separator + WorkflowBranchDefProjectFactory.SCRIPT); + if (localConfig.exists()) { + return new CpsFlowDefinition(FileUtils.readFileToString(localConfig, "utf-8"), false). + create(handle, listener, actions); + } + } + } + + ConfigProvider configProvider = ConfigProvider.getByIdOrNull(GroovyScript.class.getName()); + if (configProvider != null) { + Config config = configProvider.getConfigById(WorkflowBranchDefProjectFactory.SCRIPT); + if (config != null) { + return new CpsFlowDefinition(config.content, false).create(handle, listener, actions); + } + } + throw new IllegalArgumentException(WorkflowBranchDefProjectFactory.SCRIPT + " not found"); + } + + @Extension + public static class DescriptorImpl extends FlowDefinitionDescriptor { + + @Override + public String getDisplayName() { + return "Pipeline script from default " + WorkflowBranchProjectFactory.SCRIPT; + } + + } + + /** + * Want to display this in the r/o configuration for a branch project, but not offer it on standalone jobs or in any other context. + */ + @Extension + public static class HideMeElsewhere extends DescriptorVisibilityFilter { + + @Override + public boolean filter(Object context, Descriptor descriptor) { + if (descriptor instanceof DescriptorImpl) { + return context instanceof WorkflowJob && ((WorkflowJob) context).getParent() instanceof WorkflowMultiBranchDefProject; + } + return true; + } + + } +} diff --git a/src/main/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory.java b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory.java new file mode 100644 index 0000000..1be240d --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory.java @@ -0,0 +1,74 @@ +/* + * The MIT License + * + * Copyright 2015 CloudBees, Inc. + * + * 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 org.jenkinsci.plugins.workflow.multibranch; + +import hudson.Extension; +import hudson.model.TaskListener; +import jenkins.branch.MultiBranchProject; +import jenkins.scm.api.SCMSource; +import jenkins.scm.api.SCMSourceCriteria; +import org.jenkinsci.plugins.workflow.flow.FlowDefinition; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.io.IOException; + +/** + * Recognizes and builds by default {@code Jenkinsfile}. + */ +public class WorkflowBranchDefProjectFactory extends WorkflowBranchProjectFactory { + + @DataBoundConstructor + public WorkflowBranchDefProjectFactory() { + } + + @Override + protected FlowDefinition createDefinition() { + return new DefaultsBinder(); + } + + @Override + protected SCMSourceCriteria getSCMSourceCriteria(SCMSource source) { + return new SCMSourceCriteria() { + @Override + public boolean isHead(Probe probe, TaskListener listener) throws IOException { + return true; + } + }; + } + + @Extension + public static class DescriptorDefaultImpl extends AbstractWorkflowBranchProjectFactoryDescriptor { + @Override + public boolean isApplicable(Class clazz) { + return super.isApplicable(clazz); + } + + @Override + public String getDisplayName() { + return "by default " + SCRIPT; + } + + } +} diff --git a/src/main/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowMultiBranchDefProject.java b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowMultiBranchDefProject.java new file mode 100644 index 0000000..09b7b4c --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowMultiBranchDefProject.java @@ -0,0 +1,96 @@ +/* + * The MIT License + * + * Copyright 2015 CloudBees, Inc. + * + * 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 org.jenkinsci.plugins.workflow.multibranch; + +import hudson.Extension; +import hudson.model.Action; +import hudson.model.Item; +import hudson.model.ItemGroup; +import hudson.model.TopLevelItem; +import jenkins.branch.BranchProjectFactory; +import jenkins.model.TransientActionFactory; +import org.jenkinsci.plugins.workflow.cps.Snippetizer; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import java.util.Collection; +import java.util.Collections; + +/** + * Representation of a set of workflows keyed off of source branches. + */ +@SuppressWarnings({"unchecked", "rawtypes"}) // core’s fault +public class WorkflowMultiBranchDefProject extends WorkflowMultiBranchProject { + + public WorkflowMultiBranchDefProject(ItemGroup parent, String name) { + super(parent, name); + } + + protected BranchProjectFactory newProjectFactory() { + return new WorkflowBranchDefProjectFactory(); + } + + @Extension + public static class DescriptorImpl extends WorkflowMultiBranchProject.DescriptorImpl { + + @Override + public String getDisplayName() { + return DefMessages.WorkflowMultiBranchDefProject_DisplayName(); + } + + public String getDescription() { + return DefMessages.WorkflowMultiBranchDefProject_Description(); + } + + public String getIconFilePathPattern() { + return "plugin/workflow-multibranch/images/:size/pipelinemultibranchdefproject.png"; + } + + @Override + public TopLevelItem newInstance(ItemGroup parent, String name) { + return new WorkflowMultiBranchDefProject(parent, name); + } + } + + @Extension + public static class PerFolderAdder extends TransientActionFactory { + + @Override + public Class type() { + return WorkflowMultiBranchDefProject.class; + } + + @Override + public Collection createFor(WorkflowMultiBranchDefProject target) { + if (target.hasPermission(Item.EXTENDED_READ)) { + return Collections.singleton(new Snippetizer.LocalAction()); + } else { + return Collections.emptySet(); + } + } + + } + +} diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly new file mode 100644 index 0000000..2fdbf32 --- /dev/null +++ b/src/main/resources/index.jelly @@ -0,0 +1,29 @@ + + + + +
+ Extension for workflow-multibranch-plugin. Automatically build branches the prepared default pipeline script. +
diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/DefMessages.properties b/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/DefMessages.properties new file mode 100644 index 0000000..0bc65f6 --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/DefMessages.properties @@ -0,0 +1,3 @@ +WorkflowMultiBranchDefProject.DisplayName=Multibranch Pipeline with defaults +WorkflowMultiBranchDefProject.Description=Extend Multibranch pipeline plugin and build branches it the default prepred pipeline script.\ + Creates a set of Pipeline projects according to detected branches in one SCM repository. \ No newline at end of file diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory/config.jelly b/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory/config.jelly new file mode 100644 index 0000000..a9800ae --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory/config.jelly @@ -0,0 +1,29 @@ + + + + + + + diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory/getting-started.jelly b/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory/getting-started.jelly new file mode 100644 index 0000000..ca3db2b --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchDefProjectFactory/getting-started.jelly @@ -0,0 +1,36 @@ + + + + Pipeline Branch projects support building branches within a repository with a file named + Jenkinsfile + in the Jenkins global files or scm module root directory. + This file should contain a valid + Jenkins + Pipeline script. See also: + + Creating Multibranch Projects. + diff --git a/src/main/webapp/images/48x48/pipelinemultibranchdefproject.png b/src/main/webapp/images/48x48/pipelinemultibranchdefproject.png new file mode 100644 index 0000000..e3f6b29 Binary files /dev/null and b/src/main/webapp/images/48x48/pipelinemultibranchdefproject.png differ diff --git a/src/test/java/org/jenkinsci/plugins/workflow/multibranch/LocalSCMBinderTest.java b/src/test/java/org/jenkinsci/plugins/workflow/multibranch/LocalSCMBinderTest.java new file mode 100644 index 0000000..bab543c --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/workflow/multibranch/LocalSCMBinderTest.java @@ -0,0 +1,29 @@ +/* + * The MIT License + * + * Copyright 2015 CloudBees, Inc. + * + * 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 org.jenkinsci.plugins.workflow.multibranch; + +public class LocalSCMBinderTest { + +} diff --git a/src/test/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchLocalProjectFactoryTest.java b/src/test/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchLocalProjectFactoryTest.java new file mode 100644 index 0000000..0a268dc --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/workflow/multibranch/WorkflowBranchLocalProjectFactoryTest.java @@ -0,0 +1,29 @@ +/* + * The MIT License + * + * Copyright 2015 CloudBees, Inc. + * + * 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 org.jenkinsci.plugins.workflow.multibranch; + +public class WorkflowBranchLocalProjectFactoryTest { + +}