Skip to content

Commit

Permalink
Merge pull request #160 from nfalco79/feature/JENKINS-48837
Browse files Browse the repository at this point in the history
[JENKINS-48837] Add BranchProperty support to OrganizationFolder
  • Loading branch information
bitwiseman authored Aug 11, 2020
2 parents 3662a43 + 4dc28f4 commit 6df2124
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 6 deletions.
72 changes: 67 additions & 5 deletions src/main/java/jenkins/branch/OrganizationFolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@
import jenkins.scm.api.metadata.ObjectMetadataAction;
import jenkins.scm.impl.SingleSCMNavigator;
import jenkins.scm.impl.UncategorizedSCMSourceCategory;
import net.sf.json.JSONObject;

import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.apache.commons.io.Charsets;
Expand Down Expand Up @@ -142,6 +144,13 @@ public final class OrganizationFolder extends ComputedFolder<MultiBranchProject<
*/
private DescribableList<BranchBuildStrategy, BranchBuildStrategyDescriptor> buildStrategies = new DescribableList<>(this);

/**
* The branches properties.
*
* @since 2.5.9
*/
private BranchPropertyStrategy strategy;

/**
* The persisted state maintained outside of the config file.
*
Expand All @@ -163,6 +172,13 @@ public final class OrganizationFolder extends ComputedFolder<MultiBranchProject<
*/
private transient String facDigest;

/**
* The {@link #propertyStrategy} digest used to detect if we need to trigger a rescan on save.
*
* @since 2.5.9
*/
private transient String propsDigest;

/**
* The {@link #buildStrategies} digest used to detect if we need to trigger a rescan on save.
*
Expand Down Expand Up @@ -266,6 +282,11 @@ public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOExcep
} catch (XStreamException e) {
facDigest = null;
}
try {
propsDigest = Util.getDigestOf(Items.XSTREAM2.toXML(strategy));
} catch (XStreamException e) {
propsDigest = null;
}
try {
bbsDigest = Util.getDigestOf(Items.XSTREAM2.toXML(buildStrategies));
} catch (XStreamException e) {
Expand Down Expand Up @@ -334,6 +355,26 @@ public DescribableList<MultiBranchProjectFactory,MultiBranchProjectFactoryDescri
return projectFactories;
}

/**
* Gets the strategy.
*
* @return the strategy.
* @since 2.5.9
*/
public BranchPropertyStrategy getStrategy() {
return strategy != null ? strategy : new DefaultBranchPropertyStrategy(new BranchProperty[0]);
}

/**
* Sets the branch property strategy.
*
* @param strategy chosen.
* @since 2.5.9
*/
public void setStrategy(BranchPropertyStrategy strategy) {
this.strategy = strategy;
}

/**
* The {@link BranchBuildStrategy}s to apply.
*
Expand All @@ -350,9 +391,13 @@ public DescribableList<BranchBuildStrategy, BranchBuildStrategyDescriptor> getBu
@Override
protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException {
super.submit(req, rsp);
navigators.rebuildHetero(req, req.getSubmittedForm(), ExtensionList.lookup(SCMNavigatorDescriptor.class), "navigators");
projectFactories.rebuildHetero(req, req.getSubmittedForm(), ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class), "projectFactories");
buildStrategies.rebuildHetero(req, req.getSubmittedForm(), ExtensionList.lookup(BranchBuildStrategyDescriptor.class), "buildStrategies");

JSONObject json = req.getSubmittedForm();
navigators.rebuildHetero(req, json, ExtensionList.lookup(SCMNavigatorDescriptor.class), "navigators");
projectFactories.rebuildHetero(req, json, ExtensionList.lookup(MultiBranchProjectFactoryDescriptor.class), "projectFactories");
buildStrategies.rebuildHetero(req, json, ExtensionList.lookup(BranchBuildStrategyDescriptor.class), "buildStrategies");
strategy = req.bindJSON(BranchPropertyStrategy.class, json.getJSONObject("strategy"));

for (SCMNavigator n : navigators) {
n.afterSave(this);
}
Expand All @@ -368,6 +413,12 @@ protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOExceptio
} catch (XStreamException e) {
facDigest = null;
}
String propsDigest;
try {
propsDigest = Util.getDigestOf(Items.XSTREAM2.toXML(strategy));
} catch (XStreamException e) {
propsDigest = null;
}
String bbsDigest;
try {
bbsDigest = Util.getDigestOf(Items.XSTREAM2.toXML(buildStrategies));
Expand All @@ -376,9 +427,11 @@ protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOExceptio
}
recalculateAfterSubmitted(!StringUtils.equals(navDigest, this.navDigest));
recalculateAfterSubmitted(!StringUtils.equals(facDigest, this.facDigest));
recalculateAfterSubmitted(!StringUtils.equals(propsDigest, this.propsDigest));
recalculateAfterSubmitted(!StringUtils.equals(bbsDigest, this.bbsDigest));
this.navDigest = navDigest;
this.facDigest = facDigest;
this.propsDigest = propsDigest;
this.bbsDigest = bbsDigest;
}

Expand Down Expand Up @@ -730,6 +783,16 @@ public String getCategoryId() {
return "nested-projects";
}

/**
* Gets all the {@link BranchPropertyStrategyDescriptor} instances applicable to the specified project and source.
*
* @return all the {@link BranchPropertyStrategyDescriptor} instances applicable to the specified project and
* source.
*/
public List<BranchPropertyStrategyDescriptor> propertyStrategyDescriptors() {
return BranchPropertyStrategyDescriptor.all();
}

