├── .gitignore
├── src
└── main
│ ├── webapp
│ ├── help-globalConfig-ssl.html
│ ├── help-globalConfig-token.html
│ ├── help.html
│ ├── help-globalConfig-sounds.html
│ ├── help-globalConfig-room.html
│ ├── help-projectConfig-room.html
│ ├── help-globalConfig-hudsonUrl.html
│ ├── help-globalConfig-subdomain.html
│ └── help-globalConfig-smartNotify.html
│ ├── java
│ └── hudson
│ │ └── plugins
│ │ └── campfire
│ │ ├── PluginImpl.java
│ │ ├── Room.java
│ │ ├── DescriptorImpl.java
│ │ ├── Campfire.java
│ │ └── CampfireNotifier.java
│ └── resources
│ ├── index.jelly
│ └── hudson
│ └── plugins
│ └── campfire
│ └── CampfireNotifier
│ ├── config.jelly
│ └── global.jelly
├── README.markdown
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.*~
2 | *.swp
3 | .project
4 | target
5 |
--------------------------------------------------------------------------------
/src/main/webapp/help-globalConfig-ssl.html:
--------------------------------------------------------------------------------
1 |
2 |
Use SSL to connect to Campfire?
3 |
--------------------------------------------------------------------------------
/src/main/java/hudson/plugins/campfire/PluginImpl.java:
--------------------------------------------------------------------------------
1 | package hudson.plugins.campfire;
2 |
3 | import hudson.Plugin;
4 |
5 | public class PluginImpl extends Plugin {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/webapp/help-globalConfig-token.html:
--------------------------------------------------------------------------------
1 |
2 |
The API authentication token to be used to send notifications to Campfire. You can copy this from the settings page within Campfire.
3 |
--------------------------------------------------------------------------------
/src/main/webapp/help.html:
--------------------------------------------------------------------------------
1 |
2 | Send build notifications to a Campfire chat room.
3 | The campfire notifier is configured globally, but you can customize the room name per-project.
4 |
5 |
--------------------------------------------------------------------------------
/src/main/webapp/help-globalConfig-sounds.html:
--------------------------------------------------------------------------------
1 |
2 |
Play sounds in addition to build success and failure messages:
3 |
4 | - On SUCCESS, "rimshot" is played
5 | - On FAILURE, "sad trombone" is played
6 |
8 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | ## Campfire notifier plugin for Jenkins
2 |
3 | ---
4 |
5 | This fork has merged back to the offical Jenkins repository at
6 | [https://github.com/jenkinsci/campfire-plugin](https://github.com/jenkinsci/campfire-plugin).
7 |
8 | ---
9 |
10 |
--------------------------------------------------------------------------------
/src/main/resources/index.jelly:
--------------------------------------------------------------------------------
1 |
6 |
7 | This plugin is a Campfire bot that can publish build statusses to Campfire rooms.
8 |
--------------------------------------------------------------------------------
/src/main/webapp/help-globalConfig-room.html:
--------------------------------------------------------------------------------
1 |
2 |
Enter the name of the room to which notifications should be sent. Note that this is the name of the
3 | room, not the id number, e.g. "Dev Team". You can customize the room name per-project, but should always
4 | enter a default here.
5 |
6 |
--------------------------------------------------------------------------------
/src/main/webapp/help-projectConfig-room.html:
--------------------------------------------------------------------------------
1 |
2 |
Enter the name of the room to which notifications for this project should be sent,
3 | if different to the default room configured in the global campfire notifier settings.
4 | Note that this is the name of the room, not the id number, e.g. "Dev Team".
5 |
6 |
--------------------------------------------------------------------------------
/src/main/webapp/help-globalConfig-hudsonUrl.html:
--------------------------------------------------------------------------------
1 |
2 |
Optionally specify the URL for your Hudson installation, e.g. http://yourhost.yourdomain/hudson/.
3 | This value will be used to generate links back to Hudson from Campfire and should end with a forward slash.
4 |
This is necessary because Hudson cannot reliably detect such a URL from within itself.
5 |
--------------------------------------------------------------------------------
/src/main/webapp/help-globalConfig-subdomain.html:
--------------------------------------------------------------------------------
1 |
2 |
The subdomain for your Campfire account (strictly the leaf node of the fully qualified host name).
3 | This value is used to build the URL used when interacting with the Campfire API. For example, if your
4 | Campfire URL is "http://mysubdomain.campfirenow.com", the subdomain setting should be "mysubdomain".
5 |
--------------------------------------------------------------------------------
/src/main/webapp/help-globalConfig-smartNotify.html:
--------------------------------------------------------------------------------
1 |
2 |
When checked, build notifications will be posted to Campfire only if:
3 |
4 | - there was no previous build, or
5 | - if there was a failure, or
6 | - if previous build failed and the current build succeeded.
7 |
8 | In other words, notifications won't be sent for successful builds unless the last build was not successful.
9 |
10 |
--------------------------------------------------------------------------------
/src/main/resources/hudson/plugins/campfire/CampfireNotifier/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/main/java/hudson/plugins/campfire/Room.java:
--------------------------------------------------------------------------------
1 | package hudson.plugins.campfire;
2 |
3 | import java.io.IOException;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 | import java.util.Date;
7 |
8 | public class Room {
9 | private transient Campfire campfire;
10 | private String name;
11 | private String id;
12 |
13 | public Room(Campfire cf, String name, String id) {
14 | super();
15 | this.campfire = cf;
16 | this.name = name;
17 | this.id = id;
18 | }
19 |
20 | public String getName() {
21 | return this.name;
22 | }
23 |
24 | public String getId() {
25 | return this.id;
26 | }
27 |
28 | public void speak(String message) throws IOException {
29 | campfire.post("room/" + id + "/speak.xml", "TextMessage" + message + "");
30 | }
31 |
32 | public void play(String sound) throws IOException {
33 | campfire.post("room/" + id + "/speak.xml", "SoundMessage" + sound + "");
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/resources/hudson/plugins/campfire/CampfireNotifier/global.jelly:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.jvnet.hudson.plugins
6 | plugin
7 | 1.319
8 | ../pom.xml
9 |
10 | org.jvnet.hudson.plugins
11 | campfire
12 | hpi
13 | 2.4.2
14 | Jenkins Campfire Plugin
15 | A build status notifier that sends notifications to Campfire rooms
16 | http://wiki.jenkins-ci.org/display/JENKINS/Campfire+Plugin
17 |
18 | MIT licenseAll source code is under the MIT license.
19 |
20 |
21 | scm:git:git://github.com/thickpaddy/jenkins_campfire_plugin.git
22 | scm:git:git@github.com:thickpaddy/jenkins_campfire_plugin.git
23 | http://github.com/thickpaddy/jenkins_campfire_plugin
24 |
25 |
26 |
27 | org.jvnet.hudson.main
28 | maven-plugin
29 |
30 |
31 | commons-httpclient
32 | commons-httpclient
33 | 3.1-rc1
34 |
35 |
36 |
37 |
38 | jenslukowski
39 | Jens Lukowski
40 | jens.lukowski@softwareschneiderei.de
41 | Softwareschneiderei GmbH
42 | http://www.softwareschneiderei.de
43 |
44 |
45 | thickpaddy
46 | Mark Woods
47 | https://github.com/thickpaddy
48 |
49 |
50 | jkrall
51 | Joshua Krall
52 | https://github.com/jkrall
53 |
54 |
55 | bgreenlee
56 | Brad Greenlee
57 | https://github.com/bgreenlee
58 |
59 |
60 | hpoydar
61 | Henry Poydar
62 | https://github.com/hpoydar
63 |
64 |
65 | mortice
66 | Tom Stuart
67 | https://github.com/mortice
68 |
69 |
70 | dbriones
71 | Dante Briones
72 | https://github.com/dbriones
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/main/java/hudson/plugins/campfire/DescriptorImpl.java:
--------------------------------------------------------------------------------
1 | package hudson.plugins.campfire;
2 |
3 | import hudson.model.AbstractProject;
4 | import hudson.tasks.BuildStepDescriptor;
5 | import hudson.tasks.Publisher;
6 | import net.sf.json.JSONObject;
7 | import org.kohsuke.stapler.StaplerRequest;
8 |
9 | import java.util.logging.Level;
10 | import java.util.logging.Logger;
11 |
12 | public class DescriptorImpl extends BuildStepDescriptor {
13 | private boolean enabled = false;
14 | private String subdomain;
15 | private String token;
16 | private String room;
17 | private String hudsonUrl;
18 | private boolean ssl;
19 | private boolean smartNotify;
20 | private boolean sound;
21 | private static final Logger LOGGER = Logger.getLogger(DescriptorImpl.class.getName());
22 |
23 | public DescriptorImpl() {
24 | super(CampfireNotifier.class);
25 | load();
26 | }
27 |
28 | public boolean isEnabled() {
29 | return enabled;
30 | }
31 |
32 | public String getSubdomain() {
33 | return subdomain;
34 | }
35 |
36 | public String getToken() {
37 | return token;
38 | }
39 |
40 | public String getRoom() {
41 | return room;
42 | }
43 |
44 | public String getHudsonUrl() {
45 | return hudsonUrl;
46 | }
47 |
48 | public boolean getSsl() {
49 | return ssl;
50 | }
51 |
52 | public boolean getSmartNotify() {
53 | return smartNotify;
54 | }
55 |
56 | public boolean getSound() {
57 | return sound;
58 | }
59 |
60 | public boolean isApplicable(Class extends AbstractProject> aClass) {
61 | return true;
62 | }
63 |
64 | /**
65 | * @see hudson.model.Descriptor#newInstance(org.kohsuke.stapler.StaplerRequest)
66 | */
67 | @Override
68 | public Publisher newInstance(StaplerRequest req, JSONObject formData) throws FormException {
69 | String projectRoom = req.getParameter("roomName");
70 | if ( projectRoom == null || projectRoom.trim().length() == 0 ) {
71 | projectRoom = room;
72 | }
73 | try {
74 | return new CampfireNotifier(subdomain, token, projectRoom, hudsonUrl, ssl, smartNotify, sound);
75 | } catch (Exception e) {
76 | String message = "Failed to initialize campfire notifier - check your campfire notifier configuration settings: " + e.getMessage();
77 | LOGGER.log(Level.WARNING, message, e);
78 | throw new FormException(message, e, "");
79 | }
80 | }
81 |
82 | @Override
83 | public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
84 | subdomain = req.getParameter("campfireSubdomain");
85 | token = req.getParameter("campfireToken");
86 | room = req.getParameter("campfireRoom");
87 | hudsonUrl = req.getParameter("campfireHudsonUrl");
88 | if ( hudsonUrl != null && !hudsonUrl.endsWith("/") ) {
89 | hudsonUrl = hudsonUrl + "/";
90 | }
91 | ssl = req.getParameter("campfireSsl") != null;
92 | smartNotify = req.getParameter("campfireSmartNotify") != null;
93 | sound = req.getParameter("campfireSound") != null;
94 | try {
95 | new CampfireNotifier(subdomain, token, room, hudsonUrl, ssl, smartNotify, sound);
96 | } catch (Exception e) {
97 | String message = "Failed to initialize campfire notifier - check your global campfire notifier configuration settings: " + e.getMessage();
98 | LOGGER.log(Level.WARNING, message, e);
99 | throw new FormException(message, e, "");
100 | }
101 | save();
102 | return super.configure(req, json);
103 | }
104 |
105 | /**
106 | * @see hudson.model.Descriptor#getDisplayName()
107 | */
108 | @Override
109 | public String getDisplayName() {
110 | return "Campfire Notification";
111 | }
112 |
113 | /**
114 | * @see hudson.model.Descriptor#getHelpFile()
115 | */
116 | @Override
117 | public String getHelpFile() {
118 | return "/plugin/campfire/help.html";
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/hudson/plugins/campfire/Campfire.java:
--------------------------------------------------------------------------------
1 | package hudson.plugins.campfire;
2 |
3 | import org.apache.commons.httpclient.Credentials;
4 | import org.apache.commons.httpclient.HttpClient;
5 | import org.apache.commons.httpclient.UsernamePasswordCredentials;
6 | import org.apache.commons.httpclient.auth.AuthScope;
7 | import org.apache.commons.httpclient.methods.GetMethod;
8 | import org.apache.commons.httpclient.methods.PostMethod;
9 | import org.apache.commons.httpclient.methods.StringRequestEntity;
10 | import org.w3c.dom.Document;
11 | import org.w3c.dom.Node;
12 | import org.w3c.dom.NodeList;
13 | import org.xml.sax.InputSource;
14 | import org.xml.sax.SAXException;
15 |
16 | import javax.xml.parsers.DocumentBuilder;
17 | import javax.xml.parsers.DocumentBuilderFactory;
18 | import javax.xml.parsers.ParserConfigurationException;
19 | import javax.xml.xpath.*;
20 | import java.io.IOException;
21 | import java.io.StringReader;
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | public class Campfire {
26 | private HttpClient client;
27 | private String subdomain;
28 | private String token;
29 | private boolean ssl;
30 |
31 | public Campfire(String subdomain, String token, boolean ssl) {
32 | super();
33 | this.subdomain = subdomain;
34 | this.token = token;
35 | this.ssl = ssl;
36 | client = new HttpClient();
37 | Credentials defaultcreds = new UsernamePasswordCredentials(token, "x");
38 | client.getState().setCredentials(new AuthScope(getHost(), -1, AuthScope.ANY_REALM), defaultcreds);
39 | client.getParams().setAuthenticationPreemptive(true);
40 | client.getParams().setParameter("http.useragent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16");
41 | }
42 |
43 | protected String getHost() {
44 | return this.subdomain + ".campfirenow.com";
45 | }
46 |
47 | protected String getProtocol() {
48 | if (this.ssl) { return "https://"; }
49 | return "http://";
50 | }
51 |
52 | public int post(String url, String body) {
53 | PostMethod post = new PostMethod(getProtocol() + getHost() + "/" + url);
54 | post.setRequestHeader("Content-Type", "application/xml");
55 | try {
56 | post.setRequestEntity(new StringRequestEntity(body, "application/xml", "UTF8"));
57 | return client.executeMethod(post);
58 | } catch (IOException e) {
59 | throw new RuntimeException(e);
60 | } finally {
61 | post.releaseConnection();
62 | }
63 | }
64 |
65 | public String get(String url) {
66 | GetMethod get = new GetMethod(getProtocol() + getHost() + "/" + url);
67 | get.setFollowRedirects(true);
68 | get.setRequestHeader("Content-Type", "application/xml");
69 | try {
70 | client.executeMethod(get);
71 | verify(get.getStatusCode());
72 | return get.getResponseBodyAsString();
73 | } catch (IOException e) {
74 | throw new RuntimeException(e);
75 | } finally {
76 | get.releaseConnection();
77 | }
78 | }
79 |
80 | public boolean verify(int returnCode) {
81 | if (returnCode != 200) {
82 | throw new RuntimeException("Unexpected response code: " + Integer.toString(returnCode));
83 | }
84 | return true;
85 | }
86 |
87 | private List getRooms(){
88 | String body = get("rooms.xml");
89 |
90 | List rooms;
91 | try {
92 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
93 | factory.setNamespaceAware(true);
94 | DocumentBuilder builder = factory.newDocumentBuilder();
95 | StringReader reader = new StringReader(body);
96 | InputSource inputSource = new InputSource( reader );
97 | Document doc = builder.parse(inputSource);
98 |
99 | XPath xpath = XPathFactory.newInstance().newXPath();
100 | XPathExpression roomExpr = xpath.compile("//room");
101 | XPathExpression nameExpr = xpath.compile(".//name");
102 | XPathExpression idExpr = xpath.compile(".//id");
103 |
104 | NodeList roomNodeList = (NodeList) roomExpr.evaluate(doc, XPathConstants.NODESET);
105 | rooms = new ArrayList();
106 | for (int i = 0; i < roomNodeList.getLength(); i++) {
107 | Node roomNode = roomNodeList.item(i);
108 | String name = ((NodeList) nameExpr.evaluate(roomNode, XPathConstants.NODESET)).item(0).getFirstChild().getNodeValue();
109 | String id = ((NodeList) idExpr.evaluate(roomNode, XPathConstants.NODESET)).item(0).getFirstChild().getNodeValue();
110 | rooms.add(new Room(this, name.trim(), id.trim()));
111 | }
112 | } catch (ParserConfigurationException e) {
113 | throw new RuntimeException(e);
114 | } catch (SAXException e) {
115 | throw new RuntimeException(e);
116 | } catch (IOException e) {
117 | throw new RuntimeException(e);
118 | } catch (XPathExpressionException e) {
119 | throw new RuntimeException(e);
120 | }
121 | return rooms;
122 | }
123 |
124 | public Room findRoomByName(String name) {
125 | for (Room room : getRooms()) {
126 | if (room.getName().equals(name)) {
127 | return room;
128 | }
129 | }
130 | return null;
131 | }
132 |
133 | private Room createRoom(String name) {
134 | verify(post("rooms.xml", "" + name + ""));
135 | return findRoomByName(name);
136 | }
137 |
138 | public Room findOrCreateRoomByName(String name) {
139 | Room room = findRoomByName(name);
140 | if (room != null) {
141 | return room;
142 | }
143 | return createRoom(name);
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/main/java/hudson/plugins/campfire/CampfireNotifier.java:
--------------------------------------------------------------------------------
1 | package hudson.plugins.campfire;
2 |
3 | import hudson.Extension;
4 | import hudson.Launcher;
5 | import hudson.model.AbstractBuild;
6 | import hudson.model.BuildListener;
7 | import hudson.model.Result;
8 | import hudson.scm.ChangeLogSet;
9 | import hudson.tasks.BuildStepMonitor;
10 | import hudson.tasks.Notifier;
11 |
12 | import java.io.BufferedReader;
13 | import java.io.File;
14 | import java.io.FileReader;
15 | import java.io.IOException;
16 | import java.lang.reflect.Method;
17 | import java.util.logging.Level;
18 | import java.util.logging.Logger;
19 |
20 | public class CampfireNotifier extends Notifier {
21 |
22 | private transient Campfire campfire;
23 | private Room room;
24 | private String hudsonUrl;
25 | private boolean smartNotify;
26 | private boolean sound;
27 |
28 | // getter for project configuration..
29 | // Configured room name should be null unless different from descriptor/global room name
30 | public String getConfiguredRoomName() {
31 | if ( DESCRIPTOR.getRoom().equals(room.getName()) ) {
32 | return null;
33 | } else {
34 | return room.getName();
35 | }
36 | }
37 |
38 | @Extension
39 | public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
40 |
41 | private static final Logger LOGGER = Logger.getLogger(CampfireNotifier.class.getName());
42 |
43 | public CampfireNotifier() {
44 | super();
45 | initialize();
46 | }
47 |
48 | public CampfireNotifier(String subdomain, String token, String room, String hudsonUrl, boolean ssl, boolean smartNotify, boolean sound) {
49 | super();
50 | initialize(subdomain, token, room, hudsonUrl, ssl, smartNotify, sound);
51 | }
52 |
53 | public BuildStepMonitor getRequiredMonitorService() {
54 | return BuildStepMonitor.BUILD;
55 | }
56 |
57 | private void publish(AbstractBuild, ?> build) throws IOException {
58 | checkCampfireConnection();
59 | Result result = build.getResult();
60 | String changeString = "No changes";
61 | if (!build.hasChangeSetComputed()) {
62 | changeString = "Changes not determined";
63 | } else if (build.getChangeSet().iterator().hasNext()) {
64 | ChangeLogSet changeSet = build.getChangeSet();
65 | ChangeLogSet.Entry entry = build.getChangeSet().iterator().next();
66 | // note: iterator should return recent changes first, but GitChangeSetList currently reverses the log entries
67 | if (changeSet.getClass().getSimpleName().equals("GitChangeSetList")) {
68 | String exceptionLogMsg = "Workaround to obtain latest commit info from git plugin failed";
69 | try {
70 | // find the sha for the first commit in the changelog file, and then grab the corresponding entry from the changeset, yikes!
71 | String changeLogPath = build.getRootDir().toString() + File.separator + "changelog.xml";
72 | String sha = getCommitHash(changeLogPath);
73 | if (!"".equals(sha)) {
74 | Method getIdMethod = entry.getClass().getDeclaredMethod("getId");
75 | for(ChangeLogSet.Entry nextEntry : build.getChangeSet()) {
76 | if ( ( (String)getIdMethod.invoke(entry) ).compareTo(sha) != 0 ) entry = nextEntry;
77 | }
78 | }
79 | } catch ( IOException e ){
80 | LOGGER.log(Level.WARNING, exceptionLogMsg, e);
81 | } catch ( NoSuchMethodException e ) {
82 | LOGGER.log(Level.WARNING, exceptionLogMsg, e);
83 | } catch ( IllegalAccessException e ) {
84 | LOGGER.log(Level.WARNING, exceptionLogMsg, e);
85 | } catch ( SecurityException e ) {
86 | LOGGER.log(Level.WARNING, exceptionLogMsg, e);
87 | } catch ( Exception e ) {
88 | throw new RuntimeException(e.getClass().getName() + ": " + e.getMessage(), e);
89 | }
90 | }
91 | String commitMsg = entry.getMsg().trim();
92 | if (!"".equals(commitMsg)) {
93 | if (commitMsg.length() > 47) {
94 | commitMsg = commitMsg.substring(0, 46) + "...";
95 | }
96 | changeString = commitMsg + " - " + entry.getAuthor().toString();
97 | }
98 | }
99 | String resultString = result.toString();
100 | if (!smartNotify && result == Result.SUCCESS) resultString = resultString.toLowerCase();
101 | String message = build.getProject().getName() + " " + build.getDisplayName() + " \"" + changeString + "\": " + resultString;
102 | if (hudsonUrl != null && hudsonUrl.length() > 1 && (smartNotify || result != Result.SUCCESS)) {
103 | message = message + " (" + hudsonUrl + build.getUrl() + ")";
104 | }
105 | room.speak(message);
106 | if (sound) {
107 | String message_sound;
108 | if ("FAILURE".equals(resultString)) {
109 | message_sound = "trombone";
110 | } else {
111 | message_sound = "rimshot";
112 | }
113 | room.play(message_sound);
114 | }
115 | }
116 |
117 | private String getCommitHash(String changeLogPath) throws IOException {
118 | String sha = "";
119 | BufferedReader reader = new BufferedReader(new FileReader(changeLogPath));
120 | String line;
121 | while((line = reader.readLine()) != null) {
122 | if (line.matches("^commit [a-zA-Z0-9]+$")) {
123 | sha = line.replace("commit ", "");
124 | break;
125 | }
126 | }
127 | reader.close();
128 | return sha;
129 | }
130 |
131 | private void checkCampfireConnection() {
132 | if (campfire == null) {
133 | initialize();
134 | }
135 | }
136 |
137 | private void initialize() {
138 | initialize(DESCRIPTOR.getSubdomain(), DESCRIPTOR.getToken(), room.getName(), DESCRIPTOR.getHudsonUrl(), DESCRIPTOR.getSsl(), DESCRIPTOR.getSmartNotify(), DESCRIPTOR.getSound());
139 | }
140 |
141 | private void initialize(String subdomain, String token, String roomName, String hudsonUrl, boolean ssl, boolean smartNotify, boolean sound) {
142 | campfire = new Campfire(subdomain, token, ssl);
143 | this.room = campfire.findRoomByName(roomName);
144 | if ( this.room == null ) {
145 | throw new RuntimeException("Room '" + roomName + "' not found - verify name and room permissions");
146 | }
147 | this.hudsonUrl = hudsonUrl;
148 | this.smartNotify = smartNotify;
149 | this.sound = sound;
150 | }
151 |
152 | @Override
153 | public boolean perform(AbstractBuild, ?> build, Launcher launcher,
154 | BuildListener listener) throws InterruptedException, IOException {
155 | // If SmartNotify is enabled, only notify if:
156 | // (1) there was no previous build, or
157 | // (2) the current build did not succeed, or
158 | // (3) the previous build failed and the current build succeeded.
159 | if (smartNotify) {
160 | AbstractBuild previousBuild = build.getPreviousBuild();
161 | if (previousBuild == null ||
162 | build.getResult() != Result.SUCCESS ||
163 | previousBuild.getResult() != Result.SUCCESS)
164 | {
165 | publish(build);
166 | }
167 | } else {
168 | publish(build);
169 | }
170 | return true;
171 | }
172 | }
173 |
--------------------------------------------------------------------------------