forked from vaimr/pipeline-multibranch-defaults-plugin
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
340 additions
and
0 deletions.
There are no files selected for viewing
181 changes: 181 additions & 0 deletions
181
...nsci/plugins/pipeline/multibranch/defaults/PipelineMultiBranchDefaultsProjectFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
* The MIT License | ||
* | ||
* Copyright (c) 2016 Saponenko Denis | ||
* Copyright (c) 2018 Sam Gleske - https://github.com/samrocketman | ||
* | ||
* 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.pipeline.multibranch.defaults; | ||
|
||
import hudson.Extension; | ||
import hudson.model.Action; | ||
import hudson.model.Item; | ||
import hudson.model.ItemGroup; | ||
import hudson.model.TaskListener; | ||
import jenkins.branch.MultiBranchProject; | ||
import jenkins.branch.MultiBranchProjectFactory; | ||
import jenkins.branch.MultiBranchProjectFactoryDescriptor; | ||
import jenkins.branch.OrganizationFolder; | ||
import jenkins.model.TransientActionFactory; | ||
import jenkins.scm.api.SCMSource; | ||
import jenkins.scm.api.SCMSourceCriteria; | ||
import org.apache.commons.lang.StringUtils; | ||
import org.jenkinsci.plugins.workflow.cps.Snippetizer; | ||
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
import org.kohsuke.stapler.DataBoundSetter; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.io.IOException; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
|
||
/** | ||
* Recognizes and builds by default {@code Jenkinsfile}. | ||
*/ | ||
public class PipelineMultiBranchDefaultsProjectFactory extends MultiBranchProjectFactory.BySCMSourceCriteria { | ||
public static final String SCRIPT = "Jenkinsfile"; | ||
|
||
private String scriptId = SCRIPT; | ||
private boolean useSandbox = false; | ||
|
||
@DataBoundConstructor | ||
public PipelineMultiBranchDefaultsProjectFactory() { } | ||
|
||
/** | ||
* Set the script ID which will be used to reference the config file | ||
* management for the contents of a Jenkinsfile. | ||
* | ||
* @param scriptId The ID of the groovy script to read as a Jenkinsfile. | ||
*/ | ||
@DataBoundSetter | ||
public void setScriptId(String scriptId) { | ||
if(StringUtils.isEmpty(scriptId)) { | ||
this.scriptId = SCRIPT; | ||
} else { | ||
this.scriptId = scriptId; | ||
} | ||
} | ||
|
||
/** | ||
* Get the script ID which will be used to read the Jenkinsfile from config | ||
* file management. | ||
* | ||
* @return The Jenkinsfile script ID. | ||
*/ | ||
public String getScriptId() { | ||
return scriptId; | ||
} | ||
|
||
/** | ||
* Set whether or not a Jenkinsfile should run within a Groovy sandbox. | ||
* | ||
* @param useSandbox Set true to enable Groovy sandbox or false to run in | ||
* Jenkins master runtime. | ||
*/ | ||
@DataBoundSetter | ||
public void setUseSandbox(boolean useSandbox) { | ||
this.useSandbox = useSandbox; | ||
} | ||
|
||
/** | ||
* Get the current setting for whether or not to use a groovy sandbox. | ||
* | ||
* @return true if using a groovy sandbox is desired. | ||
*/ | ||
public boolean getUseSandbox() { | ||
return this.useSandbox; | ||
} | ||
|
||
@Override | ||
protected WorkflowMultiBranchProject doCreateProject(ItemGroup<?> parent, String name, Map<String,Object> attributes){ | ||
WorkflowMultiBranchProject project = new WorkflowMultiBranchProject(parent, name); | ||
configureProjectFactoryFor(project); | ||
return project; | ||
} | ||
|
||
@Override | ||
public void updateExistingProject(MultiBranchProject<?, ?> project, Map<String, Object> attributes, TaskListener listener) throws IOException, InterruptedException { | ||
if (project instanceof WorkflowMultiBranchProject) { | ||
configureProjectFactoryFor((WorkflowMultiBranchProject) project); | ||
} | ||
} | ||
|
||
@Override | ||
protected SCMSourceCriteria getSCMSourceCriteria(SCMSource source) { | ||
return new SCMSourceCriteria() { | ||
@Override | ||
public boolean isHead(Probe probe, TaskListener listener) throws IOException { | ||
return true; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return getClass().hashCode(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
return getClass().isInstance(obj); | ||
} | ||
}; | ||
} | ||
|
||
@Extension | ||
public static class PerFolderAdder extends TransientActionFactory<OrganizationFolder> { | ||
|
||
@Override | ||
public Class<OrganizationFolder> type() { | ||
return OrganizationFolder.class; | ||
} | ||
|
||
@Override | ||
public Collection<? extends Action> createFor(OrganizationFolder target) { | ||
if (target.getProjectFactories().get(PipelineMultiBranchDefaultsProjectFactory.class) != null && target.hasPermission(Item.EXTENDED_READ)) { | ||
return Collections.singleton(new Snippetizer.LocalAction()); | ||
} else { | ||
return Collections.emptySet(); | ||
} | ||
} | ||
} | ||
|
||
@Extension | ||
public static class DescriptorImpl extends MultiBranchProjectFactoryDescriptor { | ||
@Override | ||
public MultiBranchProjectFactory newInstance() { | ||
return null; | ||
} | ||
|
||
@Nonnull | ||
@Override | ||
public String getDisplayName() { | ||
return "by default " + SCRIPT; | ||
} | ||
} | ||
|
||
private void configureProjectFactoryFor(WorkflowMultiBranchProject project) { | ||
PipelineBranchDefaultsProjectFactory projectFactory = new PipelineBranchDefaultsProjectFactory(); | ||
projectFactory.setScriptId(scriptId); | ||
projectFactory.setUseSandbox(useSandbox); | ||
project.setProjectFactory(projectFactory); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
...gins/pipeline/multibranch/defaults/PipelineMultiBranchDefaultsProjectFactory/config.jelly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
The MIT License | ||
Copyright (c) 2016 Saponenko Denis | ||
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. | ||
--> | ||
|
||
<?jelly escape-by-default='true'?> | ||
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form"> | ||
<f:entry title="${%Script ID}" field="scriptId"> | ||
<f:textbox value="${instance.scriptId}" default="Jenkinsfile" /> | ||
</f:entry> | ||
<f:entry title="${%Run default Jenkinsfile within Groovy sandbox}" field="useSandbox"> | ||
<f:checkbox name="useSandbox" checked="${instance.useSandbox}" default="false" /> | ||
</f:entry> | ||
</j:jelly> |
39 changes: 39 additions & 0 deletions
39
...line/multibranch/defaults/PipelineMultiBranchDefaultsProjectFactory/getting-started.jelly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!-- | ||
~ The MIT License | ||
~ | ||
~ Copyright (c) 2016 Saponenko Denis | ||
~ | ||
~ 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. | ||
--> | ||
<?jelly escape-by-default='true'?> | ||
<st:compress xmlns:st="jelly:stapler"> | ||
Pipeline Branch projects support building branches within a repository with a file named | ||
<code>Jenkinsfile</code> | ||
in the Jenkins global files or scm module root directory. | ||
This file should contain a valid | ||
<a target="_blank" | ||
href="https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md#understanding-flow-scripts">Jenkins | ||
Pipeline script</a>. See also: | ||
<a target="_blank" | ||
href="https://github.com/jenkinsci/workflow-multibranch-plugin"> | ||
Workflow Multibranch Plugin</a>. | ||
<a target="_blank" | ||
href="https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md#creating-multibranch-projects"> | ||
Creating Multibranch Projects</a>. | ||
</st:compress> |
4 changes: 4 additions & 0 deletions
4
...ipeline/multibranch/defaults/PipelineMultiBranchDefaultsProjectFactory/help-scriptId.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div> | ||
The ID of the default <code>Jenkinsfile</code> to use from the global | ||
Config File Management. | ||
</div> |
6 changes: 6 additions & 0 deletions
6
...eline/multibranch/defaults/PipelineMultiBranchDefaultsProjectFactory/help-useSandbox.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<div> | ||
If enabled, the configured default <code>Jenkinsfile</code> will be run | ||
within a Groovy sandbox. This option is <b>strongly recommended</b> if the | ||
Jenkinsfile is using <a href="https://jenkins.io/doc/pipeline/steps/workflow-cps/"><code>load</code> | ||
to evaluate a groovy source file</a> from an SCM repository. | ||
</div> |
76 changes: 76 additions & 0 deletions
76
.../plugins/pipeline/multibranch/defaults/PipelineMultiBranchDefaultsProjectFactoryTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* The MIT License | ||
* | ||
* Copyright (c) 2016 Saponenko Denis | ||
* | ||
* 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.pipeline.multibranch.defaults; | ||
|
||
import hudson.model.Result; | ||
import hudson.util.DescribableList; | ||
import jenkins.branch.MultiBranchProjectFactory; | ||
import jenkins.branch.OrganizationFolder; | ||
import jenkins.scm.api.SCMNavigator; | ||
import jenkins.scm.api.SCMNavigatorDescriptor; | ||
import jenkins.scm.impl.mock.*; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.jvnet.hudson.test.JenkinsRule; | ||
|
||
import java.util.List; | ||
|
||
import static net.sf.ezmorph.test.ArrayAssertions.assertEquals; | ||
import static org.hamcrest.Matchers.is; | ||
import static org.hamcrest.core.IsNull.notNullValue; | ||
import static org.hamcrest.core.IsNull.nullValue; | ||
import static org.junit.Assert.assertThat; | ||
|
||
public class PipelineMultiBranchDefaultsProjectFactoryTest { | ||
@Rule | ||
public JenkinsRule r = new JenkinsRule(); | ||
|
||
@Test | ||
public void configureAndIndexChildren() throws Exception { | ||
try (MockSCMController c = MockSCMController.create()) { | ||
OrganizationFolder folder = r.jenkins.createProject(OrganizationFolder.class, "p"); | ||
List<MultiBranchProjectFactory> projectFactories = folder.getProjectFactories(); | ||
projectFactories.clear(); | ||
projectFactories.add(new PipelineMultiBranchDefaultsProjectFactory()); | ||
|
||
c.createRepository("sample"); | ||
MockSCMNavigator navigator = new MockSCMNavigator(c, new MockSCMDiscoverBranches(), new MockSCMDiscoverTags(), new MockSCMDiscoverChangeRequests()); | ||
|
||
DescribableList<SCMNavigator, SCMNavigatorDescriptor> navigators = folder.getNavigators(); | ||
navigators.add(navigator); | ||
|
||
assertThat("Folder has not been scanned", folder.getItem("sample"), nullValue()); | ||
|
||
folder.scheduleBuild(0); | ||
r.waitUntilNoActivity(); | ||
assertEquals(1, folder.getItems().size()); | ||
|
||
assertThat("Folder has been scanned", folder.getItem("sample"), notNullValue()); | ||
assertThat("We have run an index on the child item", | ||
folder.getItem("sample").getComputation().getResult(), is(Result.SUCCESS) | ||
); | ||
} | ||
} | ||
} |