1
0
mirror of https://github.com/jenkinsci/mattermost-plugin.git synced 2024-11-24 08:12:36 +02:00

Convert Slack to Mattermost

This commit is contained in:
Jo Vandeginste 2015-10-23 16:35:24 +02:00
parent 76dea74eeb
commit 357b1aebd3
32 changed files with 214 additions and 233 deletions

View File

@ -1,6 +1,10 @@
# Slack plugin for Jenkins - [![Build Status][jenkins-status]][jenkins-builds] [![Slack Signup][slack-badge]][slack-signup]
# Mattermost plugin for Jenkins
Started with a fork of the HipChat plugin:
Based on a fork of the Slack plugin:
https://github.com/jenkinsci/slack-plugin/
Which was a fork of the HipChat plugin:
https://github.com/jlewallen/jenkins-hipchat-plugin
@ -8,8 +12,8 @@ Which was, in turn, a fork of the Campfire plugin.
# Jenkins Instructions
1. Get a Slack account: https://slack.com/
2. Configure the Jenkins integration: https://my.slack.com/services/new/jenkins-ci
1. Set up a Mattermost server
2. Configure an outgoing webhook
3. Install this plugin on your Jenkins server
4. Configure it in your Jenkins job and **add it as a Post-build action**.
@ -22,11 +26,6 @@ Run unit tests
mvn test
Create an HPI file to install in Jenkins (HPI file will be in `target/slack.hpi`).
Create an HPI file to install in Jenkins (HPI file will be in `target/mattermost.hpi`).
mvn package
[jenkins-builds]: https://jenkins.ci.cloudbees.com/job/plugins/job/slack-plugin/
[jenkins-status]: https://jenkins.ci.cloudbees.com/buildStatus/icon?job=plugins/slack-plugin
[slack-badge]: https://jenkins-slack-testing-signup.herokuapp.com/badge.svg
[slack-signup]: https://jenkins-slack-testing-signup.herokuapp.com/

18
pom.xml
View File

