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

Commit 8de4560

Browse files
author
Bernhard Grünewaldt
committed
work in progress but global config to set webhook secret working
1 parent 4437eda commit 8de4560

File tree

8 files changed

+276
-117
lines changed

8 files changed

+276
-117
lines changed

DEVELOPMENT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Howto manually checkout certain branch at specific revision
2222

2323
```
2424
# Clone develop branch
25-
git clone --single-branch --branch develop https://github.com/codeclou/test-webhook.git .
25+
git clone --single-branch --branch develop https://github.com/codeclou/test-webhook.git foo
2626
# Switch to revision
2727
git reset --hard 495140cf2b763b8bc3821e25b4c26dd1273d6206
2828
```

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ to a state where if your job just build your `master` Branch and you create a ta
2020
and push that tag, that the jenkins job will not be triggered, since the revisions are equal.
2121

2222

23+
### NOTE
24+
25+
When using matrix-based security the 'Anonymous' user needs 'Job' `build,discover,read` rights.
2326

2427

2528

pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,5 @@
5252
<artifactId>commons-io</artifactId>
5353
<version>2.5</version>
5454
</dependency>
55-
<dependency>
56-
<groupId>org.jenkins-ci.plugins</groupId>
57-
<artifactId>git</artifactId>
58-
<version>3.2.0</version>
59-
</dependency>
6055
</dependencies>
6156
</project>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Licensed under MIT License
3+
* Copyright (c) 2017 Bernhard Grünewaldt
4+
*/
5+
package io.codeclou.jenkins.githubwebhooknotifierplugin;
6+
7+
import hudson.EnvVars;
8+
import hudson.model.AbstractBuild;
9+
import hudson.model.EnvironmentContributingAction;
10+
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
14+
public class GithubWebhookEnvironmentContributionAction implements EnvironmentContributingAction {
15+
16+
private transient Map<String, String> environmentVariables = new HashMap<>();
17+
private transient String envVarInfo;
18+
19+
public GithubWebhookEnvironmentContributionAction(GithubWebhookPayload payload) {
20+
String normalizedBranch = this.normalizeBranchNameOrEmptyString(payload.getRef());
21+
String normalizedTag = this.normalizeTagNameOrEmptyString(payload.getRef());
22+
StringBuilder info = new StringBuilder();
23+
info.append(" ref\n -> $GWNP_REF : ").append(payload.getRef()).append("\n");
24+
info.append(" -> $GWNP_TAG : ").append(normalizedTag).append("\n");
25+
info.append(" -> $GWNP_BRANCH : ").append(normalizedBranch).append("\n\n");
26+
info.append(" before\n -> $GWNP_COMMIT_BEFORE : ").append(payload.getBefore()).append("\n\n");
27+
info.append(" after\n -> $GWNP_COMMIT_AFTER : ").append(payload.getAfter()).append("\n\n");
28+
info.append(" repository.clone_url\n -> $GWNP_REPO_CLONE_URL : ").append(payload.getRepository().getClone_url()).append("\n\n");
29+
info.append(" repository.html_url\n -> $GWNP_REPO_HTML_URL : ").append(payload.getRepository().getHtml_url()).append("\n\n");
30+
info.append(" repository.full_name\n -> $GWNP_REPO_FULL_NAME : ").append(payload.getRepository().getFull_name()).append("\n\n");
31+
info.append(" repository.name\n -> $GWNP_REPO_NAME : ").append(payload.getRepository().getName()).append("\n\n");
32+
this.envVarInfo = info.toString();
33+
this.environmentVariables.put("GWNP_REF", payload.getRef());
34+
this.environmentVariables.put("GWNP_TAG", normalizedTag);
35+
this.environmentVariables.put("GWNP_BRANCH", normalizedBranch);
36+
this.environmentVariables.put("GWNP_COMMIT_BEFORE", payload.getBefore());
37+
this.environmentVariables.put("GWNP_COMMIT_AFTER", payload.getAfter());
38+
this.environmentVariables.put("GWNP_REPO_CLONE_URL", payload.getRepository().getClone_url());
39+
this.environmentVariables.put("GWNP_REPO_HTML_URL", payload.getRepository().getHtml_url());
40+
this.environmentVariables.put("GWNP_REPO_FULL_NAME", payload.getRepository().getFull_name());
41+
this.environmentVariables.put("GWNP_REPO_NAME", payload.getRepository().getName());
42+
}
43+
44+
/*
45+
* converts "refs/heads/develop" to "develop"
46+
*/
47+
private String normalizeBranchNameOrEmptyString(String branchname) {
48+
if (branchname.startsWith("refs/heads/")) {
49+
return branchname.replace("refs/heads/", "");
50+
}
51+
return "";
52+
}
53+
54+
/*
55+
* converts "refs/tags/1.0.0" to "1.0.0"
56+
*/
57+
private String normalizeTagNameOrEmptyString(String tagname) {
58+
if (tagname.startsWith("refs/tags/")) {
59+
return tagname.replace("refs/tags/", "");
60+
}
61+
return "";
62+
}
63+
64+
protected String getEnvVarInfo() {
65+
return this.envVarInfo;
66+
}
67+
68+
69+
public String getIconFileName() {
70+
return null;
71+
}
72+
73+
public String getDisplayName() {
74+
return "GithubWebhookEnvironmentContributionAction";
75+
}
76+
77+
public String getUrlName() {
78+
return "GithubWebhookEnvironmentContributionAction";
79+
}
80+
81+
@Override
82+
public void buildEnvVars(AbstractBuild<?, ?> build, EnvVars env) {
83+
if (env == null) {
84+
return;
85+
}
86+
if (environmentVariables != null) {
87+
env.putAll(environmentVariables);
88+
}
89+
}
90+
}

