Skip to content
This repository has been archived by the owner on Mar 14, 2023. It is now read-only.

Commit

Permalink
1.1.0 support pipeline jobs. support gh webhook ping event.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bernhard Grünewaldt committed Aug 24, 2017
1 parent 2154466 commit 2e23e55
Show file tree
Hide file tree
Showing 7 changed files with 286 additions and 14 deletions.
32 changes: 31 additions & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,45 @@

```bash
mvn compile && rm -rf work/ && mvn hpi:run
// configure GitHub Secret to `foobar23` via webui
```


**Testcase: Push Event**

```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "x-hub-signature: sha1=5b8a54ee48efb1fbe06e3e4fc5d120680eaa2a22" \
-d @test-webhook-payload.json \
http://localhost:8080/jenkins/github-webhook-build-trigger/receive
```

* With GitHub Secret being: `foobar23`
 


**Testcase: Ping Event**

Initial webhook created request.
Only fired once when you setup the webhook on github. See: https://developer.github.com/webhooks/#ping-event

```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "x-hub-signature: sha1=c203f51e9317264c6716ee0c6fed59d604674885" \
-d @test-webhook-init-payload.json \
http://localhost:8080/jenkins/github-webhook-build-trigger/receive
```

 

**x-hub-signature**

Create an sha1 hash for a payload.json:

```bash
cat test-webhook-init-payload.json | openssl dgst -sha1 -hmac "foobar23"
```

