Skip to content
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

Add push event information as arguments to triggered jobs. #169

Open
wants to merge 3 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
55 changes: 55 additions & 0 deletions src/main/java/com/cloudbees/jenkins/GitHubParametersAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.cloudbees.jenkins;

import hudson.EnvVars;
import hudson.Extension;
import hudson.model.EnvironmentContributor;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.model.Run;
import hudson.model.TaskListener;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class GitHubParametersAction extends ParametersAction {

private List<ParameterValue> parameters;

public GitHubParametersAction(List<ParameterValue> parameters) {
super(parameters);
this.parameters = parameters;
}

@Override
public List<ParameterValue> getParameters() {
return Collections.unmodifiableList(parameters);
}

@Override
public ParameterValue getParameter(String name) {
for (ParameterValue parameter : parameters) {
if (parameter != null && parameter.getName().equals(name)) {
return parameter;
}
}
return null;
}

@Extension
public static final class GitHubParameterEnvironmentContributor extends EnvironmentContributor {

@Override
public void buildEnvironmentFor(Run run,
EnvVars envs,
TaskListener listener) throws IOException, InterruptedException {
GitHubParametersAction gpa = run.getAction(GitHubParametersAction.class);
if (gpa != null) {
for (ParameterValue p : gpa.getParameters()) {
envs.put(p.getName(), String.valueOf(p.getValue()));
}
}
super.buildEnvironmentFor(run, envs, listener);
}
}
}
53 changes: 51 additions & 2 deletions src/main/java/com/cloudbees/jenkins/GitHubPushTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
import hudson.console.AnnotatedLargeText;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.CauseAction;
import hudson.model.Item;
import hudson.model.Job;
import hudson.model.ParameterDefinition;
import hudson.model.ParameterValue;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Project;
import hudson.model.StringParameterValue;
import hudson.model.queue.QueueTaskFuture;
import hudson.triggers.SCMTrigger;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
Expand Down Expand Up @@ -44,9 +50,11 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -79,10 +87,12 @@ public void onPost() {
/**
* Called when a POST is made.
*/
public void onPost(String triggeredByUser) {
public void onPost(String triggeredByUser, String ref, String head) {
onPost(GitHubTriggerEvent.create()
.withOrigin(SCMEvent.originOf(Stapler.getCurrentRequest()))
.withTriggeredByUser(triggeredByUser)
.withRef(ref)
.withHead(head)
.build()
);
}
Expand All @@ -92,6 +102,8 @@ public void onPost(String triggeredByUser) {
*/
public void onPost(final GitHubTriggerEvent event) {
final String pushBy = event.getTriggeredByUser();
final String ref = event.getRef();
final String head = event.getHead();
DescriptorImpl d = getDescriptor();
d.checkThreadPoolSizeAndUpdateIfNecessary();
d.queue.execute(new Runnable() {
Expand Down Expand Up @@ -140,7 +152,23 @@ public void run() {
LOGGER.warn("Failed to parse the polling log", e);
cause = new GitHubPushCause(pushBy);
}
if (asParameterizedJobMixIn(job).scheduleBuild(cause)) {

// Get the parameters defined by the job, as we will be overriding certain values
List<ParameterValue> values = getDefaultParameters();
Iterator<ParameterValue> it = values.iterator();
while (it.hasNext()) {
ParameterValue pv = it.next();
if (parameterIsOverridable(pv.getName())) {
it.remove();
}
}
values.add(new StringParameterValue("ref", ref));
values.add(new StringParameterValue("head", head));

// Schedule the job with the parameters and cause
QueueTaskFuture<?> build = asParameterizedJobMixIn(job)
.scheduleBuild2(0, new GitHubParametersAction(values), new CauseAction(cause));
if (build != null) {
LOGGER.info("SCM changes detected in " + job.getFullName()
+ ". Triggering #" + job.getNextBuildNumber());
} else {
Expand All @@ -151,6 +179,27 @@ public void run() {
});
}

/**
* Returns the default parameter values for the parameters of this job
*/
private List<ParameterValue> getDefaultParameters() {
ArrayList<ParameterValue> values = new ArrayList<ParameterValue>();
ParametersDefinitionProperty pdp = this.job.getProperty(ParametersDefinitionProperty.class);
if (pdp != null) {
for (ParameterDefinition pd : pdp.getParameterDefinitions()) {
values.add(pd.getDefaultParameterValue());
}
}
return values;
}

/**
* Returns whether or not a given parameter WILL be overridden
*/
private static boolean parameterIsOverridable(String paramName) {
return "ref".equalsIgnoreCase(paramName) || "head".equalsIgnoreCase(paramName);
}

/**
* Returns the file that records the last/current polling activity.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/cloudbees/jenkins/GitHubTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public interface GitHubTrigger {
void onPost();

// TODO: document me
void onPost(String triggeredByUser);
void onPost(String triggeredByUser, String ref, String head);

/**
* Obtains the list of the repositories that this trigger is looking at.
Expand Down
48 changes: 45 additions & 3 deletions src/main/java/com/cloudbees/jenkins/GitHubTriggerEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,21 @@ public class GitHubTriggerEvent {
* The user that the event was provided by.
*/
private final String triggeredByUser;
/**
* The user reference that the event affected
*/
private final String ref;
/**
* The head of the repo after the event
*/
private final String head;

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

public static Builder create() {
Expand All @@ -45,6 +55,14 @@ public String getTriggeredByUser() {
return triggeredByUser;
}

public String getRef() {
return ref;
}

public String getHead() {
return head;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand All @@ -62,14 +80,22 @@ public boolean equals(Object o) {
if (origin != null ? !origin.equals(that.origin) : that.origin != null) {
return false;
}
return triggeredByUser != null ? triggeredByUser.equals(that.triggeredByUser) : that.triggeredByUser == null;
if (triggeredByUser != null ? !triggeredByUser.equals(that.triggeredByUser) : that.triggeredByUser != null) {
return false;
}
if (ref != null ? !ref.equals(that.ref) : that.ref != null) {
return false;
}
return head != null ? head.equals(that.head) : that.head == null;
}

@Override
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);
result = 31 * result + (head != null ? head.hashCode() : 0);
return result;
}

Expand All @@ -79,6 +105,8 @@ public String toString() {
+ "timestamp=" + timestamp
+ ", origin='" + origin + '\''
+ ", triggeredByUser='" + triggeredByUser + '\''
+ ", ref='" + ref + '\''
+ ", head='" + head + '\''
+ '}';
}

Expand All @@ -89,6 +117,8 @@ public static class Builder {
private long timestamp;
private String origin;
private String triggeredByUser;
private String ref;
private String head;

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

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

public Builder withHead(String head) {
this.head = head;
return this;
}

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

@Override
Expand All @@ -119,6 +159,8 @@ public String toString() {
+ "timestamp=" + timestamp
+ ", origin='" + origin + '\''
+ ", triggeredByUser='" + triggeredByUser + '\''
+ ", ref='" + ref + '\''
+ ", head='" + head + '\''
+ '}';
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ protected void onEvent(final GHSubscriberEvent event) {
}
URL repoUrl = push.getRepository().getUrl();
final String pusherName = push.getPusher().getName();
final String ref = push.getRef();
final String head = push.getHead();
LOGGER.info("Received PushEvent for {} from {}", repoUrl, event.getOrigin());
final GitHubRepositoryName changedRepository = GitHubRepositoryName.create(repoUrl.toExternalForm());

Expand All @@ -97,6 +99,8 @@ public void run() {
.withTimestamp(event.getTimestamp())
.withOrigin(event.getOrigin())
.withTriggeredByUser(pusherName)
.withHead(head)
.withRef(ref)
.build()
);
} else {
Expand Down
20 changes: 19 additions & 1 deletion src/test/java/com/cloudbees/jenkins/GitHubPushTriggerTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cloudbees.jenkins;

import hudson.model.CauseAction;
import hudson.model.FreeStyleProject;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.util.Build;
Expand All @@ -24,7 +25,10 @@

import static com.cloudbees.jenkins.GitHubWebHookFullTest.classpath;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventListenerTest.HEAD_COMMIT;
import static org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventListenerTest.MASTER_BRANCH_REF;
import static org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventListenerTest.TRIGGERED_BY_USER_FROM_RESOURCE;

/**
Expand Down Expand Up @@ -69,12 +73,26 @@ public void shouldStartWorkflowByTrigger() throws Exception {
buildData.buildsByBranchName = new HashMap<String, Build>();
buildData.getLastBuiltRevision().setSha1(ObjectId.zeroId());

trigger.onPost(TRIGGERED_BY_USER_FROM_RESOURCE);
trigger.onPost(TRIGGERED_BY_USER_FROM_RESOURCE, MASTER_BRANCH_REF, HEAD_COMMIT);

TimeUnit.SECONDS.sleep(job.getQuietPeriod());
jRule.waitUntilNoActivity();

assertThat("should be 2 build after hook", job.getLastBuild().getNumber(), is(2));

// Validate that the we have added 2 actions of the correct types
// Validate that the parameters we have added are correct
GitHubParametersAction parametersAction = job.getLastBuild().getAction(GitHubParametersAction.class);
assertThat("found GitHubParametersAction", parametersAction != null);
assertThat("should be 2 parameters added", parametersAction.getParameters(), hasSize(2));
assertThat("first parameter is ref with value " + MASTER_BRANCH_REF,
"ref".equalsIgnoreCase(parametersAction.getParameters().get(0).getName())
&& MASTER_BRANCH_REF.equals(parametersAction.getParameters().get(0).getValue()));
assertThat("second parameter is head with value " + HEAD_COMMIT,
"head".equalsIgnoreCase(parametersAction.getParameters().get(1).getName())
&& HEAD_COMMIT.equals(parametersAction.getParameters().get(1).getValue()));
CauseAction causeAction = job.getLastBuild().getAction(CauseAction.class);
assertThat("found CauseAction", causeAction != null);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class DefaultPushGHEventListenerTest {

public static final GitSCM GIT_SCM_FROM_RESOURCE = new GitSCM("ssh://[email protected]/lanwen/test.git");
public static final String TRIGGERED_BY_USER_FROM_RESOURCE = "lanwen";
public static final String MASTER_BRANCH_REF = "refs/heads/master";
public static final String HEAD_COMMIT = "1eee2db8927ab3f7ec983b2e6052f351dd61a419";

@Rule
public JenkinsRule jenkins = new JenkinsRule();
Expand Down Expand Up @@ -62,6 +64,8 @@ public void shouldParsePushPayload() throws Exception {
.withTimestamp(subscriberEvent.getTimestamp())
.withOrigin("shouldParsePushPayload")
.withTriggeredByUser(TRIGGERED_BY_USER_FROM_RESOURCE)
.withRef(MASTER_BRANCH_REF)
.withHead(HEAD_COMMIT)
.build()
));
}
Expand All @@ -85,6 +89,8 @@ public void shouldReceivePushHookOnWorkflow() throws Exception {
.withTimestamp(subscriberEvent.getTimestamp())
.withOrigin("shouldReceivePushHookOnWorkflow")
.withTriggeredByUser(TRIGGERED_BY_USER_FROM_RESOURCE)
.withRef(MASTER_BRANCH_REF)
.withHead(HEAD_COMMIT)
.build()
));
}
Expand Down