src/main/java/io/codeclou/jenkins/githubwebhooknotifierplugin/GithubWebhookNotifyAction.java

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
import com.google.gson.Gson;
88
import com.google.gson.JsonSyntaxException;
99
import hudson.Extension;
10-
import hudson.model.UnprotectedRootAction;
10+
import hudson.model.*;
11+
import hudson.scm.SCMRevisionState;
12+
import hudson.triggers.SCMTrigger;
13+
import hudson.triggers.Trigger;
1114
import hudson.util.HttpResponses;
1215
import jenkins.model.Jenkins;
1316
import org.apache.commons.io.IOUtils;
@@ -32,6 +35,9 @@
3235
import java.security.NoSuchAlgorithmException;
3336
import java.security.cert.CertificateException;
3437
import java.security.cert.X509Certificate;
38+
import java.util.ArrayList;
39+
import java.util.Collection;
40+
import java.util.HashMap;
3541

3642
@Extension
3743
public class GithubWebhookNotifyAction implements UnprotectedRootAction {
@@ -56,65 +62,60 @@ public String getDisplayName() {
5662
*/
5763
@RequirePOST
5864
public HttpResponse doReceive(HttpServletRequest request, StaplerRequest staplerRequest) throws IOException, ServletException {
59-
String jenkinsRootUrl = Jenkins.getInstance().getRootUrl(); // will return something like: http://localhost:8080/jenkins/
6065
BufferedReader reader = request.getReader();
6166
Gson gson = new Gson();
6267
try {
6368
GithubWebhookPayload githubWebhookPayload = gson.fromJson(reader, GithubWebhookPayload.class);
64-
// Trigger Git-Plugins notify push SCM Polling Endpoint
65-
String gitPluginNotifyUrl = jenkinsRootUrl +
66-
"git/notifyCommit?url=" +
67-
githubWebhookPayload.getRepository().getClone_url() +
68-
"&branches=" +
69-
this.normalizeBranchNameForJenkins(githubWebhookPayload.getRef()) +
70-
"&sha1=" +
71-
githubWebhookPayload.getAfter();
72-
SSLContext sslContext = new SSLContextBuilder()
73-
.loadTrustMaterial(null, new TrustStrategy() {
74-
@Override
75-
public boolean isTrusted(X509Certificate[] certificate, String authType) throws CertificateException {
76-
return true;
77-
}
78-
}).build();
79-
CloseableHttpClient client = HttpClients.custom()
80-
.setSSLContext(sslContext)
81-
.setSSLHostnameVerifier(new NoopHostnameVerifier())
82-
.build();
83-
HttpGet httpGet = new HttpGet(gitPluginNotifyUrl);
84-
CloseableHttpResponse response = client.execute(httpGet);
85-
int statusCode = response.getStatusLine().getStatusCode();
86-
String gitNotificationResponse = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
87-
StringBuilder responseText = new StringBuilder();
88-
responseText.append("----------------------------------------------------------------------------------\n");
89-
responseText.append("github-webhook-notifier-plugin - parsed webhook payload:\n");
90-
responseText.append(" ref: ").append(githubWebhookPayload.getRef()).append("\n");
91-
responseText.append(" before: ").append(githubWebhookPayload.getBefore()).append("\n");
92-
responseText.append(" after: ").append(githubWebhookPayload.getAfter()).append("\n");
93-
responseText.append(" clone_url: ").append(githubWebhookPayload.getRepository().getClone_url()).append("\n");
94-
responseText.append("----------------------------------------------------------------------------------\n");
95-
responseText.append(">> REQUEST\n").append(gitPluginNotifyUrl).append("\n\n");
96-
responseText.append("<< RESPONSE HTTP ").append(statusCode).append("\n");
97-
responseText.append(gitNotificationResponse);
98-
if (statusCode != 200) {
99-
return HttpResponses.error(400, responseText.toString());
69+
GithubWebhookEnvironmentContributionAction environmentContributionAction = new GithubWebhookEnvironmentContributionAction(githubWebhookPayload);
70+
String jobNamePrefix = this.normalizeRepoFullName(githubWebhookPayload.getRepository().getFull_name());
71+
StringBuilder jobsTriggered = new StringBuilder();
72+
ArrayList<String> jobsAlreadyTriggered = new ArrayList<>();
73+
StringBuilder causeNote = new StringBuilder();
74+
causeNote.append("github-webhook-notifier-plugin:\n");
75+
causeNote.append(githubWebhookPayload.getAfter()).append("\n");
76+
causeNote.append(githubWebhookPayload.getRef()).append("\n");
77+
causeNote.append(githubWebhookPayload.getRepository().getClone_url());
78+
Cause cause = new Cause.RemoteCause("github.com", causeNote.toString());
79+
Collection<Job> jobs = Jenkins.getInstance().getAllItems(Job.class);
80+
if (jobs.isEmpty()) {
81+
jobsTriggered.append("WARNING NO JOBS FOUND!\n");
82+
jobsTriggered.append("If you are using matrix-based security, please give the following rights to 'Anonymous'.\n");
83+
jobsTriggered.append("'Job' -> build, discover, read.\n");
10084
}
101-
return HttpResponses.plainText(responseText.toString());
85+
for (Job job: jobs) {
86+
if (job.getName().startsWith(jobNamePrefix) && ! jobsAlreadyTriggered.contains(job.getName())) {
87+
jobsTriggered.append(" ").append(job.getName()).append("\n");
88+
jobsAlreadyTriggered.add(job.getName());
89+
AbstractProject projectScheduable = (AbstractProject) job;
90+
projectScheduable.scheduleBuild(0, cause, environmentContributionAction);
91+
}
92+
}
93+
StringBuilder info = new StringBuilder();
94+
info.append(">> webhook content to env vars").append("\n");
95+
info.append(environmentContributionAction.getEnvVarInfo());
96+
info.append("\n");
97+
info.append(">> jobs triggered with name matching '").append(jobNamePrefix).append("*'").append("\n");
98+
info.append(jobsTriggered.toString());
99+
return HttpResponses.plainText(this.getTextEnvelopedInBanner(info.toString()));
102100
} catch (JsonSyntaxException ex) {
103-
return HttpResponses.error(500, "github-webhook-notifier-plugin: github webhook json invalid");
104-
} catch (NoSuchAlgorithmException ex) {
105-
return HttpResponses.error(500, "github-webhook-notifier-plugin: internal error NoSuchAlgorithmException");
106-
} catch (KeyStoreException ex) {
107-
return HttpResponses.error(500, "github-webhook-notifier-plugin: internal error KeyStoreException");
108-
} catch (KeyManagementException ex) {
109-
return HttpResponses.error(500, "github-webhook-notifier-plugin: internal error KeyManagementException");
101+
return HttpResponses.error(500, this.getTextEnvelopedInBanner("github webhook json invalid"));
110102
}
111103
}
112104

113105
/*
114-
* converts "refs/heads/develop" to "origin/develop"
106+
* converts "codeclou/foo" to "codeclou---foo"
115107
*/
116-
private String normalizeBranchNameForJenkins(String branchname) {
117-
return branchname.replace("refs/heads/", "origin/");
108+
private String normalizeRepoFullName(String reponame) {
109+
return reponame.replace("/", "---");
118110
}
119111

112+
private String getTextEnvelopedInBanner(String text) {
113+
StringBuilder banner = new StringBuilder();
114+
banner.append("----------------------------------------------------------------------------------\n");
115+
banner.append("github-webhook-notifier-plugin").append("\n");
116+
banner.append("----------------------------------------------------------------------------------\n");
117+
banner.append(text);
118+
banner.append("\n----------------------------------------------------------------------------------\n");
119+
return banner.toString();
120+
}
120121
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package io.codeclou.jenkins.githubwebhooknotifierplugin.config;
2+
3+
import hudson.Extension;
4+
import hudson.model.AbstractProject;
5+
import hudson.tasks.BuildStepDescriptor;
6+
import hudson.tasks.Builder;
7+
import hudson.tasks.Publisher;
8+
import net.sf.json.JSONObject;
9+
import org.kohsuke.stapler.StaplerRequest;
10+
11+
12+
public class GithubWebhookNotifierPluginBuilder extends Builder {
13+
14+
@Extension
15+
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
16+
17+
private String webhookSecret;
18+
private static DescriptorImpl descriptor=null;
19+
20+
public DescriptorImpl() {
21+
load();
22+
descriptor=this;
23+
}
24+
public DescriptorImpl(String webhookSecret) {
25+
load();
26+
this.webhookSecret=webhookSecret;
27+
descriptor=this;
28+
}
29+
public static DescriptorImpl getDescriptor() {
30+
return descriptor;
31+
}
32+
33+
@Override
34+
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
35+
return true;
36+
}
37+
38+
@Override
39+
public String getDisplayName() {
40+
return "GithubWebhookNotifierPlugin";
41+
}
42+
43+
@Override
44+
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
45+
json = json.getJSONObject("config");
46+
webhookSecret = json.getString("webhookSecret");
47+
save();
48+
return true;
49+
}
50+
51+
public String getWebhookSecret() {
52+
return webhookSecret;
53+
}
54+
55+
public void setWebhookSecret(String webhookSecret) {
56+
this.webhookSecret = webhookSecret;
57+
}
58+
59+
}
60+
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?jelly escape-by-default='true'?>
2+
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define"
3+
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
4+
<f:section title="${%Github Webhook Notifier Plugin}" name="config">
5+
<f:entry title="${%GitHub webhook secret}" field="webhookSecret">
6+
<f:textbox/>
7+
</f:entry>
8+
</f:section>
9+
</j:jelly>

0 commit comments

Comments
 (0)