Skip to content
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
18 changes: 10 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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'
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -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
55 changes: 29 additions & 26 deletions src/main/java/org/jenkins/plugins/JobListener.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
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<AbstractBuild> {

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();
}

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
Expand All @@ -34,10 +47,11 @@ 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();
NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, "start");
NotificationEvent event = new NotificationEvent(projectName, buildName, buildNumber, buildUrl, buildVars, NotificationEvent.EventType.START);
httpPost(webHookUrl, event);
}

Expand All @@ -53,20 +67,21 @@ 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();
NotificationEvent event = new NotificationEvent(projectName, buildName, buildUrl, buildVars, "");
NotificationEvent event = new NotificationEvent(projectName, buildName, buildNumber, 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);
}
}
Expand All @@ -79,16 +94,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);
}
}
}
25 changes: 23 additions & 2 deletions src/main/java/org/jenkins/plugins/NotificationEvent.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
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, 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;
}

public String projectName;
public String buildName;
public int buildNumber;
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;
}
}
}
32 changes: 32 additions & 0 deletions src/main/java/org/jenkins/plugins/WebHookPipelineExecution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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<Void> {
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().getFullName();
String buildName = run.getDisplayName();
int buildNumber = run.getNumber();
String buildVars = envVars.toString();
NotificationEvent event = new NotificationEvent(projectName, buildName, buildNumber, buildUrl, buildVars, NotificationEvent.EventType.PIPELINE);
JobListener.httpPost(webHookUrl, event);
return null;
}
}
57 changes: 57 additions & 0 deletions src/main/java/org/jenkins/plugins/WebHookPipelineStep.java
Original file line number Diff line number Diff line change
@@ -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<? extends Class<?>> 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";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:entry title="WebHook URL" field="webHookUrl">
<f:textbox />
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
The URL to send the webhook to.
</div>