Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 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.BranchSpec;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.extensions.impl.UserExclusion;
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 All @@ -49,11 +54,13 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
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 All @@ -65,6 +72,7 @@
* @author Kohsuke Kawaguchi
*/
public class GitHubPushTrigger extends Trigger<Job<?, ?>> implements GitHubTrigger {
private boolean useGitExcludedUsers;

@DataBoundConstructor
public GitHubPushTrigger() {
Expand Down Expand Up @@ -98,6 +106,32 @@ public void onPost(final GitHubTriggerEvent event) {
if (Objects.isNull(job)) {
return; // nothing to do
}
if (job instanceof AbstractProject && (((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
}
}
}

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

Expand Down Expand Up @@ -168,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 Expand Up @@ -241,6 +299,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
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
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\", comparison is case insensitive)"), field: "useGitExcludedUsers")
}
Loading