@ -17,12 +17,12 @@
<version>1.567</version>
</parent>
<artifactId>slack</artifactId>
<artifactId>mattermost</artifactId>
<packaging>hpi</packaging>
<version>2.0-SNAPSHOT</version>
<name>Slack Notification Plugin</name>
<description>A Build status publisher that notifies channels on a Slack team</description>
<url>http://wiki.jenkins-ci.org/display/JENKINS/Slack+Plugin</url>
<version>1.0-SNAPSHOT</version>
<name>Mattermost Notification Plugin</name>
<description>A Build status publisher that notifies channels on a Mattermost team</description>
<url>http://wiki.jenkins-ci.org/display/JENKINS/Mattermost+Plugin</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -37,9 +37,9 @@
</licenses>
<scm>
<connection>scm:git:ssh://git@github.com/jenkinsci/slack-plugin.git</connection>
<developerConnection>scm:git:ssh://git@github.com/jenkinsci/slack-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/slack-plugin</url>
<connection>scm:git:ssh://git@github.com/jenkinsci/mattermost-plugin.git</connection>
<developerConnection>scm:git:ssh://git@github.com/jenkinsci/mattermost-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/mattermost-plugin</url>
<tag>HEAD</tag>
</scm>
@ -118,7 +118,7 @@
<!--
The developers show up as current maintainers in the Jenkins wiki.
https://wiki.jenkins-ci.org/display/JENKINS/Slack+Plugin
https://wiki.jenkins-ci.org/display/JENKINS/Mattermost+Plugin
The id should be the jenkinsci.org username and not your GitHub username.
-->

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import hudson.EnvVars;
import hudson.model.AbstractBuild;
@ -30,19 +30,19 @@ import static java.util.logging.Level.SEVERE;
@SuppressWarnings("rawtypes")
public class ActiveNotifier implements FineGrainedNotifier {
private static final Logger logger = Logger.getLogger(SlackListener.class.getName());
private static final Logger logger = Logger.getLogger(MattermostListener.class.getName());
SlackNotifier notifier;
MattermostNotifier notifier;
BuildListener listener;
public ActiveNotifier(SlackNotifier notifier, BuildListener listener) {
public ActiveNotifier(MattermostNotifier notifier, BuildListener listener) {
super();
this.notifier = notifier;
this.listener = listener;
}
private SlackService getSlack(AbstractBuild r) {
return notifier.newSlackService(r, listener);
private MattermostService getMattermost(AbstractBuild r) {
return notifier.newMattermostService(r, listener);
}
public void deleted(AbstractBuild r) {
@ -75,9 +75,9 @@ public class ActiveNotifier implements FineGrainedNotifier {
AbstractProject<?, ?> project = build.getProject();
AbstractBuild<?, ?> previousBuild = project.getLastBuild().getPreviousCompletedBuild();
if (previousBuild == null) {
getSlack(build).publish(message, "good");
getMattermost(build).publish(message, "good");
} else {
getSlack(build).publish(message, getBuildColor(previousBuild));
getMattermost(build).publish(message, getBuildColor(previousBuild));
}
}
@ -102,10 +102,10 @@ public class ActiveNotifier implements FineGrainedNotifier {
&& notifier.getNotifyBackToNormal())
|| (result == Result.SUCCESS && notifier.getNotifySuccess())
|| (result == Result.UNSTABLE && notifier.getNotifyUnstable())) {
getSlack(r).publish(getBuildStatusMessage(r, notifier.includeTestSummary(),
getMattermost(r).publish(getBuildStatusMessage(r, notifier.includeTestSummary(),
notifier.includeCustomMessage()), getBuildColor(r));
if (notifier.getShowCommitList()) {
getSlack(r).publish(getCommitList(r), getBuildColor(r));
getMattermost(r).publish(getCommitList(r), getBuildColor(r));
}
}
}
@ -206,10 +206,10 @@ public class ActiveNotifier implements FineGrainedNotifier {
public static class MessageBuilder {
private StringBuffer message;
private SlackNotifier notifier;
private MattermostNotifier notifier;
private AbstractBuild build;
public MessageBuilder(SlackNotifier notifier, AbstractBuild build) {
public MessageBuilder(MattermostNotifier notifier, AbstractBuild build) {
this.notifier = notifier;
this.message = new StringBuffer();
this.build = build;

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import hudson.model.AbstractBuild;

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import hudson.model.AbstractBuild;

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import hudson.Extension;
import hudson.model.AbstractBuild;
@ -14,11 +14,11 @@ import java.util.logging.Logger;
@Extension
@SuppressWarnings("rawtypes")
public class SlackListener extends RunListener<AbstractBuild> {
public class MattermostListener extends RunListener<AbstractBuild> {
private static final Logger logger = Logger.getLogger(SlackListener.class.getName());
private static final Logger logger = Logger.getLogger(MattermostListener.class.getName());
public SlackListener() {
public MattermostListener() {
super(AbstractBuild.class);
}
@ -50,8 +50,8 @@ public class SlackListener extends RunListener<AbstractBuild> {
FineGrainedNotifier getNotifier(AbstractProject project, TaskListener listener) {
Map<Descriptor<Publisher>, Publisher> map = project.getPublishersList().toMap();
for (Publisher publisher : map.values()) {
if (publisher instanceof SlackNotifier) {
return new ActiveNotifier((SlackNotifier) publisher, (BuildListener)listener);
if (publisher instanceof MattermostNotifier) {
return new ActiveNotifier((MattermostNotifier) publisher, (BuildListener)listener);
}
}
return new DisabledNotifier();

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import hudson.EnvVars;
import hudson.Extension;
@ -23,11 +23,11 @@ import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;
public class SlackNotifier extends Notifier {
public class MattermostNotifier extends Notifier {
private static final Logger logger = Logger.getLogger(SlackNotifier.class.getName());
private static final Logger logger = Logger.getLogger(MattermostNotifier.class.getName());
private String teamDomain;
private String host;
private String authToken;
private String buildServerUrl;
private String room;
@ -50,8 +50,8 @@ public class SlackNotifier extends Notifier {
return (DescriptorImpl) super.getDescriptor();
}
public String getTeamDomain() {
return teamDomain;
public String getHost() {
return host;
}
public String getRoom() {
@ -125,13 +125,13 @@ public class SlackNotifier extends Notifier {
}
@DataBoundConstructor
public SlackNotifier(final String teamDomain, final String authToken, final String room, final String buildServerUrl,
public MattermostNotifier(final String host, final String authToken, final String room, final String buildServerUrl,
final String sendAs, final boolean startNotification, final boolean notifyAborted, final boolean notifyFailure,
final boolean notifyNotBuilt, final boolean notifySuccess, final boolean notifyUnstable, final boolean notifyBackToNormal,
final boolean notifyRepeatedFailure, final boolean includeTestSummary, final boolean showCommitList,
boolean includeCustomMessage, String customMessage) {
super();
this.teamDomain = teamDomain;
this.host = host;
this.authToken = authToken;
this.buildServerUrl = buildServerUrl;
this.room = room;
@ -154,10 +154,10 @@ public class SlackNotifier extends Notifier {
return BuildStepMonitor.NONE;
}
public SlackService newSlackService(AbstractBuild r, BuildListener listener) {
String teamDomain = this.teamDomain;
if (StringUtils.isEmpty(teamDomain)) {
teamDomain = getDescriptor().getTeamDomain();
public MattermostService newMattermostService(AbstractBuild r, BuildListener listener) {
String host = this.host;
if (StringUtils.isEmpty(host)) {
host = getDescriptor().getHost();
}
String authToken = this.authToken;
if (StringUtils.isEmpty(authToken)) {
@ -175,11 +175,11 @@ public class SlackNotifier extends Notifier {
listener.getLogger().println("Error retrieving environment vars: " + e.getMessage());
env = new EnvVars();
}
teamDomain = env.expand(teamDomain);
host = env.expand(host);
authToken = env.expand(authToken);
room = env.expand(room);
return new StandardSlackService(teamDomain, authToken, room);
return new StandardMattermostService(host, authToken, room);
}
@Override
@ -192,9 +192,9 @@ public class SlackNotifier extends Notifier {
if (startNotification) {
Map<Descriptor<Publisher>, Publisher> map = build.getProject().getPublishersList().toMap();
for (Publisher publisher : map.values()) {
if (publisher instanceof SlackNotifier) {
if (publisher instanceof MattermostNotifier) {
logger.info("Invoking Started...");
new ActiveNotifier((SlackNotifier) publisher, listener).started(build);
new ActiveNotifier((MattermostNotifier) publisher, listener).started(build);
}
}
}
@ -204,7 +204,7 @@ public class SlackNotifier extends Notifier {
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
private String teamDomain;
private String host;
private String token;
private String room;
private String buildServerUrl;
@ -214,8 +214,8 @@ public class SlackNotifier extends Notifier {
load();
}
public String getTeamDomain() {
return teamDomain;
public String getHost() {
return host;
}
public String getToken() {
@ -245,34 +245,34 @@ public class SlackNotifier extends Notifier {
}
@Override
public SlackNotifier newInstance(StaplerRequest sr, JSONObject json) {
String teamDomain = sr.getParameter("slackTeamDomain");
String token = sr.getParameter("slackToken");
String room = sr.getParameter("slackRoom");
boolean startNotification = "true".equals(sr.getParameter("slackStartNotification"));
boolean notifySuccess = "true".equals(sr.getParameter("slackNotifySuccess"));
boolean notifyAborted = "true".equals(sr.getParameter("slackNotifyAborted"));
boolean notifyNotBuilt = "true".equals(sr.getParameter("slackNotifyNotBuilt"));
boolean notifyUnstable = "true".equals(sr.getParameter("slackNotifyUnstable"));
boolean notifyFailure = "true".equals(sr.getParameter("slackNotifyFailure"));
boolean notifyBackToNormal = "true".equals(sr.getParameter("slackNotifyBackToNormal"));
boolean notifyRepeatedFailure = "true".equals(sr.getParameter("slackNotifyRepeatedFailure"));
public MattermostNotifier newInstance(StaplerRequest sr, JSONObject json) {
String host = sr.getParameter("mattermostHost");
String token = sr.getParameter("mattermostToken");
String room = sr.getParameter("mattermostRoom");
boolean startNotification = "true".equals(sr.getParameter("mattermostStartNotification"));
boolean notifySuccess = "true".equals(sr.getParameter("mattermostNotifySuccess"));
boolean notifyAborted = "true".equals(sr.getParameter("mattermostNotifyAborted"));
boolean notifyNotBuilt = "true".equals(sr.getParameter("mattermostNotifyNotBuilt"));
boolean notifyUnstable = "true".equals(sr.getParameter("mattermostNotifyUnstable"));
boolean notifyFailure = "true".equals(sr.getParameter("mattermostNotifyFailure"));
boolean notifyBackToNormal = "true".equals(sr.getParameter("mattermostNotifyBackToNormal"));
boolean notifyRepeatedFailure = "true".equals(sr.getParameter("mattermostNotifyRepeatedFailure"));
boolean includeTestSummary = "true".equals(sr.getParameter("includeTestSummary"));
boolean showCommitList = "true".equals(sr.getParameter("slackShowCommitList"));
boolean showCommitList = "true".equals(sr.getParameter("mattermostShowCommitList"));
boolean includeCustomMessage = "on".equals(sr.getParameter("includeCustomMessage"));
String customMessage = sr.getParameter("customMessage");
return new SlackNotifier(teamDomain, token, room, buildServerUrl, sendAs, startNotification, notifyAborted,
return new MattermostNotifier(host, token, room, buildServerUrl, sendAs, startNotification, notifyAborted,
notifyFailure, notifyNotBuilt, notifySuccess, notifyUnstable, notifyBackToNormal, notifyRepeatedFailure,
includeTestSummary, showCommitList, includeCustomMessage, customMessage);
}
@Override
public boolean configure(StaplerRequest sr, JSONObject formData) throws FormException {
teamDomain = sr.getParameter("slackTeamDomain");
token = sr.getParameter("slackToken");
room = sr.getParameter("slackRoom");
buildServerUrl = sr.getParameter("slackBuildServerUrl");
sendAs = sr.getParameter("slackSendAs");
host = sr.getParameter("mattermostHost");
token = sr.getParameter("mattermostToken");
room = sr.getParameter("mattermostRoom");
buildServerUrl = sr.getParameter("mattermostBuildServerUrl");
sendAs = sr.getParameter("mattermostSendAs");
if(buildServerUrl == null || buildServerUrl == "") {
JenkinsLocationConfiguration jenkinsConfig = new JenkinsLocationConfiguration();
buildServerUrl = jenkinsConfig.getUrl();
@ -284,23 +284,23 @@ public class SlackNotifier extends Notifier {
return super.configure(sr, formData);
}
SlackService getSlackService(final String teamDomain, final String authToken, final String room) {
return new StandardSlackService(teamDomain, authToken, room);
MattermostService getMattermostService(final String host, final String authToken, final String room) {
return new StandardMattermostService(host, authToken, room);
}
@Override
public String getDisplayName() {
return "Slack Notifications";
return "Mattermost Notifications";
}
public FormValidation doTestConnection(@QueryParameter("slackTeamDomain") final String teamDomain,
@QueryParameter("slackToken") final String authToken,
@QueryParameter("slackRoom") final String room,
@QueryParameter("slackBuildServerUrl") final String buildServerUrl) throws FormException {
public FormValidation doTestConnection(@QueryParameter("mattermostHost") final String host,
@QueryParameter("mattermostToken") final String authToken,
@QueryParameter("mattermostRoom") final String room,
@QueryParameter("mattermostBuildServerUrl") final String buildServerUrl) throws FormException {
try {
String targetDomain = teamDomain;
String targetDomain = host;
if (StringUtils.isEmpty(targetDomain)) {
targetDomain = this.teamDomain;
targetDomain = this.host;
}
String targetToken = authToken;
if (StringUtils.isEmpty(targetToken)) {
@ -314,9 +314,9 @@ public class SlackNotifier extends Notifier {
if (StringUtils.isEmpty(targetBuildServerUrl)) {
targetBuildServerUrl = this.buildServerUrl;
}
SlackService testSlackService = getSlackService(targetDomain, targetToken, targetRoom);
String message = "Slack/Jenkins plugin: you're all set on " + targetBuildServerUrl;
boolean success = testSlackService.publish(message, "good");
MattermostService testMattermostService = getMattermostService(targetDomain, targetToken, targetRoom);
String message = "Mattermost/Jenkins plugin: you're all set on " + targetBuildServerUrl;
boolean success = testMattermostService.publish(message, "good");
return success ? FormValidation.ok("Success") : FormValidation.error("Failure");
} catch (Exception e) {
return FormValidation.error("Client error : " + e.getMessage());

View File

@ -1,6 +1,6 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
public interface SlackService {
public interface MattermostService {
boolean publish(String message);
boolean publish(String message, String color);

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
@ -15,18 +15,17 @@ import hudson.ProxyConfiguration;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
public class StandardSlackService implements SlackService {
public class StandardMattermostService implements MattermostService {
private static final Logger logger = Logger.getLogger(StandardSlackService.class.getName());
private static final Logger logger = Logger.getLogger(StandardMattermostService.class.getName());
private String host = "slack.com";
private String teamDomain;
private String host;
private String token;
private String[] roomIds;
public StandardSlackService(String teamDomain, String token, String roomId) {
public StandardMattermostService(String host, String token, String roomId) {
super();
this.teamDomain = teamDomain;
this.host = host;
this.token = token;
this.roomIds = roomId.split("[,; ]+");
}
@ -38,45 +37,28 @@ public class StandardSlackService implements SlackService {
public boolean publish(String message, String color) {
boolean result = true;
for (String roomId : roomIds) {
String url = "https://" + teamDomain + "." + host + "/services/hooks/jenkins-ci?token=" + token;
logger.info("Posting: to " + roomId + " on " + teamDomain + " using " + url +": " + message + " " + color);
String url = "https://" + host + "/hooks/" + token;
logger.info("Posting: to " + roomId + " on " + " using " + url +": " + message + " " + color);
HttpClient client = getHttpClient();
PostMethod post = new PostMethod(url);
JSONObject json = new JSONObject();
try {
JSONObject field = new JSONObject();
field.put("short", false);
field.put("value", message);
JSONArray fields = new JSONArray();
fields.put(field);
JSONObject attachment = new JSONObject();
attachment.put("fallback", message);
attachment.put("color", color);
attachment.put("fields", fields);
JSONArray mrkdwn = new JSONArray();
mrkdwn.put("pretext");
mrkdwn.put("text");
mrkdwn.put("fields");
attachment.put("mrkdwn_in", mrkdwn);
JSONArray attachments = new JSONArray();
attachments.put(attachment);
json.put("channel", roomId);
json.put("attachments", attachments);
json.put("text", message);
json.put("username", "jenkins");
json.put("icon_emoji", ":ghost:");
post.addParameter("payload", json.toString());
post.getParams().setContentCharset("UTF-8");
int responseCode = client.executeMethod(post);
String response = post.getResponseBodyAsString();
if(responseCode != HttpStatus.SC_OK) {
logger.log(Level.WARNING, "Slack post may have failed. Response: " + response);
logger.log(Level.WARNING, "Mattermost post may have failed. Response: " + response);
result = false;
}
} catch (Exception e) {
logger.log(Level.WARNING, "Error posting to Slack", e);
logger.log(Level.WARNING, "Error posting to Mattermost", e);
result = false;
} finally {
logger.info("Posting succeeded");

View File

@ -3,5 +3,5 @@
Since we don't really have anything dynamic here, let's just use static HTML.
-->
<div>
This plugin is a Slack notifier that can publish build status to Slack channels.
This plugin is a Mattermost notifier that can publish build status to Mattermost channels.
</div>

View File

@ -1,36 +1,36 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry title="Notify Build Start">
<f:checkbox name="slackStartNotification" value="true" checked="${instance.getStartNotification()}"/>
<f:checkbox name="mattermostStartNotification" value="true" checked="${instance.getStartNotification()}"/>
</f:entry>
<f:entry title="Notify Aborted">
<f:checkbox name="slackNotifyAborted" value="true" checked="${instance.getNotifyAborted()}"/>
<f:checkbox name="mattermostNotifyAborted" value="true" checked="${instance.getNotifyAborted()}"/>
</f:entry>
<f:entry title="Notify Failure">
<f:checkbox name="slackNotifyFailure" value="true" checked="${instance.getNotifyFailure()}"/>
<f:checkbox name="mattermostNotifyFailure" value="true" checked="${instance.getNotifyFailure()}"/>
</f:entry>
<f:entry title="Notify Not Built">
<f:checkbox name="slackNotifyNotBuilt" value="true" checked="${instance.getNotifyNotBuilt()}"/>
<f:checkbox name="mattermostNotifyNotBuilt" value="true" checked="${instance.getNotifyNotBuilt()}"/>
</f:entry>
<f:entry title="Notify Success">
<f:checkbox name="slackNotifySuccess" value="true" checked="${instance.getNotifySuccess()}"/>
<f:checkbox name="mattermostNotifySuccess" value="true" checked="${instance.getNotifySuccess()}"/>
</f:entry>
<f:entry title="Notify Unstable">
<f:checkbox name="slackNotifyUnstable" value="true" checked="${instance.getNotifyUnstable()}"/>
<f:checkbox name="mattermostNotifyUnstable" value="true" checked="${instance.getNotifyUnstable()}"/>
</f:entry>
<f:entry title="Notify Back To Normal">
<f:checkbox name="slackNotifyBackToNormal" value="true" checked="${instance.getNotifyBackToNormal()}"/>
<f:checkbox name="mattermostNotifyBackToNormal" value="true" checked="${instance.getNotifyBackToNormal()}"/>
</f:entry>
<f:advanced>
<f:entry title="Notify Repeated Failure">
<f:checkbox name="slackNotifyRepeatedFailure" value="true"
<f:checkbox name="mattermostNotifyRepeatedFailure" value="true"
checked="${instance.getNotifyRepeatedFailure()}"/>
</f:entry>
<f:entry title="Include Test Summary">
@ -38,28 +38,28 @@
</f:entry>
<f:optionalBlock name="includeCustomMessage" title="Include Custom Message" checked="${instance.includeCustomMessage()}">
<f:entry title="Custom Message" help="${rootURL}/plugin/slack/help-projectConfig-slackCustomMessage.html">
<f:entry title="Custom Message" help="${rootURL}/plugin/mattermost/help-projectConfig-mattermostCustomMessage.html">
<f:textarea name="customMessage" value="${instance.getCustomMessage()}"/>
</f:entry>
</f:optionalBlock>
<f:entry title="Show Commit List with Titles and Authors">
<f:checkbox name="slackShowCommitList" value="true" checked="${instance.getShowCommitList()}"/>
<f:checkbox name="mattermostShowCommitList" value="true" checked="${instance.getShowCommitList()}"/>
</f:entry>
<f:entry title="Team Domain" help="${rootURL}/plugin/slack/help-projectConfig-slackTeamDomain.html">
<f:textbox name="slackTeamDomain" value="${instance.getTeamDomain()}"/>
<f:entry title="Host" help="${rootURL}/plugin/mattermost/help-projectConfig-mattermostHost.html">
<f:textbox name="mattermostHost" value="${instance.getHost()}"/>
</f:entry>
<f:entry title="Integration Token" help="${rootURL}/plugin/slack/help-projectConfig-slackToken.html">
<f:textbox name="slackToken" value="${instance.getAuthToken()}"/>
<f:entry title="Integration Token" help="${rootURL}/plugin/mattermost/help-projectConfig-mattermostToken.html">
<f:textbox name="mattermostToken" value="${instance.getAuthToken()}"/>
</f:entry>
<f:entry title="Project Channel" help="${rootURL}/plugin/slack/help-projectConfig-slackRoom.html">
<f:textbox name="slackRoom" value="${instance.getRoom()}"/>
<f:entry title="Project Channel" help="${rootURL}/plugin/mattermost/help-projectConfig-mattermostRoom.html">
<f:textbox name="mattermostRoom" value="${instance.getRoom()}"/>
</f:entry>
<f:validateButton
title="${%Test Connection}" progress="${%Testing...}"
method="testConnection" with="slackTeamDomain,slackToken,slackRoom"/>
method="testConnection" with="mattermostHost,mattermostToken,mattermostRoom"/>
</f:advanced>
</j:jelly>

View File

@ -0,0 +1,31 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<!--
This Jelly script is used to produce the global configuration option.
Hudson uses a set of tag libraries to provide uniformity in forms.
To determine where this tag is defined, first check the namespace URI,
and then look under $HUDSON/views/. For example, <f:section> is defined
in $HUDSON/views/lib/form/section.jelly.
It's also often useful to just check other similar scripts to see what
tags they use. Views are always organized according to its owner class,
so it should be straightforward to find them.
-->
<f:section title="Global Mattermost Notifier Settings" name="mattermost">
<f:entry title="Host" help="${rootURL}/plugin/mattermost/help-globalConfig-mattermostHost.html">
<f:textbox field="host" name="mattermostHost" value="${descriptor.getHost()}" />
</f:entry>
<f:entry title="Integration Token" help="${rootURL}/plugin/mattermost/help-globalConfig-mattermostToken.html">
<f:textbox field="token" name="mattermostToken" value="${descriptor.getToken()}" />
</f:entry>
<f:entry title="Channel" help="${rootURL}/plugin/mattermost/help-globalConfig-mattermostRoom.html">
<f:textbox field="room" name="mattermostRoom" value="${descriptor.getRoom()}" />
</f:entry>
<f:entry title="Build Server URL" help="${rootURL}/plugin/mattermost/help-globalConfig-mattermostBuildServerUrl.html">
<f:textbox field="buildServerUrl" name="mattermostBuildServerUrl" value="${descriptor.getBuildServerUrl()}" />
</f:entry>
<f:validateButton
title="${%Test Connection}" progress="${%Testing...}"
method="testConnection" with="mattermostHost,mattermostToken,mattermostRoom,mattermostBuildServerUrl" />
</f:section>
</j:jelly>

View File

@ -1,31 +0,0 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<!--
This Jelly script is used to produce the global configuration option.
Hudson uses a set of tag libraries to provide uniformity in forms.
To determine where this tag is defined, first check the namespace URI,
and then look under $HUDSON/views/. For example, <f:section> is defined
in $HUDSON/views/lib/form/section.jelly.
It's also often useful to just check other similar scripts to see what
tags they use. Views are always organized according to its owner class,
so it should be straightforward to find them.
-->
<f:section title="Global Slack Notifier Settings" name="slack">
<f:entry title="Team Domain" help="${rootURL}/plugin/slack/help-globalConfig-slackTeamDomain.html">
<f:textbox field="teamDomain" name="slackTeamDomain" value="${descriptor.getTeamDomain()}" />
</f:entry>
<f:entry title="Integration Token" help="${rootURL}/plugin/slack/help-globalConfig-slackToken.html">
<f:textbox field="token" name="slackToken" value="${descriptor.getToken()}" />
</f:entry>
<f:entry title="Channel" help="${rootURL}/plugin/slack/help-globalConfig-slackRoom.html">
<f:textbox field="room" name="slackRoom" value="${descriptor.getRoom()}" />
</f:entry>
<f:entry title="Build Server URL" help="${rootURL}/plugin/slack/help-globalConfig-slackBuildServerUrl.html">
<f:textbox field="buildServerUrl" name="slackBuildServerUrl" value="${descriptor.getBuildServerUrl()}" />
</f:entry>
<f:validateButton
title="${%Test Connection}" progress="${%Testing...}"
method="testConnection" with="slackTeamDomain,slackToken,slackRoom,slackBuildServerUrl" />
</f:section>
</j:jelly>

View File

@ -1,5 +1,5 @@
<div>
<p>Optionally specify the URL for your Server installation, e.g. http://yourhost.yourdomain/hudson/.
This value will be used to generate links back to your Server from Slack and should end with a forward slash.</p>
This value will be used to generate links back to your Server from Mattermost and should end with a forward slash.</p>
<p>This is necessary because the Server cannot reliably detect such a URL from within itself.</p>
</div>

View File

@ -0,0 +1,4 @@
<div>
<p>Your Mattermost host.</p>
<p>It is possible to override this setting per project.</p>
</div>

View File

@ -0,0 +1,4 @@
<div>
<p>The integration token to be used to send notifications to Mattermost. You can copy this from the settings page within Mattermost.</p>
<p>It is possible to override this setting per project.</p>
</div>

View File

@ -1,4 +0,0 @@
<div>
<p>Your team's Slack subdomain. If you sign in to slack at https://example.slack.com/, your subdomain is 'example'.</p>
<p>It is possible to override this setting per project.</p>
</div>

View File

@ -1,4 +0,0 @@
<div>
<p>The integration token to be used to send notifications to Slack. You can copy this from the settings page within Slack.</p>
<p>It is possible to override this setting per project.</p>
</div>

View File

@ -0,0 +1,4 @@
<div>
<p>Your Mattermost host.</p>
<p>This overrides the global setting.</p>
</div>

View File

@ -0,0 +1,4 @@
<div>
<p>The integration token to be used to send notifications to Mattermost. You can copy this from the settings page within Mattermost.</p>
<p>This overrides the global setting.</p>
</div>

View File

@ -1,4 +0,0 @@
<div>
<p>Your team's Slack subdomain. If you sign in to slack at https://example.slack.com/, your subdomain is 'example'.</p>
<p>This overrides the global setting.</p>
</div>

View File

@ -1,4 +0,0 @@
<div>
<p>The integration token to be used to send notifications to Slack. You can copy this from the settings page within Slack.</p>
<p>This overrides the global setting.</p>
</div>

View File

@ -1,4 +1,4 @@
<div>
<p>This will test notifications to Slack using above team, room and token settings <b>exclusively</b>, so <u>any missing information will make the test fail</u>.</p>
<p>This will test notifications to Mattermost using above team, room and token settings <b>exclusively</b>, so <u>any missing information will make the test fail</u>.</p>
<p>You can test a specific setup here, but it is recommended you configure common parameters in Jenkins general configuration, so you won't have to repeat/update any job configuration if your usual token, room or team name changes.</p>
</div>

View File

@ -1,4 +1,4 @@
<div>
Send build notifications to a Slack channel.<br />
The Slack notifier is configured globally, but you can customize the channel names per-project.
Send build notifications to a Mattermost channel.<br />
The Mattermost notifier is configured globally, but you can customize the channel names per-project.
</div>

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;

View File

@ -1,32 +1,32 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
public class SlackNotifierStub extends SlackNotifier {
public class MattermostNotifierStub extends MattermostNotifier {
public SlackNotifierStub(String teamDomain, String authToken, String room, String buildServerUrl,
public MattermostNotifierStub(String host, String authToken, String room, String buildServerUrl,
String sendAs, boolean startNotification, boolean notifyAborted, boolean notifyFailure,
boolean notifyNotBuilt, boolean notifySuccess, boolean notifyUnstable, boolean notifyBackToNormal,
boolean notifyRepeatedFailure, boolean includeTestSummary, boolean showCommitList,
boolean includeCustomMessage, String customMessage) {
super(teamDomain, authToken, room, buildServerUrl, sendAs, startNotification, notifyAborted, notifyFailure,
super(host, authToken, room, buildServerUrl, sendAs, startNotification, notifyAborted, notifyFailure,
notifyNotBuilt, notifySuccess, notifyUnstable, notifyBackToNormal, notifyRepeatedFailure,
includeTestSummary, showCommitList, includeCustomMessage, customMessage);
}
public static class DescriptorImplStub extends SlackNotifier.DescriptorImpl {
public static class DescriptorImplStub extends MattermostNotifier.DescriptorImpl {
private SlackService slackService;
private MattermostService mattermostService;
@Override
public synchronized void load() {
}
@Override
SlackService getSlackService(final String teamDomain, final String authToken, final String room) {
return slackService;
MattermostService getMattermostService(final String host, final String authToken, final String room) {
return mattermostService;
}
public void setSlackService(SlackService slackService) {
this.slackService = slackService;
public void setMattermostService(MattermostService mattermostService) {
this.mattermostService = mattermostService;
}
}
}

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import hudson.model.Descriptor;
import hudson.util.FormValidation;
@ -12,21 +12,21 @@ import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
public class SlackNotifierTest extends TestCase {
public class MattermostNotifierTest extends TestCase {
private SlackNotifierStub.DescriptorImplStub descriptor;
private SlackServiceStub slackServiceStub;
private MattermostNotifierStub.DescriptorImplStub descriptor;
private MattermostServiceStub mattermostServiceStub;
private boolean response;
private FormValidation.Kind expectedResult;
@Before
@Override
public void setUp() {
descriptor = new SlackNotifierStub.DescriptorImplStub();
descriptor = new MattermostNotifierStub.DescriptorImplStub();
}
public SlackNotifierTest(SlackServiceStub slackServiceStub, boolean response, FormValidation.Kind expectedResult) {
this.slackServiceStub = slackServiceStub;
public MattermostNotifierTest(MattermostServiceStub mattermostServiceStub, boolean response, FormValidation.Kind expectedResult) {
this.mattermostServiceStub = mattermostServiceStub;
this.response = response;
this.expectedResult = expectedResult;
}
@ -34,20 +34,20 @@ public class SlackNotifierTest extends TestCase {
@Parameterized.Parameters
public static Collection businessTypeKeys() {
return Arrays.asList(new Object[][]{
{new SlackServiceStub(), true, FormValidation.Kind.OK},
{new SlackServiceStub(), false, FormValidation.Kind.ERROR},
{new MattermostServiceStub(), true, FormValidation.Kind.OK},
{new MattermostServiceStub(), false, FormValidation.Kind.ERROR},
{null, false, FormValidation.Kind.ERROR}
});
}
@Test
public void testDoTestConnection() {
if (slackServiceStub != null) {
slackServiceStub.setResponse(response);
if (mattermostServiceStub != null) {
mattermostServiceStub.setResponse(response);
}
descriptor.setSlackService(slackServiceStub);
descriptor.setMattermostService(mattermostServiceStub);
try {
FormValidation result = descriptor.doTestConnection("teamDomain", "authToken", "room", "buildServerUrl");
FormValidation result = descriptor.doTestConnection("host", "authToken", "room", "buildServerUrl");
assertEquals(result.kind, expectedResult);
} catch (Descriptor.FormException e) {
e.printStackTrace();
@ -55,7 +55,7 @@ public class SlackNotifierTest extends TestCase {
}
}
public static class SlackServiceStub implements SlackService {
public static class MattermostServiceStub implements MattermostService {
private boolean response;

View File

@ -1,11 +1,11 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
public class StandardSlackServiceStub extends StandardSlackService {
public class StandardMattermostServiceStub extends StandardMattermostService {
private HttpClientStub httpClientStub;
public StandardSlackServiceStub(String teamDomain, String token, String roomId) {
super(teamDomain, token, roomId);
public StandardMattermostServiceStub(String host, String token, String roomId) {
super(host, token, roomId);
}
@Override

View File

@ -1,4 +1,4 @@
package jenkins.plugins.slack;
package jenkins.plugins.mattermost;
import org.apache.http.HttpStatus;
import org.junit.Test;
@ -7,14 +7,14 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class StandardSlackServiceTest {
public class StandardMattermostServiceTest {
/**
* Publish should generally not rethrow exceptions, or it will cause a build job to fail at end.
*/
@Test
public void publishWithBadHostShouldNotRethrowExceptions() {
StandardSlackService service = new StandardSlackService("foo", "token", "#general");
StandardMattermostService service = new StandardMattermostService("foo", "token", "#general");
service.setHost("hostvaluethatwillcausepublishtofail");
service.publish("message");
}
@ -23,8 +23,8 @@ public class StandardSlackServiceTest {
* Use a valid host, but an invalid team domain
*/
@Test
public void invalidTeamDomainShouldFail() {
StandardSlackService service = new StandardSlackService("my", "token", "#general");
public void invalidHostShouldFail() {
StandardMattermostService service = new StandardMattermostService("my", "token", "#general");
service.publish("message");
}
@ -33,13 +33,13 @@ public class StandardSlackServiceTest {
*/
@Test
public void invalidTokenShouldFail() {
StandardSlackService service = new StandardSlackService("tinyspeck", "token", "#general");
StandardMattermostService service = new StandardMattermostService("tinyspeck", "token", "#general");
service.publish("message");
}
@Test
public void publishToASingleRoomSendsASingleMessage() {
StandardSlackServiceStub service = new StandardSlackServiceStub("domain", "token", "#room1");
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "token", "#room1");
HttpClientStub httpClientStub = new HttpClientStub();
service.setHttpClient(httpClientStub);
service.publish("message");
@ -48,7 +48,7 @@ public class StandardSlackServiceTest {
@Test
public void publishToMultipleRoomsSendsAMessageToEveryRoom() {
StandardSlackServiceStub service = new StandardSlackServiceStub("domain", "token", "#room1,#room2,#room3");
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "token", "#room1,#room2,#room3");
HttpClientStub httpClientStub = new HttpClientStub();
service.setHttpClient(httpClientStub);
service.publish("message");
@ -57,7 +57,7 @@ public class StandardSlackServiceTest {
@Test
public void successfulPublishToASingleRoomReturnsTrue() {
StandardSlackServiceStub service = new StandardSlackServiceStub("domain", "token", "#room1");
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "token", "#room1");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
@ -66,7 +66,7 @@ public class StandardSlackServiceTest {
@Test
public void successfulPublishToMultipleRoomsReturnsTrue() {
StandardSlackServiceStub service = new StandardSlackServiceStub("domain", "token", "#room1,#room2,#room3");
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "token", "#room1,#room2,#room3");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
@ -75,7 +75,7 @@ public class StandardSlackServiceTest {
@Test
public void failedPublishToASingleRoomReturnsFalse() {
StandardSlackServiceStub service = new StandardSlackServiceStub("domain", "token", "#room1");
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "token", "#room1");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_NOT_FOUND);
service.setHttpClient(httpClientStub);
@ -84,7 +84,7 @@ public class StandardSlackServiceTest {
@Test
public void singleFailedPublishToMultipleRoomsReturnsFalse() {
StandardSlackServiceStub service = new StandardSlackServiceStub("domain", "token", "#room1,#room2,#room3");
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "token", "#room1,#room2,#room3");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setFailAlternateResponses(true);
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
@ -94,7 +94,7 @@ public class StandardSlackServiceTest {
@Test
public void publishToEmptyRoomReturnsTrue() {
StandardSlackServiceStub service = new StandardSlackServiceStub("domain", "token", "");
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "token", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);