Skip to content

Commit

Permalink
Rebased to latest remote, added branch checking
Browse files Browse the repository at this point in the history
  • Loading branch information
pbalint committed Jun 5, 2020
1 parent 72c01dd commit 91a48f2
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 26 deletions.
57 changes: 43 additions & 14 deletions src/main/java/com/cloudbees/jenkins/GitHubPushTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import hudson.model.Item;
import hudson.model.Job;
import hudson.model.Project;
import hudson.plugins.git.BranchSpec;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.extensions.impl.UserExclusion;
import hudson.scm.SCM;
import hudson.triggers.SCMTrigger;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
Expand Down Expand Up @@ -60,6 +60,7 @@
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.regex.Matcher;

import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.commons.lang3.Validate.notNull;
Expand Down Expand Up @@ -105,26 +106,30 @@ public void onPost(final GitHubTriggerEvent event) {
if (Objects.isNull(job)) {
return; // nothing to do
}
if (useGitExcludedUsers) {
Set<String> lowercaseExcludedUsers = new HashSet<>();
if (job instanceof AbstractProject) {
SCM scm = ((AbstractProject<?, ?>) job).getScm();
if (scm instanceof GitSCM) {
UserExclusion exclusions = ((GitSCM) scm).getExtensions().get(UserExclusion.class);
if ((((AbstractProject<?, ?>) job).getScm()) instanceof GitSCM) {
GitSCM scm = (GitSCM) (((AbstractProject<?, ?>) job).getScm());
if (!branchMatchesGitBranchToBeBuilt(scm, event.getRef())) {
return;
}

if (useGitExcludedUsers) {
Set<String> lowercaseExcludedUsers = new HashSet<>();
if (job instanceof AbstractProject) {
UserExclusion exclusions = scm.getExtensions().get(UserExclusion.class);
if (exclusions != null) {
for (String userName: exclusions.getExcludedUsersNormalized()) {
lowercaseExcludedUsers.add(userName.toLowerCase());
}
}
}
}

String lowercaseTriggeredByUser = null;
if (event.getTriggeredByUser() != null) {
lowercaseTriggeredByUser = event.getTriggeredByUser().toLowerCase();
}
if (lowercaseExcludedUsers != null && lowercaseExcludedUsers.contains(lowercaseTriggeredByUser)) {
return; // user is excluded from triggering build
String lowercaseTriggeredByUser = null;
if (event.getTriggeredByUser() != null) {
lowercaseTriggeredByUser = event.getTriggeredByUser().toLowerCase();
}
if (lowercaseExcludedUsers != null && lowercaseExcludedUsers.contains(lowercaseTriggeredByUser)) {
return; // user is excluded from triggering build
}
}
}

Expand Down Expand Up @@ -197,6 +202,30 @@ public void run() {
});
}

private boolean branchMatchesGitBranchToBeBuilt(GitSCM scm, String ref) {
List< BranchSpec > branches = scm.getBranches();
for (BranchSpec branch: branches) {
if (!branch.matches(ref)) {
// code block copied from GitSCM plugin's GitSCM.compareRemoteRevisionWithImpl()
// convert head `refs/(heads|tags|whatever)/branch` into shortcut notation `remote/branch`
String name;
Matcher matcher = GitSCM.GIT_REF.matcher(ref);
if (matcher.matches()) {
name = "origin" + ref.substring(matcher.group(1).length());
} else {
name = "origin" + "/" + ref;
}

if (!branch.matches(name)) {
continue;
}

return true;
}
}
return false;
}

/**
* Returns the file that records the last/current polling activity.
*/
Expand Down
23 changes: 21 additions & 2 deletions src/main/java/com/cloudbees/jenkins/GitHubTriggerEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ public class GitHubTriggerEvent {
*/
private final String triggeredByUser;

private GitHubTriggerEvent(long timestamp, String origin, String triggeredByUser) {
private final String ref;

private GitHubTriggerEvent(long timestamp, String origin, String triggeredByUser, String ref) {
this.timestamp = timestamp;
this.origin = origin;
this.triggeredByUser = triggeredByUser;
this.ref = ref;
}

public static Builder create() {
Expand All @@ -44,6 +47,10 @@ public String getTriggeredByUser() {
return triggeredByUser;
}

public String getRef() {
return ref;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand All @@ -61,6 +68,9 @@ public boolean equals(Object o) {
if (origin != null ? !origin.equals(that.origin) : that.origin != null) {
return false;
}
if (ref != null ? !ref.equals(that.ref) : that.ref != null) {
return false;
}
return triggeredByUser != null ? triggeredByUser.equals(that.triggeredByUser) : that.triggeredByUser == null;
}

Expand All @@ -69,6 +79,7 @@ public int hashCode() {
int result = (int) (timestamp ^ (timestamp >>> 32));
result = 31 * result + (origin != null ? origin.hashCode() : 0);
result = 31 * result + (triggeredByUser != null ? triggeredByUser.hashCode() : 0);
result = 31 * result + (ref != null ? ref.hashCode() : 0);
return result;
}

Expand All @@ -78,6 +89,7 @@ public String toString() {
+ "timestamp=" + timestamp
+ ", origin='" + origin + '\''
+ ", triggeredByUser='" + triggeredByUser + '\''
+ ", ref='" + ref + '\''
+ '}';
}

Expand All @@ -88,6 +100,7 @@ public static class Builder {
private long timestamp;
private String origin;
private String triggeredByUser;
private String ref;

private Builder() {
timestamp = System.currentTimeMillis();
Expand All @@ -108,8 +121,13 @@ public Builder withTriggeredByUser(String triggeredByUser) {
return this;
}

public Builder withRef(String ref) {
this.ref = ref;
return this;
}

public GitHubTriggerEvent build() {
return new GitHubTriggerEvent(timestamp, origin, triggeredByUser);
return new GitHubTriggerEvent(timestamp, origin, triggeredByUser, ref);
}

@Override
Expand All @@ -118,6 +136,7 @@ public String toString() {
+ "timestamp=" + timestamp
+ ", origin='" + origin + '\''
+ ", triggeredByUser='" + triggeredByUser + '\''
+ ", ref='" + ref + '\''
+ '}';
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public void run() {
.withTimestamp(event.getTimestamp())
.withOrigin(event.getOrigin())
.withTriggeredByUser(pusherName)
.withRef(push.getRef())
.build()
);
} else {
Expand Down
91 changes: 81 additions & 10 deletions src/test/java/com/cloudbees/jenkins/GitHubPushTriggerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;
Expand All @@ -26,9 +28,13 @@
import org.mockito.Mockito;

import com.cloudbees.jenkins.GitHubPushTrigger.DescriptorImpl;
import com.google.common.collect.Lists;

import hudson.model.FreeStyleProject;
import hudson.plugins.git.BranchSpec;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.SubmoduleConfig;
import hudson.plugins.git.extensions.GitSCMExtension;
import hudson.plugins.git.extensions.impl.UserExclusion;
import hudson.plugins.git.util.Build;
import hudson.plugins.git.util.BuildData;
Expand Down Expand Up @@ -118,6 +124,16 @@ private SequentialExecutionQueue addSpyToQueueField() {
return spiedQueue;
}

private GitSCM createGitSCM(String repository) {
return new GitSCM(GitSCM.createRepoList(repository, null),
Lists.newArrayList(new BranchSpec("*/master")),
false,
Collections.<SubmoduleConfig>emptyList(),
null,
null,
Collections.<GitSCMExtension>emptyList());
}

@Test
public void shouldSkipBuildIfExclusionEnabledWithMatchingUser() throws IOException {
SequentialExecutionQueue spiedQueue = addSpyToQueueField();
Expand All @@ -128,17 +144,18 @@ public void shouldSkipBuildIfExclusionEnabledWithMatchingUser() throws IOExcepti
trigger.setUseGitExcludedUsers(true);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
GitSCM scm = createGitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
matchingUserName + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser(matchingUserName)
.withRef("refs/heads/master")
.build();
trigger.onPost(event);

Expand All @@ -155,17 +172,18 @@ public void shouldSkipBuildIfExclusionEnabledWithMatchingUserCaseInsensitive() t
trigger.setUseGitExcludedUsers(true);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
GitSCM scm = createGitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
matchingUserName.toUpperCase() + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser(matchingUserName)
.withRef("refs/heads/master")
.build();
trigger.onPost(event);

Expand All @@ -181,17 +199,18 @@ public void shouldTriggerBuildIfExclusionEnabledWithNonMatchingUser() throws IOE
trigger.setUseGitExcludedUsers(true);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
GitSCM scm = createGitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
"nonMatchingUserName" + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser("userName")
.withRef("refs/heads/master")
.build();
trigger.onPost(event);

Expand All @@ -208,17 +227,18 @@ public void shouldTriggerBuildIfExclusionDisabledWithMatchingUser() throws IOExc
trigger.setUseGitExcludedUsers(false);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
GitSCM scm = createGitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
matchingUserName + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser(matchingUserName)
.withRef("refs/heads/master")
.build();
trigger.onPost(event);

Expand All @@ -234,20 +254,71 @@ public void shouldTriggerBuildIfExclusionDisabledWithNonMatchingUser() throws IO
trigger.setUseGitExcludedUsers(false);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
GitSCM scm = createGitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
"nonMatchingUserName" + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser("userName")
.withRef("refs/heads/master")
.build();
trigger.onPost(event);

verify(spiedQueue).execute(Mockito.any(Runnable.class));
}

@Test
public void shouldTriggerBuildIfBranchNameMatches() throws IOException {
SequentialExecutionQueue spiedQueue = addSpyToQueueField();

FreeStyleProject project = jRule.createFreeStyleProject();
GitHubPushTrigger trigger = new GitHubPushTrigger();
trigger.setUseGitExcludedUsers(true);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = createGitSCM("https://localhost/dummy.git");
List< BranchSpec > branches = scm.getBranches();
branches.clear();
branches.add(new BranchSpec("*/master"));
branches.add(new BranchSpec("*/develop"));
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser("userName")
.withRef("refs/heads/master")
.build();
trigger.onPost(event);

verify(spiedQueue).execute(Mockito.any(Runnable.class));
}

@Test
public void shouldSkipBuildIfBranchNameDoesntMatch() throws IOException {
SequentialExecutionQueue spiedQueue = addSpyToQueueField();

FreeStyleProject project = jRule.createFreeStyleProject();
GitHubPushTrigger trigger = new GitHubPushTrigger();
trigger.setUseGitExcludedUsers(true);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = createGitSCM("https://localhost/dummy.git");
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser("userName")
.withRef("refs/heads/featureBranch")
.build();
trigger.onPost(event);

verify(spiedQueue, times(0)).execute(Mockito.any(Runnable.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public void shouldParsePushPayload() throws Exception {
.withTimestamp(subscriberEvent.getTimestamp())
.withOrigin("shouldParsePushPayload")
.withTriggeredByUser(TRIGGERED_BY_USER_FROM_RESOURCE)
.withRef("refs/heads/master")
.build()
));
}
Expand All @@ -85,6 +86,7 @@ public void shouldReceivePushHookOnWorkflow() throws Exception {
.withTimestamp(subscriberEvent.getTimestamp())
.withOrigin("shouldReceivePushHookOnWorkflow")
.withTriggeredByUser(TRIGGERED_BY_USER_FROM_RESOURCE)
.withRef("refs/heads/master")
.build()
));
}
Expand Down

0 comments on commit 91a48f2

Please sign in to comment.