### Build hpi

Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,37 @@ git clone --single-branch \
source
```

 

**Usage with Pipeline Jobs**

Since version 1.1.0 [Pipeline Job Types](https://jenkins.io/doc/book/pipeline/) (NOT MultiBranch Pipeline) are supported.

Make sure you have at least the following Plugins installed

```
Pipeline: Groovy
Pipeline: Job
Pipeline: API
Pipeline: Step API
Pipeline: Stage Step
Pipeline: Basic Steps
Pipeline: Model API
```

A simple **`Jenkinsfile`** could look like this:

```
node {
stage('foo') {
sh 'git clone --single-branch --branch ${env.GWBT_BRANCH} https://github.com/${env.GWBT_REPO_FULL_NAME}.git source'
dir('source') {
sh 'npm install'
}
}
}
```

-----

 
Expand Down
14 changes: 12 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.25</version>
<version>2.33</version>
<relativePath/>
</parent>
<groupId>io.codeclou.jenkins.github.webhook.notifier.plugin</groupId>
<artifactId>github-webhook-notifier-plugin</artifactId>
<version>1.0.1</version>
<version>1.1.0</version>
<packaging>hpi</packaging>

<name>github-webhook-notifier-plugin</name>
Expand Down Expand Up @@ -52,5 +52,15 @@
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>2.5</version>
<optional>true</optional>
</dependency>
</dependencies>
<!-- https://wiki.jenkins.io/display/JENKINS/Choosing+Jenkins+version+to+build+against -->
<properties>
<jenkins.version>2.73</jenkins.version>
</properties>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
package io.codeclou.jenkins.githubwebhookbuildtriggerplugin;

import hudson.EnvVars;
import hudson.model.AbstractBuild;
import hudson.model.EnvironmentContributingAction;
import hudson.model.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
Expand Down Expand Up @@ -48,7 +49,7 @@ public EnvironmentContributionAction(GithubWebhookPayload payload) {
* converts "refs/heads/develop" to "develop"
*/
private String normalizeBranchNameOrEmptyString(String branchname) {
if (branchname.startsWith("refs/heads/")) {
if (branchname != null && branchname.startsWith("refs/heads/")) {
return branchname.replace("refs/heads/", "");
}
return "";
Expand All @@ -58,7 +59,7 @@ private String normalizeBranchNameOrEmptyString(String branchname) {
* converts "refs/tags/1.0.0" to "1.0.0"
*/
private String normalizeTagNameOrEmptyString(String tagname) {
if (tagname.startsWith("refs/tags/")) {
if (tagname != null && tagname.startsWith("refs/tags/")) {
return tagname.replace("refs/tags/", "");
}
return "";
Expand Down Expand Up @@ -90,4 +91,19 @@ public void buildEnvVars(AbstractBuild<?, ?> build, EnvVars env) {
env.putAll(environmentVariables);
}
}

/**
* Since WorkflowJob does not support EnvironmentContributionAction yet,
* we need a ParametersAction filled with List ParameterValue
* See: https://github.com/jenkinsci/workflow-job-plugin/blob/124b171b76394728f9c8504829cf6857abc8bdb5/src/main/java/org/jenkinsci/plugins/workflow/job/WorkflowRun.java#L435
*/
public ParametersAction transform() {
List<ParameterValue> paramValues = new ArrayList<>();
List<String> safeParams = new ArrayList<>();
for (Map.Entry<String, String> envVar : environmentVariables.entrySet()) {
paramValues.add(new StringParameterValue(envVar.getKey(), envVar.getValue(), envVar.getValue()));
safeParams.add(envVar.getKey());
}
return new ParametersAction(paramValues, safeParams);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,30 @@

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import hudson.EnvVars;
import hudson.Extension;
import hudson.model.*;
import hudson.model.queue.QueueTaskFuture;
import hudson.util.HttpResponses;
import io.codeclou.jenkins.githubwebhookbuildtriggerplugin.config.GithubWebhookBuildTriggerPluginBuilder;
import io.codeclou.jenkins.githubwebhookbuildtriggerplugin.webhooksecret.GitHubWebhookUtility;
import jenkins.model.Jenkins;
import org.apache.commons.io.IOUtils;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.interceptor.RequirePOST;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.swing.plaf.basic.BasicToolTipUI;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;

@Extension
public class GithubWebhookBuildTriggerAction implements UnprotectedRootAction {
public class GithubWebhookBuildTriggerAction implements UnprotectedRootAction, EnvironmentContributingAction {

@Override
public String getUrlName() {
Expand Down Expand Up @@ -65,7 +68,7 @@ public HttpResponse doReceive(HttpServletRequest request, StaplerRequest stapler
String webhookSecretAsConfiguredByUser = GithubWebhookBuildTriggerPluginBuilder.DescriptorImpl.getDescriptor().getWebhookSecret();
String webhookSecretMessage ="validating webhook payload against wevhook secret.";
info.append(">> webhook secret validation").append("\n");
if (webhookSecretAsConfiguredByUser == null) {
if (webhookSecretAsConfiguredByUser == null || webhookSecretAsConfiguredByUser.isEmpty()) {
webhookSecretMessage = " skipping validation since no webhook secret is configured in \n" +
" 'Jenkins' -> 'Configure' tab under 'Github Webhook Build Trigger' section.";
} else {
Expand All @@ -77,11 +80,23 @@ public HttpResponse doReceive(HttpServletRequest request, StaplerRequest stapler
webhookSecretMessage = " ok. Webhook secret validates against " + githubSignature + "\n";
}
info.append(webhookSecretMessage).append("\n\n");

//
// PAYLOAD TO ENVVARS
// CHECK IF INITIAL REQUEST (see test-webhook-init-payload.json)
// See: https://developer.github.com/webhooks/#ping-event
//
if (githubWebhookPayload.getHook_id() != null) {
info.append(">> ping request received: your webhook with ID ");
info.append(githubWebhookPayload.getHook_id());
info.append(" is working :)\n");
return HttpResponses.plainText(this.getTextEnvelopedInBanner(info.toString()));
}

//
// PAYLOAD TO ENVVARS
//
EnvironmentContributionAction environmentContributionAction = new EnvironmentContributionAction(githubWebhookPayload);

//
// TRIGGER JOBS
//
Expand All @@ -103,10 +118,25 @@ public HttpResponse doReceive(HttpServletRequest request, StaplerRequest stapler
}
for (Job job: jobs) {
if (job.getName().startsWith(jobNamePrefix) && ! jobsAlreadyTriggered.contains(job.getName())) {
jobsTriggered.append(" ").append(job.getName()).append("\n");
jobsAlreadyTriggered.add(job.getName());
AbstractProject projectScheduable = (AbstractProject) job;
projectScheduable.scheduleBuild(0, cause, environmentContributionAction);
if (job instanceof WorkflowJob) {
WorkflowJob wjob = (WorkflowJob) job;
if (wjob.isBuildable()) {
jobsTriggered.append(" WORKFLOWJOB> ").append(job.getName()).append(" TRIGGERED\n");
wjob.addAction(environmentContributionAction.transform());
wjob.scheduleBuild(0, cause);
} else {
jobsTriggered.append(" WORKFLOWJOB> ").append(job.getName()).append(" NOT BUILDABLE. SKIPPING.\n");
}
} else {
AbstractProject projectScheduable = (AbstractProject) job;
if (job.isBuildable()) {
jobsTriggered.append(" CLASSICJOB> ").append(job.getName()).append(" TRIGGERED\n");
projectScheduable.scheduleBuild(0, cause, environmentContributionAction);
} else {
jobsTriggered.append(" CLASSICJOB> ").append(job.getName()).append(" NOT BUILDABLE. SKIPPING.\n");
}
}
}
}
//
Expand Down Expand Up @@ -139,4 +169,9 @@ private String getTextEnvelopedInBanner(String text) {
banner.append("\n----------------------------------------------------------------------------------\n");
return banner.toString();
}

@Override
public void buildEnvVars(AbstractBuild<?, ?> abstractBuild, EnvVars envVars) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
*/
public class GithubWebhookPayload {

/*
* hook_id is only set on initial request when the webhook is created.
* See: https://developer.github.com/webhooks/#ping-event
*/
private Long hook_id;
private String ref;
private String before;
private String after;
Expand Down Expand Up @@ -51,6 +56,14 @@ public void setRepository(GithubWebhookPayloadRepository repository) {
this.repository = repository;
}

public Long getHook_id() {
return hook_id;
}

public void setHook_id(Long hook_id) {
this.hook_id = hook_id;
}

public class GithubWebhookPayloadRepository {
private String clone_url;
private String html_url;
Expand Down
Loading

0 comments on commit 2e23e55

Please sign in to comment.