Skip to content

Add GithubSenderCause to PR and push GHEventSubscribers #388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package org.jenkinsci.plugins.github_branch_source;

import hudson.model.Cause;
import java.util.Objects;
import org.kohsuke.stapler.export.Exported;

public final class GitHubSenderCause extends Cause {
private final long id;
private final String login;
private final String name;
private final Kind kind;

GitHubSenderCause(long id, String login, String name, Kind kind) {
this.id = id;
this.login = login;
this.name = name;
this.kind = kind;
}

@Exported(visibility = 3)
public long getId() {
return id;
}

@Exported(visibility = 3)
public String getLogin() {
return login;
}

@Exported(visibility = 3)
public String getName() {
return name;
}

@Exported(visibility = 3)
public Kind getKind() {
return kind;
}

@Override
public String getShortDescription() {
String user;
if (name == null) {
user = login;
} else {
user = String.format("%s (%s)", new Object[] {name, login});
}
return String.format("Caused by GitHub event \"%s\" due to user %s", new Object[] {kind, user});
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
GitHubSenderCause cause = (GitHubSenderCause) obj;
return id == cause.id
&& stringEquals(login, cause.login)
&& stringEquals(name, cause.name)
&& kind == cause.kind;
}

@Override
public int hashCode() {
return Objects.hash(id, login, name, kind);
}

private boolean stringEquals(String a, String b) {
if (a == null) {
return b == null;
}
return a.equals(b);
}

@Override
public String toString() {
return String.format(
"[id=%s] [login=%s] [name=%s] [kind=%s]", new Object[] {id, login, name, kind.name()});
}

public enum Kind {
BRANCH_CREATED("branch created"),
BRANCH_DELETED("branch deleted"),
BRANCH_UPDATED("branch updated"),
PULL_REQUEST_CREATED("pull request created"),
PULL_REQUEST_UPDATED("pull request updated"),
PULL_REQUEST_DELETED("pull request deleted"),
PULL_REQUEST_OTHER("pull request");

private String description;

Kind(String description) {
this.description = description;
}

public String toString() {
return description;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.cloudbees.jenkins.GitHubRepositoryName;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.model.Cause;
import hudson.model.Item;
import hudson.scm.SCM;
import java.io.IOException;
Expand Down Expand Up @@ -57,6 +58,7 @@
import jenkins.scm.api.SCMSourceOwner;
import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy;
import jenkins.scm.api.trait.SCMHeadPrefilter;
import org.apache.commons.lang3.ArrayUtils;
import org.jenkinsci.plugins.github.extension.GHEventsSubscriber;
import org.jenkinsci.plugins.github.extension.GHSubscriberEvent;
import org.kohsuke.github.GHEvent;
Expand Down Expand Up @@ -188,6 +190,36 @@ private boolean isApiMatch(String apiUri) {
return repoHost.equalsIgnoreCase(RepositoryUriResolver.hostnameFromApiUri(apiUri));
}

@Override
public Cause[] asCauses() {
Cause[] causes = super.asCauses();
long senderId = getPayload().getSender().getId();
String senderLogin = getPayload().getSender().getLogin();
String senderName = null;
try {
senderName = getPayload().getSender().getName();
} catch (IOException e) {
LOGGER.warning("couldn't determine sender name");
}
GitHubSenderCause.Kind kind;
String action = getPayload().getAction();
if ("opened".equals(action)) {
kind = GitHubSenderCause.Kind.PULL_REQUEST_CREATED;
} else if ("reopened".equals(action)
|| "synchronize".equals(action)
|| "edited".equals(action)) {
kind = GitHubSenderCause.Kind.PULL_REQUEST_UPDATED;
} else if ("closed".equals(action)) {
kind = GitHubSenderCause.Kind.PULL_REQUEST_DELETED;
} else {
kind = GitHubSenderCause.Kind.PULL_REQUEST_OTHER;
}
causes =
ArrayUtils.addAll(
causes, new Cause[] {new GitHubSenderCause(senderId, senderLogin, senderName, kind)});
return causes;
}

@Override
public boolean isMatch(@NonNull SCMNavigator navigator) {
return navigator instanceof GitHubSCMNavigator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
import com.cloudbees.jenkins.GitHubRepositoryName;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.model.Cause;
import hudson.model.Item;
import hudson.scm.SCM;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collections;
import java.util.Map;
Expand All @@ -54,6 +56,7 @@
import jenkins.scm.api.SCMSource;
import jenkins.scm.api.SCMSourceOwner;
import jenkins.scm.api.trait.SCMHeadPrefilter;
import org.apache.commons.lang3.ArrayUtils;
import org.jenkinsci.plugins.github.extension.GHEventsSubscriber;
import org.jenkinsci.plugins.github.extension.GHSubscriberEvent;
import org.kohsuke.github.GHEvent;
Expand Down Expand Up @@ -178,19 +181,44 @@ private static class SCMHeadEventImpl extends SCMHeadEvent<GHEventPayload.Push>
public SCMHeadEventImpl(
Type type,
long timestamp,
GHEventPayload.Push pullRequest,
GHEventPayload.Push push,
GitHubRepositoryName repo,
String origin) {
super(type, timestamp, pullRequest, origin);
super(type, timestamp, push, origin);
this.repoHost = repo.getHost();
this.repoOwner = pullRequest.getRepository().getOwnerName();
this.repository = pullRequest.getRepository().getName();
this.repoOwner = push.getRepository().getOwnerName();
this.repository = push.getRepository().getName();
}

private boolean isApiMatch(String apiUri) {
return repoHost.equalsIgnoreCase(RepositoryUriResolver.hostnameFromApiUri(apiUri));
}

@Override
public Cause[] asCauses() {
Cause[] causes = super.asCauses();
long senderId = getPayload().getSender().getId();
String senderLogin = getPayload().getSender().getLogin();
String senderName = null;
try {
senderName = getPayload().getSender().getName();
} catch (IOException e) {
LOGGER.warning("couldn't determine sender name");
}
GitHubSenderCause.Kind kind;
if (getPayload().isCreated()) {
kind = GitHubSenderCause.Kind.BRANCH_CREATED;
} else if (getPayload().isDeleted()) {
kind = GitHubSenderCause.Kind.BRANCH_DELETED;
} else {
kind = GitHubSenderCause.Kind.BRANCH_UPDATED;
}
causes =
ArrayUtils.addAll(
causes, new Cause[] {new GitHubSenderCause(senderId, senderLogin, senderName, kind)});
return causes;
}

/** {@inheritDoc} */
@Override
public boolean isMatch(@NonNull SCMNavigator navigator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import static org.junit.Assert.assertEquals;

import hudson.model.Cause;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import jenkins.scm.api.SCMEvent;
Expand All @@ -52,6 +53,7 @@ public class EventsTest {

private static SCMEvent.Type firedEventType;
private static GHSubscriberEvent ghEvent;
private static Cause[] firedEventCauses;

@BeforeClass
public static void setupDelay() {
Expand All @@ -61,8 +63,10 @@ public static void setupDelay() {
@Before
public void resetFiredEvent() {
firedEventType = null;
firedEventCauses = null;
ghEvent = null;
TestSCMEventListener.setReceived(false);
TestSCMEventListener.setError(null);
}

@AfterClass
Expand All @@ -75,6 +79,11 @@ public void given_ghPushEventCreated_then_createdHeadEventFired() throws Excepti
PushGHEventSubscriber subscriber = new PushGHEventSubscriber();

firedEventType = SCMEvent.Type.CREATED;
firedEventCauses =
new Cause[] {
new GitHubSenderCause(
6752317, "baxterthehacker", null, GitHubSenderCause.Kind.BRANCH_CREATED)
};
ghEvent = callOnEvent(subscriber, "EventsTest/pushEventCreated.json");
waitAndAssertReceived(true);
}
Expand All @@ -84,6 +93,11 @@ public void given_ghPushEventDeleted_then_removedHeadEventFired() throws Excepti
PushGHEventSubscriber subscriber = new PushGHEventSubscriber();

firedEventType = SCMEvent.Type.REMOVED;
firedEventCauses =
new Cause[] {
new GitHubSenderCause(
6752317, "baxterthehacker", null, GitHubSenderCause.Kind.BRANCH_DELETED)
};
ghEvent = callOnEvent(subscriber, "EventsTest/pushEventRemoved.json");
waitAndAssertReceived(true);
}
Expand All @@ -93,6 +107,11 @@ public void given_ghPushEventUpdated_then_updatedHeadEventFired() throws Excepti
PushGHEventSubscriber subscriber = new PushGHEventSubscriber();

firedEventType = SCMEvent.Type.UPDATED;
firedEventCauses =
new Cause[] {
new GitHubSenderCause(
6752317, "baxterthehacker", null, GitHubSenderCause.Kind.BRANCH_UPDATED)
};
ghEvent = callOnEvent(subscriber, "EventsTest/pushEventUpdated.json");
waitAndAssertReceived(true);
}
Expand All @@ -102,6 +121,11 @@ public void given_ghPullRequestEventOpened_then_createdHeadEventFired() throws E
PullRequestGHEventSubscriber subscriber = new PullRequestGHEventSubscriber();

firedEventType = SCMEvent.Type.CREATED;
firedEventCauses =
new Cause[] {
new GitHubSenderCause(
6752317, "baxterthehacker", null, GitHubSenderCause.Kind.PULL_REQUEST_CREATED)
};
ghEvent = callOnEvent(subscriber, "EventsTest/pullRequestEventCreated.json");
waitAndAssertReceived(true);
}
Expand All @@ -111,6 +135,11 @@ public void given_ghPullRequestEventClosed_then_removedHeadEventFired() throws E
PullRequestGHEventSubscriber subscriber = new PullRequestGHEventSubscriber();

firedEventType = SCMEvent.Type.REMOVED;
firedEventCauses =
new Cause[] {
new GitHubSenderCause(
6752317, "baxterthehacker", null, GitHubSenderCause.Kind.PULL_REQUEST_DELETED)
};
ghEvent = callOnEvent(subscriber, "EventsTest/pullRequestEventRemoved.json");
waitAndAssertReceived(true);
}
Expand All @@ -120,6 +149,11 @@ public void given_ghPullRequestEventReopened_then_updatedHeadEventFired() throws
PullRequestGHEventSubscriber subscriber = new PullRequestGHEventSubscriber();

firedEventType = SCMEvent.Type.UPDATED;
firedEventCauses =
new Cause[] {
new GitHubSenderCause(
6752317, "baxterthehacker", null, GitHubSenderCause.Kind.PULL_REQUEST_UPDATED)
};
ghEvent = callOnEvent(subscriber, "EventsTest/pullRequestEventUpdated.json");
waitAndAssertReceived(true);
}
Expand All @@ -129,6 +163,11 @@ public void given_ghPullRequestEventSync_then_updatedHeadEventFired() throws Exc
PullRequestGHEventSubscriber subscriber = new PullRequestGHEventSubscriber();

firedEventType = SCMEvent.Type.UPDATED;
firedEventCauses =
new Cause[] {
new GitHubSenderCause(
6752317, "baxterthehacker", null, GitHubSenderCause.Kind.PULL_REQUEST_UPDATED)
};
ghEvent = callOnEvent(subscriber, "EventsTest/pullRequestEventUpdatedSync.json");
waitAndAssertReceived(true);
}
Expand All @@ -139,6 +178,7 @@ public void given_ghRepositoryEventCreatedFromFork_then_createdSourceEventFired(
GitHubRepositoryEventSubscriber subscriber = new GitHubRepositoryEventSubscriber();

firedEventType = SCMEvent.Type.CREATED;
firedEventCauses = new Cause[] {};
ghEvent = callOnEvent(subscriber, "EventsTest/repositoryEventCreated.json");
waitAndAssertReceived(true);
}
Expand Down Expand Up @@ -194,26 +234,35 @@ private void waitAndAssertReceived(boolean received) throws InterruptedException
"Event should have " + ((!received) ? "not " : "") + "been received",
received,
TestSCMEventListener.didReceive());
if (TestSCMEventListener.didError() != null) {
throw TestSCMEventListener.didError();
}
}