/**
* A description of this {@link OrganizationFolder}.
*
Expand Down Expand Up @@ -1388,10 +1451,9 @@ private List<BranchSource> createBranchSources() {
for (SCMSource source : sources) {
BranchSource branchSource = new BranchSource(source);
branchSource.setBuildStrategies(buildStrategies);
// TODO do we want/need a more general BranchPropertyStrategyFactory?
branchSource.setStrategy(strategy);
branchSources.add(branchSource);
}
sources = null; // make sure complete gets called just once
return branchSources;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
~ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler">
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler" xmlns:branch="/lib/branch-api">
<f:section title="${%Projects}">
<j:choose>
<j:when test="${instance.singleOrigin}">
Expand All @@ -48,6 +48,12 @@
<f:entry field="projectFactories" title="${%Project Recognizers}">
<f:repeatableHeteroProperty field="projectFactories" hasHeader="true" />
</f:entry>
<j:set var="descriptors" value="${descriptor.propertyStrategyDescriptors()}"/>
<j:if test="${!descriptors.isEmpty()}">
<f:block>
<branch:dropdownDescriptorSelector field="strategy" title="Property strategy" descriptors="${descriptors}"/>
</f:block>
</j:if>
<j:set var="descriptors" value="${descriptor.getPropertyType(instance,'buildStrategies').applicableItemDescriptors}"/>
<j:if test="${!descriptors.isEmpty()}">
<f:entry title="${%Build strategies}" help="${descriptor.getHelpFile('buildStrategies')}">
Expand Down
60 changes: 60 additions & 0 deletions src/test/java/jenkins/branch/OrganizationFolderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@
import hudson.ExtensionList;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.ParameterDefinition;
import hudson.model.Result;
import hudson.model.StringParameterDefinition;
import hudson.model.TaskListener;
import hudson.model.View;
import hudson.scm.NullSCM;
import hudson.security.Permission;
import integration.harness.BasicMultiBranchProject;
import integration.harness.BasicMultiBranchProjectFactory;
import java.io.IOException;
import java.util.Arrays;
Expand Down Expand Up @@ -75,6 +78,22 @@

public class OrganizationFolderTest {

public static class OrganizationFolderBranchProperty extends ParameterDefinitionBranchProperty {

@DataBoundConstructor
public OrganizationFolderBranchProperty() {
super();
}

@TestExtension
public static class DescriptorImpl extends BranchPropertyDescriptor {
@Override
protected boolean isApplicable(MultiBranchProjectDescriptor projectDescriptor) {
return projectDescriptor instanceof BasicMultiBranchProject.DescriptorImpl;
}
}
}

@Rule
public JenkinsRule r = new JenkinsRule();

Expand Down Expand Up @@ -103,6 +122,47 @@ public void configRoundTrip() throws Exception {
}
}

@Issue("JENKINS-48837")
@Test
public void verifyBranchPropertiesAppliedOnNewProjects() throws Exception {
try (MockSCMController c = MockSCMController.create()) {
c.createRepository("stuff");
OrganizationFolder top = r.jenkins.createProject(OrganizationFolder.class, "top");
List<MultiBranchProjectFactory> projectFactories = top.getProjectFactories();
assertEquals(1, projectFactories.size());
assertEquals(MockFactory.class, projectFactories.get(0).getClass());
top.getNavigators().add(new SingleSCMNavigator("stuff",
Collections.<SCMSource>singletonList(new SingleSCMSource("stuffy",
new MockSCM(c, "stuff", new MockSCMHead("master"), null))))
);
OrganizationFolderBranchProperty instance = new OrganizationFolderBranchProperty();
instance.setParameterDefinitions(Collections.<ParameterDefinition>singletonList(
new StringParameterDefinition("PARAM_STR", "PARAM_DEFAULT_0812673", "The param")
));
top.setStrategy(new DefaultBranchPropertyStrategy(new BranchProperty[] { instance }));
top = r.configRoundtrip(top);

top.scheduleBuild(0);
r.waitUntilNoActivity();

// get the child project produced by the factory after scan
MultiBranchImpl prj = (MultiBranchImpl) top.getItem("stuff");
// verify new multibranch project have branch properties inherited from folder
assertThat(prj.getSources().get(0).getStrategy(), instanceOf(DefaultBranchPropertyStrategy.class));
DefaultBranchPropertyStrategy strategy = (DefaultBranchPropertyStrategy) prj.getSources().get(0).getStrategy();
assertThat(strategy.getProps().get(0), instanceOf(OrganizationFolderBranchProperty.class));
OrganizationFolderBranchProperty property = (OrganizationFolderBranchProperty) strategy.getProps().get(0);
assertThat(property.getParameterDefinitions(), contains(
allOf(
instanceOf(StringParameterDefinition.class),
hasProperty("name", is("PARAM_STR")),
hasProperty("defaultValue", is("PARAM_DEFAULT_0812673")),
hasProperty("description", is("The param"))
)
));
}
}

@Test
@Issue("JENKINS-31516")
public void indexChildrenOnOrganizationFolderIndex() throws Exception {
Expand Down

0 comments on commit 6df2124

Please sign in to comment.