Skip to content

Commit

Permalink
Merge pull request #416 from cwholmes/filter-drafts-trait
Browse files Browse the repository at this point in the history
Add trait for filtering draft PRs
  • Loading branch information
bitwiseman authored Jul 23, 2021
2 parents 1b5b7e7 + a032897 commit 4acf9fa
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.jenkinsci.plugins.github_branch_source;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import java.io.IOException;
import jenkins.scm.api.SCMHead;
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 jenkins.scm.impl.trait.Selection;
import org.jenkinsci.Symbol;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.stapler.DataBoundConstructor;

/** Trait used to filter any pull requests current set as a draft from building. */
public class IgnoreDraftPullRequestFilterTrait extends SCMSourceTrait {

@DataBoundConstructor
public IgnoreDraftPullRequestFilterTrait() {}

protected void decorateContext(SCMSourceContext<?, ?> context) {
context.withFilter(
new SCMHeadFilter() {
@Override
public boolean isExcluded(
@NonNull final SCMSourceRequest request, @NonNull final SCMHead head)
throws IOException {
if (!(request instanceof GitHubSCMSourceRequest)
|| !(head instanceof PullRequestSCMHead)) {
return false;
}
GitHubSCMSourceRequest githubRequest = (GitHubSCMSourceRequest) request;
PullRequestSCMHead prHead = (PullRequestSCMHead) head;
for (GHPullRequest pullRequest : githubRequest.getPullRequests()) {
if (pullRequest.getNumber() != prHead.getNumber()) {
continue;
}
if (pullRequest.isDraft()) {
request
.listener()
.getLogger()
.format(
"%n Won't Build PR %s. Marked as a draft.%n", "#" + prHead.getNumber());
return true;
}
return false;
}
return false;
}
});
}

@Symbol({"gitHubIgnoreDraftPullRequestFilter"})
@Extension
@Selection
public static class DescriptorImpl extends SCMSourceTraitDescriptor {
public DescriptorImpl() {}

public String getDisplayName() {
return Messages.IgnoreDraftPullRequestFilterTrait_DisplayName();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@ GitHubSCMNavigator.general=General
GitHubSCMNavigator.withinRepository=Within repository

GitHubAppCredentials.displayName=GitHub App

IgnoreDraftPullRequestFilterTrait.DisplayName=Ignore pull requests marked as drafts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.jenkinsci.plugins.github_branch_source;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import jenkins.scm.api.SCMHead;
import jenkins.scm.api.SCMHeadObserver;
import jenkins.scm.api.SCMHeadOrigin;
import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy;
import jenkins.scm.api.trait.SCMHeadFilter;
import org.junit.Test;
import org.kohsuke.github.GHPullRequest;
import org.mockito.Mockito;

public class IgnoreDraftPullRequestFilterTraitTest extends GitSCMSourceBase {

public IgnoreDraftPullRequestFilterTraitTest() {
this.source = new GitHubSCMSource("cloudbeers", "yolo", null, false);
}

@Test
public void testTraitFiltersDraft() throws IOException, InterruptedException {
GitHubSCMSourceContext probe = new GitHubSCMSourceContext(null, SCMHeadObserver.collect());
IgnoreDraftPullRequestFilterTrait instance = new IgnoreDraftPullRequestFilterTrait();
instance.decorateContext(probe);
List<SCMHeadFilter> filters = probe.filters();
assertThat(filters, hasSize(1));
SCMHeadFilter filter = filters.get(0);
SCMHead scmHead =
new PullRequestSCMHead(
"PR-5",
"cloudbeers",
"http://localhost:" + githubApi.port(),
"feature/5",
5,
new BranchSCMHead("master"),
SCMHeadOrigin.DEFAULT,
ChangeRequestCheckoutStrategy.MERGE);
GitHubSCMSourceRequest request = new GitHubSCMSourceRequest(source, probe, null);
// Situation: Hitting the Github API for a PR and getting a PR that is a draft
GHPullRequest pullRequest = Mockito.mock(GHPullRequest.class);
Mockito.when(pullRequest.getNumber()).thenReturn(5);
Mockito.when(pullRequest.isDraft()).thenReturn(true);
request.setPullRequests(Collections.singleton(pullRequest));
assertThat(filter.isExcluded(request, scmHead), equalTo(true));
}

@Test
public void testTraitDoesNotFilterNonDraft() throws IOException, InterruptedException {
GitHubSCMSourceContext probe = new GitHubSCMSourceContext(null, SCMHeadObserver.collect());
IgnoreDraftPullRequestFilterTrait instance = new IgnoreDraftPullRequestFilterTrait();
instance.decorateContext(probe);
List<SCMHeadFilter> filters = probe.filters();
assertThat(filters, hasSize(1));
SCMHeadFilter filter = filters.get(0);
SCMHead scmHead =
new PullRequestSCMHead(
"PR-5",
"cloudbeers",
"http://localhost:" + githubApi.port(),
"feature/5",
5,
new BranchSCMHead("master"),
SCMHeadOrigin.DEFAULT,
ChangeRequestCheckoutStrategy.MERGE);
GitHubSCMSourceRequest request = new GitHubSCMSourceRequest(source, probe, null);
// Situation: Hitting the Github API for a PR and getting a PR that is not a draft
GHPullRequest pullRequest = Mockito.mock(GHPullRequest.class);
Mockito.when(pullRequest.getNumber()).thenReturn(5);
Mockito.when(pullRequest.isDraft()).thenReturn(false);
request.setPullRequests(Collections.singleton(pullRequest));
assertThat(filter.isExcluded(request, scmHead), equalTo(false));
}
}

0 comments on commit 4acf9fa

Please sign in to comment.