Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-43507] Check-pointing work in progress
  • Loading branch information
stephenc committed Jun 16, 2017
1 parent f695f9f commit e14433f
Show file tree
Hide file tree
Showing 25 changed files with 2,556 additions and 1,021 deletions.
6 changes: 3 additions & 3 deletions pom.xml
Expand Up @@ -8,7 +8,7 @@
<relativePath />
</parent>
<artifactId>github-branch-source</artifactId>
<version>2.2.0-20170411.160059-4</version>
<version>2.2.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<name>GitHub Branch Source Plugin</name>
<url>https://wiki.jenkins-ci.org/display/JENKINS/GitHub+Branch+Source+Plugin</url>
Expand All @@ -23,7 +23,7 @@
<properties>
<jenkins.version>1.625.3</jenkins.version>
<workflow.version>1.14.2</workflow.version>
<scm-api.version>2.2.0-20170411.160059-4</scm-api.version>
<scm-api.version>2.2.0-SNAPSHOT</scm-api.version>
</properties>

<scm>
Expand All @@ -41,7 +41,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git</artifactId>
<version>3.2.0</version>
<version>3.3.1-SNAPSHOT</version>
<exclusions>
<!-- To avoid ClassNotFoundException during InjectedTest -->
<exclusion>
Expand Down
@@ -0,0 +1,139 @@
package org.jenkinsci.plugins.github_branch_source;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.scm.SCM;
import hudson.util.ListBoxModel;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.SCMHead;
import jenkins.scm.api.SCMHeadCategory;
import jenkins.scm.api.trait.SCMHeadAuthority;
import jenkins.scm.api.trait.SCMHeadAuthorityDescriptor;
import jenkins.scm.api.trait.SCMHeadFilter;
import jenkins.scm.api.trait.SCMSourceContext;
import jenkins.scm.api.trait.SCMSourceRequest;
import jenkins.scm.api.trait.SCMSourceTrait;
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.stapler.DataBoundConstructor;

public class BranchDiscoveryTrait extends SCMSourceTrait {
private int strategyId;

@DataBoundConstructor
public BranchDiscoveryTrait(int strategyId) {
this.strategyId = strategyId;
}

public BranchDiscoveryTrait(boolean buildBranch, boolean buildBranchWithPr) {
this.strategyId = (buildBranch ? 1 : 0) + (buildBranchWithPr ? 2 : 0);
}

public int getStrategyId() {
return strategyId;
}

@Restricted(NoExternalUse.class)
public boolean isBuildBranch() {
return (strategyId & 1) != 0;

}

@Restricted(NoExternalUse.class)
public boolean isBuildBranchesWithPR() {
return (strategyId & 2) != 0;
}

@Override
protected <B extends SCMBuilder<B, S>, S extends SCM> void decorateBuilder(B builder) {
GitHubSCMSourceContext b = GitHubSCMSourceContext.class.cast(builder);
b.wantBranches(true);
b.withAuthority(new BranchSCMHeadAuthority());
switch (strategyId) {
case 1:
b.wantOriginPRs(true);
b.withFilter(new SCMHeadFilter() {
@Override
public boolean isExcluded(@NonNull SCMSourceRequest request, @NonNull SCMHead head) {
if (head instanceof BranchSCMHead && request instanceof GitHubSCMSourceRequest) {
for (GHPullRequest pullRequest: ((GitHubSCMSourceRequest) request).getPullRequests()) {
if (pullRequest.getHead().getRef().equals(head.getName())) {
// TODO correct is also a PR test
return true;
}
}
}
return false;
}
});
break;
case 2:
b.wantOriginPRs(true);
b.withFilter(new SCMHeadFilter() {
@Override
public boolean isExcluded(@NonNull SCMSourceRequest request, @NonNull SCMHead head) {
if (head instanceof BranchSCMHead && request instanceof GitHubSCMSourceRequest) {
for (GHPullRequest pullRequest : ((GitHubSCMSourceRequest) request).getPullRequests()) {
if (!pullRequest.getHead().getRef().equals(head.getName())) {
// TODO correct is also a PR test
return true;
}
}
}
return false;
}
});
break;
case 3:
default:
// we don't care if it is a PR or not, we're taking them all, no need to ask for PRs and no need
// to filter
break;

}
}

@Override
public boolean includeCategory(@NonNull SCMHeadCategory category) {
return category.isUncategorized();
}

@Extension
public static class DescriptorImpl extends SCMSourceTraitDescriptor {

@Override
public String getDisplayName() {
return "Discover branches";
}

@Override
public boolean isApplicableToContext(Class<? extends SCMSourceContext> contextClass) {
return GitHubSCMSourceRequest.class.isAssignableFrom(contextClass);
}

public ListBoxModel doFillStrategyIdItems() {
ListBoxModel result = new ListBoxModel();
result.add("Only branches that are not also filed as PRs", "1");
result.add("Only branches that are also filed as PRs", "2");
result.add("All branches", "3");
return result;
}
}

public static class BranchSCMHeadAuthority extends SCMHeadAuthority<SCMSourceRequest,BranchSCMHead> {
@Override
protected boolean checkTrusted(@NonNull SCMSourceRequest request, @NonNull BranchSCMHead head) {
return true;
}

@Extension
public static class DescriptorImpl extends SCMHeadAuthorityDescriptor {
@Override
public String getDisplayName() {
return null;
}
}
}
}
Expand Up @@ -373,7 +373,7 @@ private static CredentialsMatcher githubScanCredentialsMatcher() {
return CredentialsMatchers.anyOf(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class));
}