@TestExtension
public static class TestSCMEventListener extends jenkins.scm.api.SCMEventListener {

private static boolean eventReceived = false;
private static Error error = null;

public void onSCMHeadEvent(SCMHeadEvent<?> event) {
receiveEvent(event.getType(), event.getOrigin());
receiveEvent(event.getType(), event.getOrigin(), event.asCauses());
}

public void onSCMSourceEvent(SCMSourceEvent<?> event) {
receiveEvent(event.getType(), event.getOrigin());
receiveEvent(event.getType(), event.getOrigin(), event.asCauses());
}

private void receiveEvent(SCMEvent.Type type, String origin) {
private void receiveEvent(SCMEvent.Type type, String origin, Cause[] causes) {
eventReceived = true;

assertEquals("Event type should be the same", type, firedEventType);
assertEquals("Event origin should be the same", origin, ghEvent.getOrigin());
try {
assertEquals("Event type should be the same", type, firedEventType);
assertEquals("Event causes should be the same", causes, firedEventCauses);
assertEquals("Event origin should be the same", origin, ghEvent.getOrigin());
} catch (Error e) {
error = e;
}
}

public static boolean didReceive() {
Expand All @@ -223,5 +272,13 @@ public static boolean didReceive() {
public static void setReceived(boolean received) {
eventReceived = received;
}

public static Error didError() {
return error;
}

public static void setError(Error e) {
error = e;
}
}
}