Skip to content

Commit

Permalink
Use MultiBranchProject from Branch API Plugin to manage sub-projects.
Browse files Browse the repository at this point in the history
Bump core dependency version to 1.625.1 to match Branch API Plugin and
refactor TemplateDrivenMultiBranchProject significantly to use new APIs.

Remove "Allow anonymous trigger of branch sync" setting

Remove "Suppress automatic build trigger after discovering new branches"
setting

Add migration for SCMSource and build discarder.
  • Loading branch information
mjdetullio committed Jun 30, 2016
1 parent 98a9910 commit 798be16
Show file tree
Hide file tree
Showing 37 changed files with 812 additions and 888 deletions.
30 changes: 0 additions & 30 deletions README.md
Expand Up @@ -47,33 +47,3 @@ Thanks to Jesse Glick for stablizing a good chunk of boilerplate code from the
Branch API Plugin and then abstracting it into the
[Folders Plugin](https://github.com/jenkinsci/cloudbees-folder-plugin).

### Why not use the Branch API Plugin?

This project was first started from scratch. After discovering the Branch API,
the implementation was changed to utilize the API. However, there were some
issues with API that caused the switch back to an independent plugin:

* The vision for this plugin is one consolidated configuration for all branches
combined with support for the same build wrappers, builders, publishers, etc.
that you would see in the "stock" Jenkins project types. There does not seem
to be a clear way to do this with the API. This plugin uses an internal
template project, whose XML is applied directly to the branch projects, making
it possible to use all the same wrappers, builders, and publishers (including
configuration from community plugins).
* The API was still experimental at the time. Since then, it had a 1.0 release
and the parts that were abstracted to the Folders Plugin are now used by this
plugin.
* This plugin favors simplicity in configuration over the complexity seen in the
API. Admittedly, the API offers a lot of flexibility and nice-to-haves when
it comes to configuring the project's SCM, but it seems like overkill.

Now that the Branch API Plugin is stable, there is a likelihood that this
plugin will be deprecated or adopt the API. Here's what's holding that up:

* Writing the migration path will be a huge PITA or impossible.
* A separate
[Freestyle Multibranch Plugin](https://github.com/jenkinsci/freestyle-multibranch-plugin)
was started, but there isn't yet feature parity with this plugin (in both
directions).
* There is not an equivalent for Maven Projects that uses the API yet. The
implementation should ideally belong to the Maven Plugin.
20 changes: 7 additions & 13 deletions pom.xml
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.mjdetullio.jenkins.plugins</groupId>
<artifactId>multi-branch-project-plugin</artifactId>
<version>0.4.3-SNAPSHOT</version>
<version>0.5-SNAPSHOT</version>
<packaging>hpi</packaging>

<parent>
Expand Down Expand Up @@ -52,8 +52,7 @@
</prerequisites>

<properties>
<jenkins.version>1.609.1</jenkins.version>
<java.level>6</java.level>
<jenkins.version>1.625.1</jenkins.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
Expand All @@ -75,21 +74,16 @@
</pluginRepositories>

<dependencies>
<!-- Use newer cloudbees-folder than defined in branch-api to fix some bugs -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>scm-api</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
</exclusions>
<artifactId>cloudbees-folder</artifactId>
<version>5.7</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>cloudbees-folder</artifactId>
<version>5.7</version>
<artifactId>branch-api</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
Expand Down
Expand Up @@ -39,6 +39,7 @@
*
* @author Matthew DeTullio
*/
@SuppressWarnings("unused")
public final class BallColorFolderIcon extends FolderIcon {
private static final String UNUSED = "unused";

Expand Down
@@ -0,0 +1,86 @@
/*
* The MIT License
*
* Copyright (c) 2016, Matthew DeTullio
*
* 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 com.github.mjdetullio.jenkins.plugins.multibranch;

import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.JobProperty;
import hudson.model.JobPropertyDescriptor;
import hudson.model.TopLevelItem;
import jenkins.branch.Branch;

import javax.annotation.Nonnull;

/**
* A basic {@link JobProperty} that holds a {@link Branch} so that {@link TemplateDrivenMultiBranchProject}s can
* manage the project holding this property.
*
* @author Matthew DeTullio
*/
public class BranchProjectProperty<P extends AbstractProject<P, B> & TopLevelItem, B extends AbstractBuild<P, B>>
extends JobProperty<P> {

private Branch branch;

/**
* Creates a new property with the Branch it will hold.
*
* @param branch the branch
*/
public BranchProjectProperty(@Nonnull Branch branch) {
this.branch = branch;
}

/**
* Gets the Branch held by the property.
*
* @return the branch
*/
@Nonnull
public Branch getBranch() {
return branch;
}

/**
* Sets the Branch held by the property.
*
* @param branch the branch
*/
public void setBranch(@Nonnull Branch branch) {
this.branch = branch;
}

/**
* {@link BranchProjectProperty}'s descriptor.
*/
@SuppressWarnings("unused")
@Extension
public static class DescriptorImpl extends JobPropertyDescriptor {
@Override
public String getDisplayName() {
return "Branch";
}
}
}
@@ -0,0 +1,84 @@
/*
* The MIT License
*
* Copyright (c) 2014-2015, Matthew DeTullio
*
* 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 com.github.mjdetullio.jenkins.plugins.multibranch;

import hudson.Extension;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Item;
import jenkins.branch.Branch;
import jenkins.branch.BranchProjectFactoryDescriptor;
import jenkins.branch.MultiBranchProject;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* @author Matthew DeTullio
*/
public final class FreeStyleBranchProjectFactory
extends TemplateDrivenBranchProjectFactory<FreeStyleProject, FreeStyleBuild> {

/**
* No-op constructor used for data binding.
*/
@DataBoundConstructor
public FreeStyleBranchProjectFactory() {
// No-op
}

/**
* {@inheritDoc}
*/
@Override
public FreeStyleProject newInstance(Branch branch) {
FreeStyleProject project = new FreeStyleProject(getOwner(), branch.getEncodedName());
setBranch(project, branch);
return project;
}

/**
* {@inheritDoc}
*/
@Override
public boolean isProject(Item item) {
return item instanceof FreeStyleProject &&
((FreeStyleProject) item).getProperty(BranchProjectProperty.class) != null;
}

/**
* {@link TemplateDrivenBranchProjectFactory}'s descriptor.
*/
@SuppressWarnings("unused")
@Extension
public static class DescriptorImpl extends BranchProjectFactoryDescriptor {
@Override
public String getDisplayName() {
return "Fixed configuration";
}

@Override
public boolean isApplicable(Class<? extends MultiBranchProject> clazz) {
return FreeStyleMultiBranchProject.class.isAssignableFrom(clazz);
}
}
}
Expand Up @@ -23,7 +23,6 @@
*/
package com.github.mjdetullio.jenkins.plugins.multibranch;

import com.cloudbees.hudson.plugins.folder.AbstractFolderDescriptor;
import hudson.Extension;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
Expand All @@ -32,20 +31,20 @@
import hudson.model.ItemGroup;
import hudson.model.Items;
import hudson.model.TopLevelItem;
import jenkins.branch.BranchProjectFactory;
import jenkins.branch.MultiBranchProjectDescriptor;
import jenkins.model.Jenkins;

import javax.annotation.Nonnull;

/**
* @author Matthew DeTullio
*/
@SuppressWarnings("unused")
public final class FreeStyleMultiBranchProject
extends TemplateDrivenMultiBranchProject<FreeStyleProject, FreeStyleBuild> {

private static final String UNUSED = "unused";

/**
* Constructor that specifies the {@link ItemGroup} for this project and the
* project name.
* Constructor that specifies the {@link ItemGroup} for this project and the project name.
*
* @param parent the project's parent {@link ItemGroup}
* @param name the project's name
Expand All @@ -54,31 +53,37 @@ public FreeStyleMultiBranchProject(ItemGroup parent, String name) {
super(parent, name);
}

/**
* {@inheritDoc}
*/
@Override
protected FreeStyleProject createNewSubProject(TemplateDrivenMultiBranchProject parent, String branchName) {
return new FreeStyleProject(parent, branchName);
protected FreeStyleProject newTemplate() {
return new FreeStyleProject(this, TemplateDrivenMultiBranchProject.TEMPLATE);
}

/**
* {@inheritDoc}
*/
@Nonnull
@Override
public AbstractFolderDescriptor getDescriptor() {
return (DescriptorImpl) Jenkins.getActiveInstance().getDescriptorOrDie(FreeStyleMultiBranchProject.class);
protected BranchProjectFactory<FreeStyleProject, FreeStyleBuild> newProjectFactory() {
return new FreeStyleBranchProjectFactory();
}

/**
* {@inheritDoc}
*/
protected Class<FreeStyleBuild> getBuildClass() {
return FreeStyleBuild.class;
@Nonnull
@Override
public MultiBranchProjectDescriptor getDescriptor() {
return (DescriptorImpl) Jenkins.getActiveInstance().getDescriptorOrDie(FreeStyleMultiBranchProject.class);
}

/**
* Our project's descriptor.
* {@link FreeStyleMultiBranchProject}'s descriptor.
*/
@Extension
public static class DescriptorImpl extends AbstractFolderDescriptor {
public static class DescriptorImpl extends MultiBranchProjectDescriptor {
/**
* {@inheritDoc}
*/
Expand All @@ -100,7 +105,7 @@ public TopLevelItem newInstance(ItemGroup parent, String name) {
* Gives this class an alias for configuration XML.
*/
@Initializer(before = InitMilestone.PLUGINS_STARTED)
@SuppressWarnings(UNUSED)
@SuppressWarnings("unused")
public static void registerXStream() {
Items.XSTREAM.alias("freestyle-multi-branch-project", FreeStyleMultiBranchProject.class);
}
Expand Down

0 comments on commit 798be16

Please sign in to comment.