├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── _config.yml ├── pom.xml └── src ├── main ├── java │ └── org │ │ └── jenkinsci │ │ └── plugins │ │ └── pipeline │ │ └── multibranch │ │ └── defaults │ │ ├── DefaultsBinder.java │ │ ├── DefaultsMessages.java │ │ ├── PipelineBranchDefaultsProjectFactory.java │ │ └── PipelineMultiBranchDefaultsProject.java ├── resources │ └── org │ │ └── jenkinsci │ │ └── plugins │ │ └── pipeline │ │ └── multibranch │ │ └── defaults │ │ ├── DefaultsMessages.properties │ │ ├── PipelineBranchDefaultsProjectFactory │ │ ├── config.jelly │ │ └── getting-started.jelly │ │ └── index.jelly └── webapp │ └── images │ └── 48x48 │ └── pipelinemultibranchdefaultsproject.png └── test └── java └── org └── jenkinsci └── plugins └── pipeline └── multibranch └── defaults ├── DefaultsBinderTest.java ├── PipelineBranchDefaultsProjectFactoryTest.java └── PipelineMultiBranchDefaultsProjectTest.java /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | end_of_line = crlf 7 | indent_size = 4 8 | continuation_indent_size = 4 9 | indent_style = space 10 | insert_final_newline = false 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | 16 | [**.{js,css,less,html,htm}] 17 | charset = utf-8 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /work 3 | *.iml 4 | /.idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Saponenko Denis 3 | 4 | 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: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Motivation 2 | Concept of Pipeline plugins it requires save Jenkinsfile in root repository. Workflow Multibranch Plugin extend this idea to build all branches in repository. This is very easy for CI. 3 | 4 | In company may be many modules in separate repositories (I have over 100). This is exactly modules. They may be build one Jenkinsfile. But save duplicate Jenkins file each repository makes very hard support. 5 | 6 | This is plugin have Jenkinsfile in [global Jenkins script store](https://github.com/jenkinsci/config-file-provider-plugin). And load is for all tasks. 7 | 8 | The Jenkinsfile may load specified Jenkinsfile from SCM for build concrete module branch. 9 | 10 | # Basics 11 | This plugin extend [workflow-multibranch-plugin](https://github.com/jenkinsci/workflow-multibranch-plugin) and differs only one option in configuration 12 | 13 | # How it works 14 | Config files load in order: 15 | 16 | * Jenkinsfile from root in checkout 17 | * Jenkinsfile from [global Jenkins script store](https://github.com/jenkinsci/config-file-provider-plugin) 18 | * Jenkinsfile from [UI](https://jenkins.io/doc/book/pipeline/overview/#writing-pipeline-scripts-in-the-jenkins-ui) - not realized 19 | 20 | # Configuration steps 21 | ## Create job 22 | Enter name and select job type: 23 | 24 | ![create job](https://habrastorage.org/files/c77/cb7/9a7/c77cb79a7c794f7aa25827dafafb64b0.png) 25 | 26 | ## Select build mode 27 | In job options go to "Build Configuration" section and select "by default Jenkinsfile": 28 | 29 | ![select option](https://habrastorage.org/files/112/bed/263/112bed26372e4b239e12353dc0d73ef6.png) 30 | 31 | 32 | If your select option "by Jenkinsfile" task will also work as a Workflow Multibranch Plugin 33 | 34 | ## Select other options 35 | All other options fully equivalent with Workflow Multibranch Plugin 36 | 37 | ## Create and save default Jenkinsfile 38 | Write your default Jenkinsfile ([Pipeline write tutorial](https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md)) and go to "Managed files" in jenkins manage section: 39 | 40 | ![manage files section](https://habrastorage.org/files/5f5/431/300/5f5431300e8e431ab66ef975f41aaf76.png) 41 | 42 | 43 | Add new config file with Groovy type and Jenkinsfile name: 44 | 45 | ![add config](https://habrastorage.org/files/9d8/143/155/9d81431553144a7bb73320a5a0856c5e.png) 46 | 47 | 48 | Write pipeline: 49 | 50 | ![pipeline](https://habrastorage.org/files/37e/807/853/37e807853c03404bacf8362a1bfc3c50.png) 51 | 52 | ***After change global scripts may require administrative [approval](https://wiki.jenkins-ci.org/display/JENKINS/Script+Security+Plugin)*** 53 | 54 | ## Usage sample 55 | All modules builds default Jenkinsfile. This is libs and other dependencies. But have modules with specific build configurations (run hard tests, deploy to docker etc.) 56 | Default configurations sample: 57 | ```groovy 58 | #!groovy​ 59 | node('builder-01||builder-02||builder-03') { 60 | try { 61 | stage('Checkout') {...} 62 | 63 | stage('Prepare') {...} 64 | 65 | def hasJenkinsfile = fileExists 'Jenkinsfile' 66 | if (hasJenkinsfile) { 67 | load 'Jenkinsfile' // Loading Jenkinsfile from checkout 68 | } else { 69 | stage('Build') {...} 70 | 71 | stage('Test') {...} 72 | } 73 | currentBuild.result = 'SUCCESS' 74 | } catch (error) { 75 | currentBuild.result = 'FAILURE' 76 | throw error 77 | } finally { 78 | stage('Clean') {...} 79 | } 80 | } 81 | ``` 82 | 83 | Jenkinsfile in SCM example: 84 | ```groovy 85 | #!groovy​ 86 | stage('Build') {...} 87 | 88 | stage('Deploy and Tests') {...} 89 | currentBuild.result = 'SUCCESS' 90 | ``` 91 | 92 | # Versions 93 | 1.0 (18.11.2016) - First release under per-plugin versioning scheme. 94 | 95 | 1.1 (05.01.2017) - Actual dependencies versions. Thanks @nichobbs #1 96 | __WARNING__ This version is now saved different then it used to and a rollback of this release is not supported. If you'r unsure, please save your configuration before updating. 97 | Update plugins [Config file provider](https://wiki.jenkins-ci.org/display/JENKINS/Config+File+Provider+Plugin), [Workflow multibranch](https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Multibranch+Plugin) and their dependence. 98 | 99 | 100 | # Authors 101 | * **Saponenko Denis** - *Initial work* - [vaimr](https://github.com/vaimr) 102 | 103 | See also the list of [contributors](https://github.com/vaimr/workflow-multibranch-def-plugin/contributors) who participated in this project. 104 | 105 | # License 106 | ``` 107 | The MIT License 108 | 109 | Copyright (c) 2016 Saponenko Denis 110 | 111 | Permission is hereby granted, free of charge, to any person obtaining a copy 112 | of this software and associated documentation files (the "Software"), to deal 113 | in the Software without restriction, including without limitation the rights 114 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 115 | copies of the Software, and to permit persons to whom the Software is 116 | furnished to do so, subject to the following conditions: 117 | 118 | The above copyright notice and this permission notice shall be included in 119 | all copies or substantial portions of the Software. 120 | 121 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 122 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 123 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 124 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 125 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 126 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 127 | THE SOFTWARE. 128 | ``` 129 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 4.0.0 28 | 29 | org.jenkins-ci.plugins 30 | plugin 31 | 2.19 32 | 33 | 34 | pipeline-multibranch-defaults 35 | 1.2-SNAPSHOT 36 | hpi 37 | Pipeline: Multibranch with defaults 38 | https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Multibranch+Defaults+Plugin 39 | Enhances Pipeline plugin to handle branches better by automatically grouping builds from different 40 | branches. Supports enable one default pipeline 41 | 42 | 43 | 44 | MIT License 45 | http://opensource.org/licenses/MIT 46 | 47 | 48 | 49 | 50 | vaimr 51 | Saponenko Denis 52 | saponenko.denis@gmail.com 53 | 54 | 55 | 56 | scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git 57 | scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git 58 | https://github.com/jenkinsci/${project.artifactId}-plugin 59 | HEAD 60 | 61 | 62 | 63 | repo.jenkins-ci.org 64 | http://repo.jenkins-ci.org/public/ 65 | 66 | 67 | 68 | 69 | repo.jenkins-ci.org 70 | http://repo.jenkins-ci.org/public/ 71 | 72 | 73 | 74 | 1.642.3 75 | 76 | 77 | 78 | org.jenkins-ci.plugins.workflow 79 | workflow-multibranch 80 | 2.9.2 81 | 82 | 83 | org.jenkins-ci.plugins 84 | config-file-provider 85 | 2.15.1 86 | 87 | 88 | 89 | com.cloudbees 90 | groovy-cps 91 | 1.10 92 | test 93 | 94 | 95 | org.jenkins-ci.plugins.workflow 96 | workflow-basic-steps 97 | 2.3 98 | test 99 | 100 | 101 | org.jenkins-ci.plugins.workflow 102 | workflow-durable-task-step 103 | 2.5 104 | test 105 | 106 | 107 | org.jenkins-ci.plugins.workflow 108 | workflow-cps-global-lib 109 | 2.5 110 | test 111 | 112 | 113 | org.jenkins-ci.plugins.workflow 114 | workflow-step-api 115 | 2.6 116 | tests 117 | test 118 | 119 | 120 | org.jenkins-ci.plugins.workflow 121 | workflow-support 122 | 2.11 123 | tests 124 | test 125 | 126 | 127 | org.jenkins-ci.plugins.workflow 128 | workflow-cps 129 | 2.23 130 | tests 131 | test 132 | 133 | 134 | org.jenkins-ci.plugins.workflow 135 | workflow-scm-step 136 | 2.3 137 | tests 138 | test 139 | 140 | 141 | org.jenkins-ci.plugins 142 | git 143 | 2.5.2 144 | test 145 | 146 | 147 | org.apache.httpcomponents 148 | httpclient 149 | 150 | 151 | 152 | 153 | org.jenkins-ci.plugins 154 | subversion 155 | 2.6 156 | test 157 | 158 | 159 | org.jenkins-ci.plugins 160 | git 161 | 2.5.2 162 | tests 163 | test 164 | 165 | 166 | org.apache.httpcomponents 167 | httpclient 168 | 169 | 170 | 171 | 172 | org.jenkins-ci.plugins 173 | subversion 174 | 2.6 175 | tests 176 | test 177 | 178 | 179 | org.jenkins-ci.plugins.workflow 180 | workflow-job 181 | 2.9 182 | tests 183 | test 184 | 185 | 186 | org.jenkins-ci.modules 187 | sshd 188 | 1.6 189 | test 190 | 191 | 192 | 193 | org.jenkins-ci.plugins 194 | matrix-auth 195 | 1.4 196 | test 197 | 198 | 199 | 200 | 201 | 202 | org.jenkins-ci.tools 203 | maven-hpi-plugin 204 | 205 | 206 | FINE 207 | 208 | 209 | 210 | 211 | maven-jar-plugin 212 | 213 | 214 | 215 | test-jar 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pipeline/multibranch/defaults/DefaultsBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016 Saponenko Denis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.pipeline.multibranch.defaults; 26 | 27 | import hudson.Extension; 28 | import hudson.model.*; 29 | import jenkins.model.Jenkins; 30 | import org.jenkinsci.lib.configprovider.ConfigProvider; 31 | import org.jenkinsci.lib.configprovider.model.Config; 32 | import org.jenkinsci.plugins.configfiles.ConfigFileStore; 33 | import org.jenkinsci.plugins.configfiles.GlobalConfigFiles; 34 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 35 | import org.jenkinsci.plugins.workflow.flow.FlowDefinition; 36 | import org.jenkinsci.plugins.workflow.flow.FlowDefinitionDescriptor; 37 | import org.jenkinsci.plugins.workflow.flow.FlowExecution; 38 | import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner; 39 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 40 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 41 | import org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory; 42 | 43 | import java.util.List; 44 | 45 | /** 46 | * Checks out the local default version of {@link WorkflowBranchProjectFactory#SCRIPT} in order if exist: 47 | * 1. From module checkout 48 | * 1. From task workspace directory 49 | * 2. From global jenkins managed files 50 | */ 51 | class DefaultsBinder extends FlowDefinition { 52 | 53 | @Override 54 | public FlowExecution create(FlowExecutionOwner handle, TaskListener listener, List actions) throws Exception { 55 | Jenkins jenkins = Jenkins.getInstance(); 56 | if (jenkins == null) { 57 | throw new IllegalStateException("inappropriate context"); 58 | } 59 | Queue.Executable exec = handle.getExecutable(); 60 | if (!(exec instanceof WorkflowRun)) { 61 | throw new IllegalStateException("inappropriate context"); 62 | } 63 | 64 | ConfigFileStore store = GlobalConfigFiles.get(); 65 | if (store != null) { 66 | Config config = store.getById(PipelineBranchDefaultsProjectFactory.SCRIPT); 67 | if (config != null) { 68 | return new CpsFlowDefinition(config.content, false).create(handle, listener, actions); 69 | } 70 | } 71 | throw new IllegalArgumentException("Default " + PipelineBranchDefaultsProjectFactory.SCRIPT + " not found. Check configuration."); 72 | } 73 | 74 | @Extension 75 | public static class DescriptorImpl extends FlowDefinitionDescriptor { 76 | 77 | @Override 78 | public String getDisplayName() { 79 | return "Pipeline script from default " + PipelineBranchDefaultsProjectFactory.SCRIPT; 80 | } 81 | 82 | } 83 | 84 | /** 85 | * 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. 86 | */ 87 | @Extension 88 | public static class HideMeElsewhere extends DescriptorVisibilityFilter { 89 | 90 | @Override 91 | public boolean filter(Object context, Descriptor descriptor) { 92 | if (descriptor instanceof DescriptorImpl) { 93 | return context instanceof WorkflowJob && ((WorkflowJob) context).getParent() instanceof PipelineMultiBranchDefaultsProject; 94 | } 95 | return true; 96 | } 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pipeline/multibranch/defaults/DefaultsMessages.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016 Saponenko Denis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.pipeline.multibranch.defaults; 26 | 27 | import org.jvnet.localizer.Localizable; 28 | import org.jvnet.localizer.ResourceBundleHolder; 29 | 30 | /** 31 | * Generated localization support class. 32 | */ 33 | @SuppressWarnings({ 34 | "", 35 | "PMD", 36 | "all" 37 | }) 38 | public class DefaultsMessages { 39 | /** 40 | * The resource bundle reference 41 | */ 42 | private final static ResourceBundleHolder holder = ResourceBundleHolder.get(DefaultsMessages.class); 43 | 44 | /** 45 | * Key {@code PipelineMultiBranchDefaultsProject.Description}: {@code Creates a 46 | * set of Pipeline projects according to detected branches in one SCM 47 | * repository.}. 48 | * 49 | * @return {@code Creates a set of Pipeline projects according to detected 50 | * branches in one SCM repository.} 51 | */ 52 | public static String PipelineMultiBranchDefaultsProject_Description() { 53 | return holder.format("PipelineMultiBranchDefaultsProject.Description"); 54 | } 55 | 56 | /** 57 | * Key {@code PipelineMultiBranchDefaultsProject.Description}: {@code Creates a 58 | * set of Pipeline projects according to detected branches in one SCM 59 | * repository.}. 60 | * 61 | * @return {@code Creates a set of Pipeline projects according to detected 62 | * branches in one SCM repository.} 63 | */ 64 | public static Localizable _PipelineMultiBranchDefaultsProject_Description() { 65 | return new Localizable(holder, "PipelineMultiBranchDefaultsProject.Description"); 66 | } 67 | 68 | /** 69 | * Key {@code PipelineMultiBranchDefaultsProject.DisplayName}: {@code Multibranch 70 | * Pipeline}. 71 | * 72 | * @return {@code Multibranch Pipeline} 73 | */ 74 | public static String PipelineMultiBranchDefaultsProject_DisplayName() { 75 | return holder.format("PipelineMultiBranchDefaultsProject.DisplayName"); 76 | } 77 | 78 | /** 79 | * Key {@code PipelineMultiBranchDefaultsProject.DisplayName}: {@code Multibranch 80 | * Pipeline}. 81 | * 82 | * @return {@code Multibranch Pipeline} 83 | */ 84 | public static Localizable _PipelineMultiBranchDefaultsProject_DisplayName() { 85 | return new Localizable(holder, "PipelineMultiBranchDefaultsProject.DisplayName"); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pipeline/multibranch/defaults/PipelineBranchDefaultsProjectFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016 Saponenko Denis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.pipeline.multibranch.defaults; 26 | 27 | import hudson.Extension; 28 | import hudson.model.TaskListener; 29 | import jenkins.branch.MultiBranchProject; 30 | import jenkins.scm.api.SCMSource; 31 | import jenkins.scm.api.SCMSourceCriteria; 32 | import org.jenkinsci.plugins.workflow.flow.FlowDefinition; 33 | import org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory; 34 | import org.kohsuke.stapler.DataBoundConstructor; 35 | 36 | import javax.annotation.Nonnull; 37 | import java.io.IOException; 38 | 39 | /** 40 | * Recognizes and builds by default {@code Jenkinsfile}. 41 | */ 42 | public class PipelineBranchDefaultsProjectFactory extends WorkflowBranchProjectFactory { 43 | public static final String SCRIPT = "Jenkinsfile"; 44 | 45 | @DataBoundConstructor 46 | public PipelineBranchDefaultsProjectFactory() { 47 | } 48 | 49 | @Override 50 | protected FlowDefinition createDefinition() { 51 | return new DefaultsBinder(); 52 | } 53 | 54 | @Override 55 | protected SCMSourceCriteria getSCMSourceCriteria(SCMSource source) { 56 | return new SCMSourceCriteria() { 57 | @Override 58 | public boolean isHead(Probe probe, TaskListener listener) throws IOException { 59 | return true; 60 | } 61 | }; 62 | } 63 | 64 | @Extension 65 | public static class DescriptorDefaultImpl extends AbstractWorkflowBranchProjectFactoryDescriptor { 66 | 67 | @Override 68 | public boolean isApplicable(Class clazz) { 69 | return PipelineMultiBranchDefaultsProject.class.isAssignableFrom(clazz); 70 | } 71 | 72 | @Nonnull 73 | @Override 74 | public String getDisplayName() { 75 | return "by default " + SCRIPT; 76 | } 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pipeline/multibranch/defaults/PipelineMultiBranchDefaultsProject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016 Saponenko Denis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.pipeline.multibranch.defaults; 26 | 27 | import hudson.Extension; 28 | import hudson.model.ItemGroup; 29 | import hudson.model.TopLevelItem; 30 | import jenkins.branch.BranchProjectFactory; 31 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 32 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 33 | import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; 34 | 35 | import javax.annotation.Nonnull; 36 | 37 | /** 38 | * Representation of a set of workflows keyed off of source branches. 39 | */ 40 | @SuppressWarnings({"unchecked", "rawtypes"}) // core’s fault 41 | public class PipelineMultiBranchDefaultsProject extends WorkflowMultiBranchProject { 42 | 43 | public PipelineMultiBranchDefaultsProject(ItemGroup parent, String name) { 44 | super(parent, name); 45 | } 46 | 47 | @Nonnull 48 | protected BranchProjectFactory newProjectFactory() { 49 | return new PipelineBranchDefaultsProjectFactory(); 50 | } 51 | 52 | @Extension 53 | public static class DescriptorImpl extends WorkflowMultiBranchProject.DescriptorImpl { 54 | 55 | @Nonnull 56 | @Override 57 | public String getDisplayName() { 58 | return DefaultsMessages.PipelineMultiBranchDefaultsProject_DisplayName(); 59 | } 60 | 61 | public String getDescription() { 62 | return DefaultsMessages.PipelineMultiBranchDefaultsProject_Description(); 63 | } 64 | 65 | public String getIconFilePathPattern() { 66 | return "plugin/pipeline-multibranch-defaults/images/:size/pipelinemultibranchdefaultsproject.png"; 67 | } 68 | 69 | @Override 70 | public TopLevelItem newInstance(ItemGroup parent, String name) { 71 | return new PipelineMultiBranchDefaultsProject(parent, name); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pipeline/multibranch/defaults/DefaultsMessages.properties: -------------------------------------------------------------------------------- 1 | PipelineMultiBranchDefaultsProject.DisplayName=Multibranch Pipeline with defaults 2 | PipelineMultiBranchDefaultsProject.Description=Extend Multibranch pipeline plugin and build branches it the default prepred pipeline script.\ 3 | Creates a set of Pipeline projects according to detected branches in one SCM repository. -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pipeline/multibranch/defaults/PipelineBranchDefaultsProjectFactory/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pipeline/multibranch/defaults/PipelineBranchDefaultsProjectFactory/getting-started.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | Pipeline Branch projects support building branches within a repository with a file named 27 | Jenkinsfile 28 | in the Jenkins global files or scm module root directory. 29 | This file should contain a valid 30 | Jenkins 32 | Pipeline script. See also: 33 | 35 | Workflow Multibranch Plugin. 36 | 38 | Creating Multibranch Projects. 39 | 40 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pipeline/multibranch/defaults/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 |
28 | Extension for workflow-multibranch-plugin. Automatically build branches the prepared default pipeline script. 29 |
30 | -------------------------------------------------------------------------------- /src/main/webapp/images/48x48/pipelinemultibranchdefaultsproject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaimr/pipeline-multibranch-defaults-plugin/37c50abd281fb885914c9b0567a47527d82486c8/src/main/webapp/images/48x48/pipelinemultibranchdefaultsproject.png -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pipeline/multibranch/defaults/DefaultsBinderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016 Saponenko Denis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.pipeline.multibranch.defaults; 26 | 27 | import jenkins.branch.BranchProperty; 28 | import jenkins.branch.BranchSource; 29 | import jenkins.branch.DefaultBranchPropertyStrategy; 30 | import jenkins.plugins.git.GitSCMSource; 31 | import jenkins.plugins.git.GitSampleRepoRule; 32 | import org.jenkinsci.lib.configprovider.ConfigProvider; 33 | import org.jenkinsci.lib.configprovider.model.Config; 34 | import org.jenkinsci.plugins.configfiles.ConfigFileStore; 35 | import org.jenkinsci.plugins.configfiles.GlobalConfigFiles; 36 | import org.jenkinsci.plugins.configfiles.groovy.GroovyScript; 37 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 38 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 39 | import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; 40 | import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; 41 | import org.junit.ClassRule; 42 | import org.junit.Rule; 43 | import org.junit.Test; 44 | import org.jvnet.hudson.test.BuildWatcher; 45 | import org.jvnet.hudson.test.JenkinsRule; 46 | 47 | import static net.sf.ezmorph.test.ArrayAssertions.assertEquals; 48 | import static org.junit.Assert.assertNotNull; 49 | 50 | public class DefaultsBinderTest { 51 | @ClassRule 52 | public static BuildWatcher buildWatcher = new BuildWatcher(); 53 | @Rule 54 | public JenkinsRule r = new JenkinsRule(); 55 | @Rule 56 | public GitSampleRepoRule sampleGitRepo = new GitSampleRepoRule(); 57 | 58 | 59 | @Test 60 | public void testDefaultJenkinsFile() throws Exception { 61 | GlobalConfigFiles globalConfigFiles = r.jenkins.getExtensionList(GlobalConfigFiles.class).get(GlobalConfigFiles.class); 62 | ConfigFileStore store = globalConfigFiles.get(); 63 | 64 | Config config = new GroovyScript("Jenkinsfile", "Jenkinsfile", "", 65 | "semaphore 'wait'; node {checkout scm; echo readFile('file')}"); 66 | store.save(config); 67 | 68 | sampleGitRepo.init(); 69 | sampleGitRepo.write("file", "initial content"); 70 | sampleGitRepo.git("commit", "--all", "--message=flow"); 71 | WorkflowMultiBranchProject mp = r.jenkins.createProject(PipelineMultiBranchDefaultsProject.class, "p"); 72 | mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleGitRepo.toString(), "", "*", "", false), 73 | new DefaultBranchPropertyStrategy(new BranchProperty[0]))); 74 | WorkflowJob p = PipelineMultiBranchDefaultsProjectTest.scheduleAndFindBranchProject(mp, "master"); 75 | SemaphoreStep.waitForStart("wait/1", null); 76 | WorkflowRun b1 = p.getLastBuild(); 77 | assertNotNull(b1); 78 | assertEquals(1, b1.getNumber()); 79 | SemaphoreStep.success("wait/1", null); 80 | r.assertLogContains("initial content", r.waitForCompletion(b1)); 81 | } 82 | 83 | @Test 84 | public void testDefaultJenkinsFileLoadFromWorkspace() throws Exception { 85 | GlobalConfigFiles globalConfigFiles = r.jenkins.getExtensionList(GlobalConfigFiles.class).get(GlobalConfigFiles.class); 86 | ConfigFileStore store = globalConfigFiles.get(); 87 | Config config = new GroovyScript("Jenkinsfile", "Jenkinsfile", "", 88 | "semaphore 'wait'; node {checkout scm; load 'Jenkinsfile'}"); 89 | store.save(config); 90 | 91 | 92 | sampleGitRepo.init(); 93 | sampleGitRepo.write("Jenkinsfile", "echo readFile('file')"); 94 | sampleGitRepo.git("add", "Jenkinsfile"); 95 | sampleGitRepo.write("file", "initial content"); 96 | sampleGitRepo.git("commit", "--all", "--message=flow"); 97 | WorkflowMultiBranchProject mp = r.jenkins.createProject(PipelineMultiBranchDefaultsProject.class, "p"); 98 | mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleGitRepo.toString(), "", "*", "", false), 99 | new DefaultBranchPropertyStrategy(new BranchProperty[0]))); 100 | WorkflowJob p = PipelineMultiBranchDefaultsProjectTest.scheduleAndFindBranchProject(mp, "master"); 101 | SemaphoreStep.waitForStart("wait/1", null); 102 | WorkflowRun b1 = p.getLastBuild(); 103 | assertNotNull(b1); 104 | assertEquals(1, b1.getNumber()); 105 | SemaphoreStep.success("wait/1", null); 106 | r.assertLogContains("initial content", r.waitForCompletion(b1)); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pipeline/multibranch/defaults/PipelineBranchDefaultsProjectFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016 Saponenko Denis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.pipeline.multibranch.defaults; 26 | 27 | import jenkins.branch.BranchSource; 28 | import jenkins.plugins.git.GitSCMSource; 29 | import jenkins.plugins.git.GitSampleRepoRule; 30 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 31 | import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; 32 | import org.junit.ClassRule; 33 | import org.junit.Rule; 34 | import org.junit.Test; 35 | import org.jvnet.hudson.test.BuildWatcher; 36 | import org.jvnet.hudson.test.JenkinsRule; 37 | 38 | import static net.sf.ezmorph.test.ArrayAssertions.assertEquals; 39 | 40 | public class PipelineBranchDefaultsProjectFactoryTest { 41 | @ClassRule 42 | public static BuildWatcher buildWatcher = new BuildWatcher(); 43 | @Rule 44 | public JenkinsRule r = new JenkinsRule(); 45 | @Rule 46 | public GitSampleRepoRule sampleRepo = new GitSampleRepoRule(); 47 | 48 | @Test 49 | public void allBranches() throws Exception { 50 | sampleRepo.init(); 51 | sampleRepo.git("checkout", "-b", "dev/main"); 52 | sampleRepo.write("file", "initial content"); 53 | sampleRepo.git("add", "file"); 54 | sampleRepo.git("commit", "--all", "--message=flow"); 55 | WorkflowMultiBranchProject mp = r.jenkins.createProject(PipelineMultiBranchDefaultsProject.class, "p"); 56 | mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false))); 57 | WorkflowJob p = PipelineMultiBranchDefaultsProjectTest.scheduleAndFindBranchProject(mp, "dev%2Fmain"); 58 | assertEquals(2, mp.getItems().size()); 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pipeline/multibranch/defaults/PipelineMultiBranchDefaultsProjectTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016 Saponenko Denis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.pipeline.multibranch.defaults; 26 | 27 | import com.cloudbees.hudson.plugins.folder.computed.FolderComputation; 28 | import org.jenkinsci.plugins.pipeline.multibranch.defaults.PipelineBranchDefaultsProjectFactory; 29 | import org.jenkinsci.plugins.pipeline.multibranch.defaults.PipelineMultiBranchDefaultsProject; 30 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 31 | import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; 32 | import org.junit.Rule; 33 | import org.junit.Test; 34 | import org.jvnet.hudson.test.JenkinsRule; 35 | 36 | import javax.annotation.Nonnull; 37 | 38 | import static junit.framework.TestCase.fail; 39 | import static org.junit.Assert.assertTrue; 40 | 41 | /** 42 | * Created by dsaponenko on 09.10.16. 43 | */ 44 | public class PipelineMultiBranchDefaultsProjectTest { 45 | @Rule 46 | public JenkinsRule r = new JenkinsRule(); 47 | 48 | @Test 49 | public void newProjectFactory() throws Exception { 50 | assertTrue(r.jenkins.createProject(PipelineMultiBranchDefaultsProject.class, "test"). 51 | newProjectFactory() instanceof PipelineBranchDefaultsProjectFactory); 52 | } 53 | 54 | 55 | public static 56 | @Nonnull 57 | WorkflowJob scheduleAndFindBranchProject(@Nonnull WorkflowMultiBranchProject mp, @Nonnull String name) throws Exception { 58 | mp.scheduleBuild2(0).getFuture().get(); 59 | return findBranchProject(mp, name); 60 | } 61 | 62 | public static 63 | @Nonnull 64 | WorkflowJob findBranchProject(@Nonnull WorkflowMultiBranchProject mp, @Nonnull String name) throws Exception { 65 | WorkflowJob p = mp.getItem(name); 66 | showIndexing(mp); 67 | if (p == null) { 68 | fail(name + " project not found"); 69 | } 70 | return p; 71 | } 72 | 73 | static void showIndexing(@Nonnull WorkflowMultiBranchProject mp) throws Exception { 74 | FolderComputation indexing = mp.getIndexing(); 75 | System.out.println("---%<--- " + indexing.getUrl()); 76 | indexing.writeWholeLogTo(System.out); 77 | System.out.println("---%<--- "); 78 | } 79 | } --------------------------------------------------------------------------------