-
Notifications
You must be signed in to change notification settings - Fork 414
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #167 from kmadel/issue50
JENKINS-27652 - Workflow Support #50
- Loading branch information
Showing
13 changed files
with
499 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
156 changes: 156 additions & 0 deletions
156
src/main/java/jenkins/plugins/slack/workflow/SlackSendStep.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package jenkins.plugins.slack.workflow; | ||
|
||
import hudson.AbortException; | ||
import hudson.Extension; | ||
import hudson.Util; | ||
import hudson.model.TaskListener; | ||
import jenkins.model.Jenkins; | ||
import jenkins.plugins.slack.Messages; | ||
import jenkins.plugins.slack.SlackNotifier; | ||
import jenkins.plugins.slack.SlackService; | ||
import jenkins.plugins.slack.StandardSlackService; | ||
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl; | ||
import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl; | ||
import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution; | ||
import org.jenkinsci.plugins.workflow.steps.StepContextParameter; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
import org.kohsuke.stapler.DataBoundSetter; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.inject.Inject; | ||
|
||
/** | ||
* Workflow step to send a Slack channel notification. | ||
*/ | ||
public class SlackSendStep extends AbstractStepImpl { | ||
|
||
private final @Nonnull String message; | ||
private String color; | ||
private String token; | ||
private String channel; | ||
private String teamDomain; | ||
private boolean failOnError; | ||
|
||
|
||
@Nonnull | ||
public String getMessage() { | ||
return message; | ||
} | ||
|
||
public String getColor() { | ||
return color; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setColor(String color) { | ||
this.color = Util.fixEmpty(color); | ||
} | ||
|
||
public String getToken() { | ||
return token; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setToken(String token) { | ||
this.token = Util.fixEmpty(token); | ||
} | ||
|
||
public String getChannel() { | ||
return channel; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setChannel(String channel) { | ||
this.channel = Util.fixEmpty(channel); | ||
} | ||
|
||
public String getTeamDomain() { | ||
return teamDomain; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setTeamDomain(String teamDomain) { | ||
this.teamDomain = Util.fixEmpty(teamDomain); | ||
} | ||
|
||
public boolean isFailOnError() { | ||
return failOnError; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setFailOnError(boolean failOnError) { | ||
this.failOnError = failOnError; | ||
} | ||
|
||
@DataBoundConstructor | ||
public SlackSendStep(@Nonnull String message) { | ||
this.message = message; | ||
} | ||
|
||
@Extension | ||
public static class DescriptorImpl extends AbstractStepDescriptorImpl { | ||
|
||
public DescriptorImpl() { | ||
super(SlackSendStepExecution.class); | ||
} | ||
|
||
@Override | ||
public String getFunctionName() { | ||
return "slackSend"; | ||
} | ||
|
||
@Override | ||
public String getDisplayName() { | ||
return Messages.SlackSendStepDisplayName(); | ||
} | ||
} | ||
|
||
public static class SlackSendStepExecution extends AbstractSynchronousNonBlockingStepExecution<Void> { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
@Inject | ||
transient SlackSendStep step; | ||
|
||
@StepContextParameter | ||
transient TaskListener listener; | ||
|
||
@Override | ||
protected Void run() throws Exception { | ||
|
||
//default to global config values if not set in step, but allow step to override all global settings | ||
Jenkins jenkins; | ||
//Jenkins.getInstance() may return null, no message sent in that case | ||
try { | ||
jenkins = Jenkins.getInstance(); | ||
} catch (NullPointerException ne) { | ||
listener.error(Messages.NotificationFailedWithException(ne)); | ||
return null; | ||
} | ||
SlackNotifier.DescriptorImpl slackDesc = jenkins.getDescriptorByType(SlackNotifier.DescriptorImpl.class); | ||
String team = step.teamDomain != null ? step.teamDomain : slackDesc.getTeamDomain(); | ||
String token = step.token != null ? step.token : slackDesc.getToken(); | ||
String channel = step.channel != null ? step.channel : slackDesc.getRoom(); | ||
String color = step.color != null ? step.color : ""; | ||
|
||
//placing in console log to simplify testing of retrieving values from global config or from step field; also used for tests | ||
listener.getLogger().println(Messages.SlackSendStepConfig(step.teamDomain == null, step.token == null, step.channel == null, step.color == null)); | ||
|
||
SlackService slackService = getSlackService(team, token, channel); | ||
boolean publishSuccess = slackService.publish(step.message, color); | ||
if (!publishSuccess && step.failOnError) { | ||
throw new AbortException(Messages.NotificationFailed()); | ||
} else if (!publishSuccess) { | ||
listener.error(Messages.NotificationFailed()); | ||
} | ||
return null; | ||
} | ||
|
||
//streamline unit testing | ||
SlackService getSlackService(String team, String token, String channel) { | ||
return new StandardSlackService(team, token, channel); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Localization for config pages | ||
SlackSendStepDisplayName=Send Slack Message | ||
|
||
# Messages to display in the build logs | ||
NotificationFailed=Slack notification failed. See Jenkins logs for details. | ||
NotificationFailedWithException=Slack notification failed with exception: {0} | ||
SlackSendStepConfig=Slack Send Workflow step configured values from global config - teamDomain: {0}, token: {1}, channel: {2}, color: {3} |
24 changes: 24 additions & 0 deletions
24
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/config.jelly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<?jelly escape-by-default='true'?> | ||
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form"> | ||
<f:entry field="message" title="Message"> | ||
<f:textbox/> | ||
</f:entry> | ||
<f:entry field="color" title="Color"> | ||
<f:textbox/> | ||
</f:entry> | ||
<f:advanced> | ||
<f:entry field="channel" title="Channel"> | ||
<f:textbox /> | ||
</f:entry> | ||
<f:entry field="token" title="Integration Token"> | ||
<f:textbox /> | ||
</f:entry> | ||
<f:entry field="teamDomain" title="Team Domain"> | ||
<f:textbox /> | ||
</f:entry> | ||
<f:entry field="failOnError"> | ||
<f:checkbox title="Fail On Error" default="false"/> | ||
</f:entry> | ||
</f:advanced> | ||
</j:jelly> |
4 changes: 4 additions & 0 deletions
4
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/help-channel.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div> | ||
Allows overriding the Slack Plugin channel specified in the global configuration.<br> | ||
<code>slackSend channel: "#channel-name", message: "Build Started: ${env.JOB_NAME} ${env.BUILD_NUMBER}"</code> | ||
</div> |
5 changes: 5 additions & 0 deletions
5
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/help-color.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<div> | ||
An <b>optional</b> value that can either be one of <b>good</b>, <b>warning</b>, <b>danger</b>, or any <b>hex color code</b> (eg. #439FE0). | ||
This value is used to color the border along the left side of the message attachment.<br> | ||
<code>slackSend color: "#439FE0", message: "Build Started: ${env.JOB_NAME} ${env.BUILD_NUMBER}"</code> | ||
</div> |
4 changes: 4 additions & 0 deletions
4
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/help-failOnError.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div> | ||
If set to true, then the step will abort the Workflow run if there is an error sending message.<br> | ||
<code>hipchatSend failOnError: true, message: "Build Started: ${env.JOB_NAME} ${env.BUILD_NUMBER}"</code> | ||
</div> |
8 changes: 8 additions & 0 deletions
8
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/help-message.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<div> | ||
This is the main text in a message attachment, and can contain standard message markup. | ||
The content will automatically collapse if it contains 700+ characters or 5+ linebreaks, and will display a "Show more..." link to expand the content. | ||
Message may include global variables, for example environment and currentBuild variables:<br> | ||
<code> | ||
slackSend "started ${env.JOB_NAME} ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" | ||
</code> | ||
</div> |
3 changes: 3 additions & 0 deletions
3
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/help-teamDomain.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div> | ||
Allows overriding the Slack Plugin Integration Team Domain specified in the global configuration. | ||
</div> |
3 changes: 3 additions & 0 deletions
3
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/help-token.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div> | ||
Allows overriding the Slack Plugin Integration Token specified in the global configuration. | ||
</div> |
10 changes: 10 additions & 0 deletions
10
src/main/resources/jenkins/plugins/slack/workflow/SlackSendStep/help.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<div> | ||
Simple step for sending a Slack message to specified channel.<br> | ||
Use the advanced settings to override the Slack Plugin global configuration to include: <code>token</code> and <code>channel</code>.<br> | ||
Please see the Slack Plugin global configuration for more details on the fields. | ||
|
||
Usage Example:<br> | ||
<code> | ||
slackSend "Build Started - ${env.JOB_NAME} ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" | ||
</code> | ||
</div> |
50 changes: 50 additions & 0 deletions
50
src/test/java/jenkins/plugins/slack/workflow/SlackSendStepIntegrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package jenkins.plugins.slack.workflow; | ||
|
||
|
||
import hudson.model.Result; | ||
import jenkins.plugins.slack.Messages; | ||
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; | ||
import org.jenkinsci.plugins.workflow.job.WorkflowJob; | ||
import org.jenkinsci.plugins.workflow.job.WorkflowRun; | ||
import org.jenkinsci.plugins.workflow.steps.StepConfigTester; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.jvnet.hudson.test.JenkinsRule; | ||
|
||
public class SlackSendStepIntegrationTest { | ||
@Rule | ||
public JenkinsRule jenkinsRule = new JenkinsRule(); | ||
|
||
@Test | ||
public void configRoundTrip() throws Exception { | ||
SlackSendStep step1 = new SlackSendStep("message"); | ||
step1.setColor("good"); | ||
step1.setChannel("#channel"); | ||
step1.setToken("token"); | ||
step1.setTeamDomain("teamDomain"); | ||
step1.setFailOnError(true); | ||
|
||
SlackSendStep step2 = new StepConfigTester(jenkinsRule).configRoundTrip(step1); | ||
jenkinsRule.assertEqualDataBoundBeans(step1, step2); | ||
} | ||
|
||
@Test | ||
public void test_global_config_override() throws Exception { | ||
WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "workflow"); | ||
//just define message | ||
job.setDefinition(new CpsFlowDefinition("slackSend(message: 'message', teamDomain: 'teamDomain', token: 'token', channel: '#channel', color: 'good');", true)); | ||
WorkflowRun run = jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0).get()); | ||
//everything should come from step configuration | ||
jenkinsRule.assertLogContains(Messages.SlackSendStepConfig(false, false, false, false), run); | ||
} | ||
|
||
@Test | ||
public void test_fail_on_error() throws Exception { | ||
WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "workflow"); | ||
//just define message | ||
job.setDefinition(new CpsFlowDefinition("slackSend(message: 'message', teamDomain: 'teamDomain', token: 'token', channel: '#channel', color: 'good', failOnError: true);", true)); | ||
WorkflowRun run = jenkinsRule.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get()); | ||
//everything should come from step configuration | ||
jenkinsRule.assertLogContains(Messages.NotificationFailed(), run); | ||
} | ||
} |
Oops, something went wrong.