Skip to content

Commit

Permalink
Added option to reuse GitSCM's excluded users list
Browse files Browse the repository at this point in the history
  • Loading branch information
Pámer Bálint committed Nov 16, 2019
1 parent 7549b07 commit 0d54b11
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 13 deletions.
31 changes: 31 additions & 0 deletions src/main/java/com/cloudbees/jenkins/GitHubPushTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import hudson.model.Item;
import hudson.model.Job;
import hudson.model.Project;
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 All @@ -23,6 +26,7 @@
import jenkins.scm.api.SCMEvent;
import jenkins.triggers.SCMTriggerItem;
import jenkins.triggers.SCMTriggerItem.SCMTriggerItems;

import org.apache.commons.jelly.XMLOutput;
import org.jenkinsci.plugins.github.GitHubPlugin;
import org.jenkinsci.plugins.github.admin.GitHubHookRegisterProblemMonitor;
Expand All @@ -34,6 +38,7 @@
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.Stapler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -65,6 +70,7 @@
* @author Kohsuke Kawaguchi
*/
public class GitHubPushTrigger extends Trigger<Job<?, ?>> implements GitHubTrigger {
private boolean useGitExcludedUsers;

@DataBoundConstructor
public GitHubPushTrigger() {
Expand Down Expand Up @@ -98,6 +104,22 @@ public void onPost(final GitHubTriggerEvent event) {
if (Objects.isNull(job)) {
return; // nothing to do
}
if (useGitExcludedUsers) {
Set<String> excludedUsers = null;
if (job instanceof AbstractProject) {
SCM scm = ((AbstractProject<?, ?>) job).getScm();
if (scm instanceof GitSCM) {
UserExclusion exclusions = ((GitSCM) scm).getExtensions().get(UserExclusion.class);
if (exclusions != null) {
excludedUsers = exclusions.getExcludedUsersNormalized();
}
}
}

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

Job<?, ?> currentJob = notNull(job, "Job can't be null");

Expand Down Expand Up @@ -241,6 +263,15 @@ public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}

public boolean isUseGitExcludedUsers() {
return useGitExcludedUsers;
}

@DataBoundSetter
public void setUseGitExcludedUsers(Boolean useGitExcludedUsers) {
this.useGitExcludedUsers = useGitExcludedUsers != null ? useGitExcludedUsers : false;
}

/**
* Action object for {@link Project}. Used to display the polling log.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.cloudbees.jenkins.GitHubPushTrigger

import com.cloudbees.jenkins.GitHubPushTrigger

def f = namespace(lib.FormTagLib);

tr {
td(colspan: 4) {
div(id: 'gh-hooks-warn')
Expand All @@ -18,3 +20,7 @@ InlineWarning.setup({
}).start();
""")
}

f.entry() {
f.checkbox(title: _("Use Git excluded user list (\"Polling ignores commits from certain users\")"), field: "useGitExcludedUsers")
}
153 changes: 140 additions & 13 deletions src/test/java/com/cloudbees/jenkins/GitHubPushTriggerTest.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package com.cloudbees.jenkins;

import hudson.model.FreeStyleProject;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.util.Build;
import hudson.plugins.git.util.BuildData;
import hudson.util.FormValidation;
import static com.cloudbees.jenkins.GitHubWebHookFullTest.classpath;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventListenerTest.TRIGGERED_BY_USER_FROM_RESOURCE;

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

import javax.inject.Inject;

import org.eclipse.jgit.lib.ObjectId;
import org.jenkinsci.plugins.github.admin.GitHubHookRegisterProblemMonitor;
import org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventListenerTest;
Expand All @@ -16,16 +23,21 @@
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.mockito.Mockito;

import javax.inject.Inject;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import com.cloudbees.jenkins.GitHubPushTrigger.DescriptorImpl;

import static com.cloudbees.jenkins.GitHubWebHookFullTest.classpath;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventListenerTest.TRIGGERED_BY_USER_FROM_RESOURCE;
import hudson.model.FreeStyleProject;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.extensions.impl.UserExclusion;
import hudson.plugins.git.util.Build;
import hudson.plugins.git.util.BuildData;
import hudson.util.FormValidation;
import hudson.util.ReflectionUtils;
import hudson.util.SequentialExecutionQueue;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;

/**
* @author lanwen (Merkushev Kirill)
Expand Down Expand Up @@ -96,4 +108,119 @@ public void shouldReturnOkOnNoAnyProblem() throws Exception {
FormValidation validation = descriptor.doCheckHookRegistered(job);
assertThat("all ok", validation.kind, is(FormValidation.Kind.OK));
}

private SequentialExecutionQueue addSpyToQueueField() {
Field queueField = ReflectionUtils.findField(DescriptorImpl.class, "queue");
ReflectionUtils.makeAccessible(queueField);
SequentialExecutionQueue queue = (SequentialExecutionQueue)ReflectionUtils.getField(queueField, descriptor);
SequentialExecutionQueue spiedQueue = Mockito.spy(queue);
ReflectionUtils.setField(queueField, descriptor, spiedQueue);
return spiedQueue;
}

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

String matchingUserName = "userName";
FreeStyleProject project = jRule.createFreeStyleProject();
GitHubPushTrigger trigger = new GitHubPushTrigger();
trigger.setUseGitExcludedUsers(true);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
matchingUserName + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser(matchingUserName)
.build();
trigger.onPost(event);

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

@Test
public void shouldTriggerBuildIfExclusionEnabledWithNonMatchingUser() 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 = new GitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
"nonMatchingUserName" + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser("userName")
.build();
trigger.onPost(event);

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

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

String matchingUserName = "userName";
FreeStyleProject project = jRule.createFreeStyleProject();
GitHubPushTrigger trigger = new GitHubPushTrigger();
trigger.setUseGitExcludedUsers(false);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
matchingUserName + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser(matchingUserName)
.build();
trigger.onPost(event);

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

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

FreeStyleProject project = jRule.createFreeStyleProject();
GitHubPushTrigger trigger = new GitHubPushTrigger();
trigger.setUseGitExcludedUsers(false);
trigger.start(project, false);
project.addTrigger(trigger);
GitSCM scm = new GitSCM("https://localhost/dummy.git");
UserExclusion userExclusion = new UserExclusion("something" + System.lineSeparator() +
"nonMatchingUserName" + System.lineSeparator() +
"somethingElse" + System.lineSeparator());
scm.getExtensions().add(userExclusion);
project.setScm(scm);

GitHubTriggerEvent event = GitHubTriggerEvent.create()
.withTimestamp(System.currentTimeMillis())
.withOrigin("origin")
.withTriggeredByUser("userName")
.build();
trigger.onPost(event);

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

0 comments on commit 0d54b11

Please sign in to comment.