From 73c577aa2a19d48d4c5430c01a1cc5ea1744cc84 Mon Sep 17 00:00:00 2001 From: RobotHanzo Date: Sun, 28 May 2023 13:39:48 +0800 Subject: [PATCH 1/5] Update dependencies --- build.gradle | 18 ++++++++++-------- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 67c07bf..ca9215c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ plugins { id 'java' - id 'org.jenkins-ci.jpi' version '0.39.0' + id 'org.jenkins-ci.jpi' version '0.49.0' } group 'org.jenkins-ci.plugins' -version '0.3.0' +version '0.4.0' description 'Outbound WebHook for Jenkins build events' jenkinsPlugin { - coreVersion = "2.200" + jenkinsVersion = "2.387.3" displayName = "Outbound WebHook for build events" url = "https://github.com/jenkinsci/outbound-webhook-plugin" gitHubUrl = "https://github.com/jenkinsci/outbound-webhook-plugin" @@ -23,13 +23,15 @@ jenkinsPlugin { } repositories { - maven { url 'http://bits.netbeans.org/maven2' } - maven { url 'http://repo.jenkins-ci.org/releases/' } - jcenter() mavenCentral() + maven { url 'https://repo.jenkins-ci.org/releases/' } + maven { url 'https://bits.netbeans.org/maven2' } } dependencies { - compile 'com.alibaba:fastjson:1.2.71' - compile 'com.squareup.okhttp3:okhttp:4.7.2' + api platform('io.jenkins.tools.bom:bom-2.387.x:2102.v854b_fec19c92') + implementation 'org.jenkins-ci.plugins:structs' + implementation 'org.jenkins-ci.plugins.workflow:workflow-basic-steps' + implementation 'com.alibaba:fastjson:2.0.32' + implementation 'com.squareup.okhttp3:okhttp:4.11.0' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 622ab64..fae0804 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 95ab2a3b2d262913184cde3d974d233a56de0242 Mon Sep 17 00:00:00 2001 From: RobotHanzo Date: Sun, 28 May 2023 16:52:24 +0800 Subject: [PATCH 2/5] Added support for pipeline --- .../java/org/jenkins/plugins/JobListener.java | 50 ++++++++-------- .../jenkins/plugins/NotificationEvent.java | 23 +++++++- .../plugins/WebHookPipelineExecution.java | 31 ++++++++++ .../jenkins/plugins/WebHookPipelineStep.java | 57 +++++++++++++++++++ .../plugins/WebHookPipelineStep/config.jelly | 6 ++ .../WebHookPipelineStep/help-webHookUrl.html | 3 + 6 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java create mode 100644 src/main/java/org/jenkins/plugins/WebHookPipelineStep.java create mode 100644 src/main/resources/org/jenkins/plugins/WebHookPipelineStep/config.jelly create mode 100644 src/main/resources/org/jenkins/plugins/WebHookPipelineStep/help-webHookUrl.html diff --git a/src/main/java/org/jenkins/plugins/JobListener.java b/src/main/java/org/jenkins/plugins/JobListener.java index 76b4894..605a996 100644 --- a/src/main/java/org/jenkins/plugins/JobListener.java +++ b/src/main/java/org/jenkins/plugins/JobListener.java @@ -1,29 +1,43 @@ package org.jenkins.plugins; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; import hudson.Extension; import hudson.model.AbstractBuild; import hudson.model.Result; import hudson.model.TaskListener; import hudson.model.listeners.RunListener; -import com.alibaba.fastjson.JSON; import okhttp3.*; - -import javax.annotation.Nonnull; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + @Extension public class JobListener extends RunListener { private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8"); - private OkHttpClient client; - private static final Logger log = LoggerFactory.getLogger(JobListener.class); + private static final OkHttpClient client = new OkHttpClient(); public JobListener() { super(AbstractBuild.class); - client = new OkHttpClient(); + } + + @Nullable + public static void httpPost(String url, Object object) { + String jsonString = JSON.toJSONString(object, SerializerFeature.WriteEnumUsingToString); + RequestBody body = RequestBody.create(jsonString, JSON_MEDIA_TYPE); + Request request = new Request.Builder().url(url).post(body).build(); + try { + Response response = client.newCall(request).execute(); + log.debug("Invocation of webhook {} successful", url); + if (response.body() != null) log.debug("Response: {}", response.body().string()); + response.close(); + } catch (Exception e) { + log.info("Invocation of webhook {} failed", url, e); + } } @Override @@ -37,7 +51,7 @@ public void onStarted(AbstractBuild build, TaskListener listener) { String projectName = build.getProject().getDisplayName(); String buildName = build.getDisplayName(); String buildVars = build.getBuildVariables().toString(); - NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, "start"); + NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, NotificationEvent.EventType.START); httpPost(webHookUrl, event); } @@ -56,17 +70,17 @@ public void onCompleted(AbstractBuild build, @Nonnull TaskListener listener) { String projectName = build.getProject().getDisplayName(); String buildName = build.getDisplayName(); String buildVars = build.getBuildVariables().toString(); - NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, ""); + NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, null); if (publisher.onSuccess && result.equals(Result.SUCCESS)) { - event.event = "success"; + event.event = NotificationEvent.EventType.SUCCESS; httpPost(webHookUrl, event); } if (publisher.onFailure && result.equals(Result.FAILURE)) { - event.event = "failure"; + event.event = NotificationEvent.EventType.FAILURE; httpPost(webHookUrl, event); } if (publisher.onUnstable && result.equals(Result.UNSTABLE)) { - event.event = "unstable"; + event.event = NotificationEvent.EventType.UNSTABLE; httpPost(webHookUrl, event); } } @@ -79,16 +93,4 @@ private WebHookPublisher GetWebHookPublisher(AbstractBuild build) { } return null; } - - private void httpPost(String url, Object object) { - String jsonString = JSON.toJSONString(object); - RequestBody body = RequestBody.create(JSON_MEDIA_TYPE, jsonString); - Request request = new Request.Builder().url(url).post(body).build(); - try { - Response response = client.newCall(request).execute(); - log.debug("Invocation of webhook {} successful", url); - } catch (Exception e) { - log.info("Invocation of webhook {} failed", url, e); - } - } } diff --git a/src/main/java/org/jenkins/plugins/NotificationEvent.java b/src/main/java/org/jenkins/plugins/NotificationEvent.java index 4d0fe47..383f3ed 100644 --- a/src/main/java/org/jenkins/plugins/NotificationEvent.java +++ b/src/main/java/org/jenkins/plugins/NotificationEvent.java @@ -1,7 +1,7 @@ package org.jenkins.plugins; public class NotificationEvent { - public NotificationEvent(String projectName, String buildName, String buildUrl, String buildVars, String event) { + public NotificationEvent(String projectName, String buildName, String buildUrl, String buildVars, EventType event) { this.projectName = projectName; this.buildName = buildName; this.buildUrl = buildUrl; @@ -13,5 +13,24 @@ public NotificationEvent(String projectName, String buildName, String buildUrl, public String buildName; public String buildUrl; public String buildVars; - public String event; + public EventType event; + + public enum EventType { + START("start"), + SUCCESS("success"), + FAILURE("failure"), + UNSTABLE("unstable"), + PIPELINE("pipeline"); + + private final String value; + + EventType(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } + } } diff --git a/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java new file mode 100644 index 0000000..f9ae672 --- /dev/null +++ b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java @@ -0,0 +1,31 @@ +package org.jenkins.plugins; + +import hudson.EnvVars; +import hudson.model.Run; +import org.jenkinsci.plugins.workflow.steps.StepContext; +import org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution; + +public class WebHookPipelineExecution extends SynchronousNonBlockingStepExecution { + private final WebHookPipelineStep step; + + public WebHookPipelineExecution(WebHookPipelineStep step, StepContext context) { + super(context); + this.step = step; + } + + @Override + protected Void run() throws Exception { + String webHookUrl = this.step.getWebHookUrl(); + Run run = this.getContext().get(Run.class); + EnvVars envVars = this.getContext().get(EnvVars.class); + if (run == null) throw new Exception("Run is null"); + if (envVars == null) throw new Exception("EnvVars is null"); + String buildUrl = run.getAbsoluteUrl(); + String projectName = run.getParent().getDisplayName(); + String buildName = run.getDisplayName(); + String buildVars = envVars.toString(); + NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, NotificationEvent.EventType.START); + JobListener.httpPost(webHookUrl, event); + return null; + } +} diff --git a/src/main/java/org/jenkins/plugins/WebHookPipelineStep.java b/src/main/java/org/jenkins/plugins/WebHookPipelineStep.java new file mode 100644 index 0000000..f9d262f --- /dev/null +++ b/src/main/java/org/jenkins/plugins/WebHookPipelineStep.java @@ -0,0 +1,57 @@ +package org.jenkins.plugins; + +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.EnvVars; +import hudson.Extension; +import hudson.model.Run; +import org.jenkinsci.plugins.workflow.steps.Step; +import org.jenkinsci.plugins.workflow.steps.StepContext; +import org.jenkinsci.plugins.workflow.steps.StepDescriptor; +import org.jenkinsci.plugins.workflow.steps.StepExecution; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.io.Serializable; +import java.util.Set; + +public class WebHookPipelineStep extends Step implements Serializable { + public static final long serialVersionUID = 1L; + private final String webHookUrl; + + @DataBoundConstructor + public WebHookPipelineStep(String webHookUrl) { + this.webHookUrl = webHookUrl; + } + + public String getWebHookUrl() { + return webHookUrl; + } + + @Override + public StepExecution start(StepContext context) { + return new WebHookPipelineExecution(this, context); + } + + + @Extension(optional = true) + public static class DescriptorImpl extends StepDescriptor { + public DescriptorImpl() { + super(); + } + + @Override + public Set> getRequiredContext() { + return Set.of(Run.class, EnvVars.class); + } + + @Override + public String getFunctionName() { + return "webhookSend"; + } + + @NonNull + @Override + public String getDisplayName() { + return "Send a message to a webhook with current build details"; + } + } +} diff --git a/src/main/resources/org/jenkins/plugins/WebHookPipelineStep/config.jelly b/src/main/resources/org/jenkins/plugins/WebHookPipelineStep/config.jelly new file mode 100644 index 0000000..90b7538 --- /dev/null +++ b/src/main/resources/org/jenkins/plugins/WebHookPipelineStep/config.jelly @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/main/resources/org/jenkins/plugins/WebHookPipelineStep/help-webHookUrl.html b/src/main/resources/org/jenkins/plugins/WebHookPipelineStep/help-webHookUrl.html new file mode 100644 index 0000000..3ddfdd1 --- /dev/null +++ b/src/main/resources/org/jenkins/plugins/WebHookPipelineStep/help-webHookUrl.html @@ -0,0 +1,3 @@ +
+ The URL to send the webhook to. +
From 9e665b854373ed474bfb03ef41745005899f1f07 Mon Sep 17 00:00:00 2001 From: RobotHanzo Date: Sun, 28 May 2023 16:53:07 +0800 Subject: [PATCH 3/5] Fixed typo --- src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java index f9ae672..e0a1256 100644 --- a/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java +++ b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java @@ -24,7 +24,7 @@ protected Void run() throws Exception { String projectName = run.getParent().getDisplayName(); String buildName = run.getDisplayName(); String buildVars = envVars.toString(); - NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, NotificationEvent.EventType.START); + NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, NotificationEvent.EventType.PIPELINE); JobListener.httpPost(webHookUrl, event); return null; } From d4aca8224754388739163d03017d664a3a0a411b Mon Sep 17 00:00:00 2001 From: RobotHanzo Date: Sun, 28 May 2023 16:55:14 +0800 Subject: [PATCH 4/5] Added buildNumber in NotificationEvent --- src/main/java/org/jenkins/plugins/JobListener.java | 7 ++++--- src/main/java/org/jenkins/plugins/NotificationEvent.java | 4 +++- .../java/org/jenkins/plugins/WebHookPipelineExecution.java | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jenkins/plugins/JobListener.java b/src/main/java/org/jenkins/plugins/JobListener.java index 605a996..4a42195 100644 --- a/src/main/java/org/jenkins/plugins/JobListener.java +++ b/src/main/java/org/jenkins/plugins/JobListener.java @@ -25,7 +25,6 @@ public JobListener() { super(AbstractBuild.class); } - @Nullable public static void httpPost(String url, Object object) { String jsonString = JSON.toJSONString(object, SerializerFeature.WriteEnumUsingToString); RequestBody body = RequestBody.create(jsonString, JSON_MEDIA_TYPE); @@ -50,8 +49,9 @@ public void onStarted(AbstractBuild build, TaskListener listener) { String buildUrl = build.getAbsoluteUrl(); String projectName = build.getProject().getDisplayName(); String buildName = build.getDisplayName(); + int buildNumber = build.getNumber(); String buildVars = build.getBuildVariables().toString(); - NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, NotificationEvent.EventType.START); + NotificationEvent event = new NotificationEvent(projectName, buildName, buildNumber, buildUrl, buildVars, NotificationEvent.EventType.START); httpPost(webHookUrl, event); } @@ -69,8 +69,9 @@ public void onCompleted(AbstractBuild build, @Nonnull TaskListener listener) { String buildUrl = build.getAbsoluteUrl(); String projectName = build.getProject().getDisplayName(); String buildName = build.getDisplayName(); + int buildNumber = build.getNumber(); String buildVars = build.getBuildVariables().toString(); - NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, null); + NotificationEvent event = new NotificationEvent(projectName, buildName, buildNumber, buildUrl, buildVars, null); if (publisher.onSuccess && result.equals(Result.SUCCESS)) { event.event = NotificationEvent.EventType.SUCCESS; httpPost(webHookUrl, event); diff --git a/src/main/java/org/jenkins/plugins/NotificationEvent.java b/src/main/java/org/jenkins/plugins/NotificationEvent.java index 383f3ed..3e52836 100644 --- a/src/main/java/org/jenkins/plugins/NotificationEvent.java +++ b/src/main/java/org/jenkins/plugins/NotificationEvent.java @@ -1,9 +1,10 @@ package org.jenkins.plugins; public class NotificationEvent { - public NotificationEvent(String projectName, String buildName, String buildUrl, String buildVars, EventType event) { + public NotificationEvent(String projectName, String buildName, int buildNumber, String buildUrl, String buildVars, EventType event) { this.projectName = projectName; this.buildName = buildName; + this.buildNumber = buildNumber; this.buildUrl = buildUrl; this.buildVars = buildVars; this.event = event; @@ -11,6 +12,7 @@ public NotificationEvent(String projectName, String buildName, String buildUrl, public String projectName; public String buildName; + public int buildNumber; public String buildUrl; public String buildVars; public EventType event; diff --git a/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java index e0a1256..ed72fa3 100644 --- a/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java +++ b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java @@ -23,8 +23,9 @@ protected Void run() throws Exception { String buildUrl = run.getAbsoluteUrl(); String projectName = run.getParent().getDisplayName(); String buildName = run.getDisplayName(); + int buildNumber = run.getNumber(); String buildVars = envVars.toString(); - NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, NotificationEvent.EventType.PIPELINE); + NotificationEvent event = new NotificationEvent(projectName, buildName, buildNumber, buildUrl, buildVars, NotificationEvent.EventType.PIPELINE); JobListener.httpPost(webHookUrl, event); return null; } From 6b2b742ae8ebcc840e9e6c49bf792ddc6687b175 Mon Sep 17 00:00:00 2001 From: RobotHanzo Date: Fri, 2 Jun 2023 12:23:38 +0800 Subject: [PATCH 5/5] Use the full for buildName to support multibranch pipeline projects --- src/main/java/org/jenkins/plugins/JobListener.java | 4 ++-- .../java/org/jenkins/plugins/WebHookPipelineExecution.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jenkins/plugins/JobListener.java b/src/main/java/org/jenkins/plugins/JobListener.java index 4a42195..72c7ee1 100644 --- a/src/main/java/org/jenkins/plugins/JobListener.java +++ b/src/main/java/org/jenkins/plugins/JobListener.java @@ -47,7 +47,7 @@ public void onStarted(AbstractBuild build, TaskListener listener) { } String webHookUrl = publisher.webHookUrl; String buildUrl = build.getAbsoluteUrl(); - String projectName = build.getProject().getDisplayName(); + String projectName = build.getProject().getFullName(); String buildName = build.getDisplayName(); int buildNumber = build.getNumber(); String buildVars = build.getBuildVariables().toString(); @@ -67,7 +67,7 @@ public void onCompleted(AbstractBuild build, @Nonnull TaskListener listener) { } String webHookUrl = publisher.webHookUrl; String buildUrl = build.getAbsoluteUrl(); - String projectName = build.getProject().getDisplayName(); + String projectName = build.getProject().getFullName(); String buildName = build.getDisplayName(); int buildNumber = build.getNumber(); String buildVars = build.getBuildVariables().toString(); diff --git a/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java index ed72fa3..56cc7fc 100644 --- a/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java +++ b/src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java @@ -21,7 +21,7 @@ protected Void run() throws Exception { if (run == null) throw new Exception("Run is null"); if (envVars == null) throw new Exception("EnvVars is null"); String buildUrl = run.getAbsoluteUrl(); - String projectName = run.getParent().getDisplayName(); + String projectName = run.getParent().getFullName(); String buildName = run.getDisplayName(); int buildNumber = run.getNumber(); String buildVars = envVars.toString();