Skip to content
This repository was archived by the owner on Feb 13, 2020. It is now read-only.

Commit

Permalink
Add BuildWrapper to notify when the build starts/ends
Browse files Browse the repository at this point in the history
I remove a notifier field 'notifyWhenSuccess' because I want you to use a buildWrapper instead of it.
So the plugin since this version is not compatible with previous version.
  • Loading branch information
ikikko committed May 5, 2014
1 parent 9fd1dc4 commit 0039b8d
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 164 deletions.
106 changes: 106 additions & 0 deletions src/main/java/org/jenkinsci/plugins/typetalk/TypetalkBuildWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package org.jenkinsci.plugins.typetalk;

import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrapperDescriptor;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.typetalk.api.Typetalk;
import org.jenkinsci.plugins.typetalk.api.TypetalkMessage;
import org.kohsuke.stapler.DataBoundConstructor;

import java.io.IOException;

public class TypetalkBuildWrapper extends BuildWrapper {

public final String name;
public final String topicNumber;
public final boolean notifyStart;
public final String notifyStartMessage;
public final boolean notifyEnd;
public final String notifyEndMessage;

@DataBoundConstructor
public TypetalkBuildWrapper(String name, String topicNumber, boolean notifyStart, String notifyStartMessage, boolean notifyEnd, String notifyEndMessage) {
this.name = name;
this.topicNumber = topicNumber;
this.notifyStart = notifyStart;
this.notifyStartMessage = notifyStartMessage;
this.notifyEnd = notifyEnd;
this.notifyEndMessage = notifyEndMessage;
}

@Override
public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
if (notifyStart) {
listener.getLogger().println("Notifying build start to Typetalk...");

String message;
if (StringUtils.isBlank(notifyStartMessage)) {
TypetalkMessage typetalkMessage = new TypetalkMessage(TypetalkMessage.Emoji.LOUDSPEAKER, "Build start");
message = typetalkMessage.messageWithBuildInfo(build);
} else{
message = build.getEnvironment(listener).expand(notifyStartMessage);
}
Long topicId = Long.valueOf(topicNumber);

Typetalk.createFromName(name).postMessage(topicId, message);
}

return new Environment() {
@Override
public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException {
if (notifyEnd && isSuccessBuild(build)) {
listener.getLogger().println("Notifying build end to Typetalk...");

String message;
if (StringUtils.isBlank(notifyEndMessage)) {
TypetalkMessage typetalkMessage = new TypetalkMessage(TypetalkMessage.Emoji.MEGA, "Build end");
message = typetalkMessage.messageWithBuildInfo(build);
} else {
message = build.getEnvironment(listener).expand(notifyEndMessage);
}
Long topicId = Long.valueOf(topicNumber);

Typetalk.createFromName(name).postMessage(topicId, message);
}

return true;
}

private boolean isSuccessBuild(AbstractBuild build) {
// When there is nothing failure (equals success), getResult hasn't been set yet.
return build.getResult() == null || build.getResult().equals(Result.SUCCESS);
}
};
}

@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}

@Extension
public static final class DescriptorImpl extends BuildWrapperDescriptor {

public DescriptorImpl() {
super(TypetalkBuildWrapper.class);
load();
}

@Override
public boolean isApplicable(AbstractProject<?, ?> item) {
return true;
}

@Override
public String getDisplayName() {
return "Notify to Typetalk when the build starts/ends";
}
}

}
41 changes: 8 additions & 33 deletions src/main/java/org/jenkinsci/plugins/typetalk/TypetalkNotifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import hudson.tasks.Notifier;
import hudson.tasks.Publisher;
import hudson.util.Secret;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.typetalk.api.Typetalk;
import org.jenkinsci.plugins.typetalk.api.TypetalkMessage;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