private static List<DomainRequirement> githubDomainRequirements(String apiUri) {
static List<DomainRequirement> githubDomainRequirements(String apiUri) {
return URIRequirementBuilder.fromUri(StringUtils.defaultIfEmpty(apiUri, "https://github.com")).build();
}

Expand Down
@@ -0,0 +1,174 @@
package org.jenkinsci.plugins.github_branch_source;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.scm.SCM;
import hudson.util.ListBoxModel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import jenkins.scm.api.SCMHeadCategory;
import jenkins.scm.api.SCMHeadOrigin;
import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy;
import jenkins.scm.api.mixin.ChangeRequestSCMHead2;
import jenkins.scm.api.trait.SCMBuilder;
import jenkins.scm.api.trait.SCMHeadAuthority;
import jenkins.scm.api.trait.SCMHeadAuthorityDescriptor;
import jenkins.scm.api.trait.SCMSourceContext;
import jenkins.scm.api.trait.SCMSourceRequest;
import jenkins.scm.api.trait.SCMSourceTrait;
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
import jenkins.scm.impl.ChangeRequestSCMHeadCategory;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;

public class ForkPullRequestDiscoveryTrait extends SCMSourceTrait {
private final int strategyId;
private final SCMHeadAuthority<? super GitHubSCMSourceRequest, ? extends ChangeRequestSCMHead2> trust;

@DataBoundConstructor
public ForkPullRequestDiscoveryTrait(int strategyId,
SCMHeadAuthority<? super GitHubSCMSourceRequest, ? extends
ChangeRequestSCMHead2> trust) {
this.strategyId = strategyId;
this.trust = trust;
}

public ForkPullRequestDiscoveryTrait(boolean buildMerge, boolean buildHead) {
this.strategyId = (buildMerge ? 1 : 0) + (buildHead ? 2 : 0);
this.trust = new TrustContributors();
}

public int getStrategyId() {
return strategyId;
}

@Restricted(NoExternalUse.class)
public boolean isPRMerge() {
return (strategyId & 1) != 0;
}

@Restricted(NoExternalUse.class)
public boolean isPRHead() {
return (strategyId & 1) != 0;
}

public SCMHeadAuthority<? super GitHubSCMSourceRequest, ? extends ChangeRequestSCMHead2> getTrust() {
return trust;
}

@Override
protected <B extends SCMBuilder<B, S>, S extends SCM> void decorateBuilder(B builder) {
GitHubSCMSourceContext b = GitHubSCMSourceContext.class.cast(builder);
b.wantForkPRs(true);
if ((strategyId & 1) != 0) {
b.withForkPRStrategies(Collections.singleton(ChangeRequestCheckoutStrategy.MERGE));
}
if ((strategyId & 2) != 0) {
b.withForkPRStrategies(Collections.singleton(ChangeRequestCheckoutStrategy.HEAD));
}
}

@Override
public boolean includeCategory(@NonNull SCMHeadCategory category) {
return category instanceof ChangeRequestSCMHeadCategory;
}

@Extension
public static class DescriptorImpl extends SCMSourceTraitDescriptor {

@Override
public String getDisplayName() {
return "Discover pull requests from forks";
}

@Override
public boolean isApplicableToContext(Class<? extends SCMSourceContext> contextClass) {
return GitHubSCMSourceRequest.class.isAssignableFrom(contextClass);
}

public ListBoxModel doFillStrategyIdItems() {
ListBoxModel result = new ListBoxModel();
result.add("Merging the pull request with the current target branch revision", "1");
result.add("The current pull request revision", "2");
result.add("Build the current pull request revision", "3");
return result;
}

public List<SCMHeadAuthorityDescriptor> getTrustDescriptors() {
List<SCMHeadAuthorityDescriptor> result = new ArrayList<>();
for (SCMHeadAuthorityDescriptor d : ExtensionList.lookup(SCMHeadAuthorityDescriptor.class)) {
if (d.isApplicableToRequest(GitHubSCMSourceRequest.class)
&& d.isApplicableToHead(PullRequestSCMHead.class)) {
result.add(d);
}
}
return result;
}
}


public static class TrustContributors extends SCMHeadAuthority<GitHubSCMSourceRequest, PullRequestSCMHead> {
@DataBoundConstructor
public TrustContributors() {
}


@Override
protected boolean checkTrusted(@NonNull GitHubSCMSourceRequest request, @NonNull PullRequestSCMHead head) {
return !head.getOrigin().equals(SCMHeadOrigin.DEFAULT)
&& request.getCollaboratorNames().contains(head.getSourceOwner());
}

@Extension
public static class DescriptorImpl extends SCMHeadAuthorityDescriptor {

@Override
public String getDisplayName() {
return "Contributors";
}
}
}

public static class TrustNobody extends SCMHeadAuthority<SCMSourceRequest, ChangeRequestSCMHead2> {
@DataBoundConstructor
public TrustNobody() {
}

@Override
public boolean checkTrusted(@NonNull SCMSourceRequest request, @NonNull ChangeRequestSCMHead2 head) {
return false;
}

@Extension
public static class DescriptorImpl extends SCMHeadAuthorityDescriptor {

@Override
public String getDisplayName() {
return "Nobody";
}
}
}

public static class TrustEveryone extends SCMHeadAuthority<SCMSourceRequest, ChangeRequestSCMHead2> {
@DataBoundConstructor
public TrustEveryone() {
}

@Override
protected boolean checkTrusted(@NonNull SCMSourceRequest request, @NonNull ChangeRequestSCMHead2 head) {
return !head.getOrigin().equals(SCMHeadOrigin.DEFAULT);
}

@Extension
public static class DescriptorImpl extends SCMHeadAuthorityDescriptor {

@Override
public String getDisplayName() {
return "Everyone";
}
}
}
}

0 comments on commit e14433f

Please sign in to comment.