Expand All @@ -25,13 +25,11 @@ public class TypetalkNotifier extends Notifier {

public final String name;
public final String topicNumber;
public final boolean notifyWhenSuccess;

@DataBoundConstructor
public TypetalkNotifier(String name, String topicNumber, boolean notifyWhenSuccess) {
this.name = name;
this.topicNumber = topicNumber;
this.notifyWhenSuccess = notifyWhenSuccess;
}

@Override
Expand All @@ -43,42 +41,19 @@ public BuildStepMonitor getRequiredMonitorService() {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
throws InterruptedException, IOException {

final String rootUrl = Jenkins.getInstance().getRootUrl();
if (StringUtils.isEmpty(rootUrl)) {
throw new IllegalStateException("Root URL isn't configured yet. Cannot compute absolute URL.");
}

// 前回からビルド成功で "ビルドが成功した場合も通知する" がオフの場合、通知しない
if (successFromPreviousBuild(build) && notifyWhenSuccess == false) {
if (successFromPreviousBuild(build)) {
return true;
}

// Typetalkに通知中...
listener.getLogger().println("Notifying to the Typetalk...");

Credential credential = getDescriptor().getCredential(name);
if (credential == null) {
throw new IllegalStateException("Credential is not found.");
}
Typetalk typetalk = new Typetalk(credential.getClientId(), credential.getClientSecret());
listener.getLogger().println("Notifying build result to Typetalk...");

String message = makeMessage(build, TypetalkResult.convert(build), rootUrl);
TypetalkMessage typetalkMessage = TypetalkMessage.convertFromResult(build);
String message = typetalkMessage.messageWithBuildInfo(build);
Long topicId = Long.valueOf(topicNumber);
typetalk.postMessage(topicId, message);

return true;
}
Typetalk.createFromName(name).postMessage(topicId, message);

private String makeMessage(AbstractBuild<?, ?> build, TypetalkResult typetalkResult, String rootUrl) {
final StringBuilder message = new StringBuilder();
message.append(typetalkResult);
message.append(" [ ");
message.append(build.getProject().getDisplayName());
message.append(" ]");
message.append("\n");
message.append(rootUrl);
message.append(build.getUrl());
return message.toString();
return true;
}

private boolean successFromPreviousBuild(AbstractBuild<?, ?> build) {
Expand Down
71 changes: 0 additions & 71 deletions src/main/java/org/jenkinsci/plugins/typetalk/TypetalkResult.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.jenkinsci.plugins.typetalk;
package org.jenkinsci.plugins.typetalk.api;

import com.google.api.client.util.Key;

public class Message {
public class MessageEntity {

@Key
private String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.jenkinsci.plugins.typetalk;
package org.jenkinsci.plugins.typetalk.api;

import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.ClientCredentialsTokenRequest;
Expand All @@ -17,7 +17,10 @@
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonObjectParser;
import com.google.api.client.json.jackson.JacksonFactory;
import hudson.model.AbstractBuild;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.typetalk.TypetalkNotifier;

import java.io.IOException;
import java.util.Arrays;
Expand Down Expand Up @@ -67,15 +70,25 @@ public Typetalk(String clientId, String clientSecret) {
this.clientSecret = clientSecret;
}

public static Typetalk createFromName(String name) {
TypetalkNotifier.DescriptorImpl descriptor = (TypetalkNotifier.DescriptorImpl) Jenkins.getInstance().getDescriptor(TypetalkNotifier.class);
TypetalkNotifier.Credential credential = descriptor.getCredential(name);
if (credential == null) {
throw new IllegalArgumentException("Credential is not found.");
}

return new Typetalk(credential.getClientId(), credential.getClientSecret());
}

/**
* Typetalkにメッセージを通知する
*/
public int postMessage(final Long topicId, final String message) throws IOException {
final GenericUrl url = new PostMessageUrl(topicId);
final Message messageObj = new Message();
messageObj.setMessage(message);
final MessageEntity entity = new MessageEntity();
entity.setMessage(message);

final HttpContent content = new JsonHttpContent(JSON_FACTORY, messageObj);
final HttpContent content = new JsonHttpContent(JSON_FACTORY, entity);
final HttpRequest request = createRequestFactory().buildPostRequest(url, content);
HttpResponse response = request.execute();
response.disconnect();
Expand Down
Loading

0 comments on commit 0039b8d

Please sign in to comment.