Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JENKINS-7824: Add configurable emails to assignees when assigning a
failure
- Loading branch information
Showing
12 changed files
with
311 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
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
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
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,61 @@ | ||
package hudson.plugins.claim; | ||
|
||
import hudson.Extension; | ||
import jenkins.model.GlobalConfiguration; | ||
import net.sf.json.JSONObject; | ||
|
||
import org.kohsuke.stapler.StaplerRequest; | ||
|
||
@Extension | ||
public class ClaimConfig extends GlobalConfiguration { | ||
|
||
public ClaimConfig() { | ||
load(); | ||
} | ||
|
||
/** | ||
* Whether we want to send emails to the assignee when items are claimed/assigned | ||
*/ | ||
private boolean sendEmails; | ||
|
||
|
||
/** | ||
* This human readable name is used in the configuration screen. | ||
*/ | ||
public String getDisplayName() { | ||
return "Claim"; | ||
} | ||
|
||
@Override | ||
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { | ||
// To persist global configuration information, | ||
// set that to properties and call save(). | ||
sendEmails = formData.getBoolean("sendEmails"); | ||
save(); | ||
return super.configure(req,formData); | ||
} | ||
|
||
/** | ||
* This method returns true if the global configuration says we should send mails on build claims | ||
* @return true if configuration is that we send emails for claims, false otherwise | ||
*/ | ||
public boolean getSendEmails() { | ||
return sendEmails; | ||
} | ||
|
||
/** | ||
* Set whether we should send emails | ||
* @param val the setting to use | ||
*/ | ||
public void setSendEmails(boolean val) { | ||
sendEmails = val; | ||
} | ||
|
||
/** | ||
* get the current claim configuration | ||
* @return the global claim configuration | ||
*/ | ||
public static ClaimConfig get() { | ||
return GlobalConfiguration.all().get(ClaimConfig.class); | ||
} | ||
} |
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,124 @@ | ||
package hudson.plugins.claim; | ||
|
||
import hudson.model.User; | ||
import hudson.tasks.Mailer; | ||
|
||
import java.io.IOException; | ||
import java.io.UnsupportedEncodingException; | ||
import java.util.Date; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
import javax.mail.Address; | ||
import javax.mail.Message.RecipientType; | ||
import javax.mail.MessagingException; | ||
import javax.mail.Transport; | ||
import javax.mail.internet.AddressException; | ||
import javax.mail.internet.InternetAddress; | ||
import javax.mail.internet.MimeMessage; | ||
|
||
import jenkins.model.JenkinsLocationConfiguration; | ||
/** | ||
* Email utility class to allow sending of emails using the setup of the mailer plug-in to do so. | ||
* If the mailer plug-in is not installed, then no emails are sent | ||
* | ||
* | ||
*/ | ||
public class ClaimEmailer { | ||
|
||
private static final Logger LOGGER = Logger.getLogger("claim-plugin"); | ||
|
||
private static final boolean mailerLoaded = isMailerLoaded(); | ||
|
||
private static boolean isMailerLoaded () { | ||
boolean ret = true; | ||
try { | ||
new Mailer.DescriptorImpl(); | ||
} catch (Throwable e) { | ||
LOGGER.warning("Mailer plugin is not installed. Mailer plugin must be installed if you want to send emails"); | ||
ret = false; | ||
} | ||
return ret; | ||
} | ||
|
||
/** | ||
* Send an email to the assignee indicating that the given build has been assigned | ||
* @param assignee the user assigned the failed build | ||
* @param assignedBy the user assigning the build | ||
* @param build the build/action which has been assigned | ||
* @param reason the reason given for the assignment | ||
* @param URL the URL the user can view for the assigned build | ||
* @throws MessagingException if there has been some problem with sending the email | ||
* @throws IOException if there is an IO problem when sending the mail | ||
* @throws InterruptedException if the send operation is interrupted | ||
*/ | ||
public static void sendEmailIfConfigured (User assignee, String assignedBy, String build, String reason, String URL) throws MessagingException, IOException, InterruptedException { | ||
|
||
ClaimConfig config = ClaimConfig.get(); | ||
if (config.getSendEmails() && mailerLoaded) { | ||
MimeMessage msg = createMessage(assignee, assignedBy, build, reason, URL); | ||
Transport.send(msg); | ||
} | ||
} | ||
|
||
private static MimeMessage createMessage(User assignee, String assignedBy, String build, String reason, String URL) | ||
throws MessagingException, IOException, InterruptedException { | ||
MimeMessage msg = null; | ||
// create Session | ||
final Mailer.DescriptorImpl mailDescriptor = new Mailer.DescriptorImpl(); | ||
msg = createMimeMessage(mailDescriptor); | ||
|
||
msg.setSentDate(new Date()); | ||
msg.setSubject(Messages.ClaimEmailer_Subject(build),mailDescriptor.getCharset()); | ||
//TODO configurable formatting, through email-ext plugin | ||
final String text = Messages.ClaimEmailer_Text(build, assignedBy) + | ||
System.getProperty("line.separator") + Messages.ClaimEmailer_Reason(reason) + | ||
System.getProperty("line.separator") + System.getProperty("line.separator") + | ||
Messages.ClaimEmailer_Details(JenkinsLocationConfiguration.get().getUrl() + URL); | ||
|
||
msg.setText(text, mailDescriptor.getCharset()); | ||
msg.setRecipient(RecipientType.TO, getUserEmail(assignee,mailDescriptor)); | ||
|
||
return msg; | ||
} | ||
|
||
/** | ||
* Creates MimeMessage using the mailer plugin for jenkins. | ||
* | ||
* @param mailDescriptor a reference to the mailer plugin from which we can get mailing parameters | ||
* @return mimemessage a message which can be emailed | ||
* @throws MessagingException | ||
* @throws UnsupportedEncodingException | ||
* @throws AddressException | ||
* | ||
*/ | ||
private static MimeMessage createMimeMessage(final Mailer.DescriptorImpl mailDescriptor) throws AddressException, UnsupportedEncodingException, MessagingException { | ||
MimeMessage ret = new MimeMessage(mailDescriptor.createSession()); | ||
ret.setFrom(Mailer.StringToAddress(JenkinsLocationConfiguration.get().getAdminAddress(), mailDescriptor.getCharset())); | ||
return ret; | ||
} | ||
|
||
/** | ||
* Returns the email address of a given user. | ||
* | ||
* @param user the user | ||
* @param mailDescriptor the descriptor allowing us to access mail config | ||
* @return email address for this user, null if none can be derived | ||
*/ | ||
private static Address getUserEmail(User user, Mailer.DescriptorImpl mailDescriptor) { | ||
if (user != null) { | ||
try { | ||
final Mailer.UserProperty mailProperty = user | ||
.getProperty(Mailer.UserProperty.class); | ||
if (mailProperty != null && mailProperty.getAddress() != null) { | ||
return new InternetAddress(mailProperty.getAddress()); | ||
} | ||
return new InternetAddress(user.getId() + mailDescriptor.getDefaultSuffix()); | ||
} catch (AddressException e) { | ||
LOGGER.log(Level.WARNING, "Cannot get email address for user " + user.getId(), e); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
} |
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
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
7 changes: 7 additions & 0 deletions
7
src/main/resources/hudson/plugins/claim/ClaimConfig/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,7 @@ | ||
<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:section title="Claim"> | ||
<f:entry title="${%SendEmails}" field="sendEmails" help="/plugin/claim/help-sendEmails.html"> | ||
<f:checkbox /> | ||
</f:entry> | ||
</f:section> | ||
</j:jelly> |
1 change: 1 addition & 0 deletions
1
src/main/resources/hudson/plugins/claim/ClaimConfig/config.properties
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 @@ | ||
SendEmails=Send emails when assigning/claiming builds |
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
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> | ||
If selected, an email is sent to the assignee when a build is claimed or assigned. To enable sending emails, you need to also install the email-ext plugin | ||
</div> |
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,75 @@ | ||
package hudson.plugins.claim; | ||
|
||
import hudson.model.UserProperty; | ||
import hudson.model.User; | ||
import hudson.tasks.Mailer; | ||
|
||
import java.util.Collections; | ||
|
||
import javax.mail.Address; | ||
import javax.mail.internet.InternetAddress; | ||
|
||
import jenkins.model.JenkinsLocationConfiguration; | ||
|
||
import org.junit.Test; | ||
import org.jvnet.hudson.test.HudsonTestCase; | ||
import org.jvnet.mock_javamail.Mailbox; | ||
|
||
public class ClaimEmailerTest extends HudsonTestCase { | ||
|
||
/* | ||
* Test that no mail is sent if mail sending is not configured | ||
*/ | ||
@Test | ||
public void testSendEmailNotConfigured() throws Exception { | ||
|
||
JenkinsLocationConfiguration.get().setAdminAddress("test <test@test.com>"); | ||
ClaimConfig config = ClaimConfig.get(); | ||
config.setSendEmails(false); | ||
|
||
String recipient = "assignee <assignee@test.com>"; | ||
Mailbox yourInbox = Mailbox.get(new InternetAddress(recipient)); | ||
yourInbox.clear(); | ||
|
||
User assignee = User.get("assignee", true, Collections.emptyMap()); | ||
UserProperty p = new Mailer.UserProperty("assignee@test.com"); | ||
assignee.addProperty(p); | ||
ClaimEmailer.sendEmailIfConfigured(assignee, "assignedByMe", "Test build", "test reason", "jobs/TestBuild/"); | ||
|
||
assertEquals(0,yourInbox.size()); | ||
} | ||
|
||
/* | ||
* Test that mail is sent to the assignee if mail sending is configured | ||
*/ | ||
@Test | ||
public void testSendEmailConfigured() throws Exception { | ||
|
||
JenkinsLocationConfiguration.get().setAdminAddress("test <test@test.com>"); | ||
JenkinsLocationConfiguration.get().setUrl("localhost:8080/jenkins/"); | ||
|
||
ClaimConfig config = ClaimConfig.get(); | ||
config.setSendEmails(true); | ||
|
||
String recipient = "assignee <assignee@test.com>"; | ||
Mailbox yourInbox = Mailbox.get(new InternetAddress(recipient)); | ||
yourInbox.clear(); | ||
|
||
User assignee = User.get("assignee", true, Collections.emptyMap()); | ||
UserProperty p = new Mailer.UserProperty("assignee@test.com"); | ||
assignee.addProperty(p); | ||
ClaimEmailer.sendEmailIfConfigured(assignee, "assignedBy", "Test build", "test reason", "jobs/TestBuild/"); | ||
|
||
assertEquals(1,yourInbox.size()); | ||
Address[] senders = yourInbox.get(0).getFrom(); | ||
assertEquals(1,senders.length); | ||
assertEquals("test <test@test.com>",senders[0].toString()); | ||
|
||
Object content = yourInbox.get(0).getContent(); | ||
assertTrue("Mail content should contain the reason",content.toString().contains(Messages.ClaimEmailer_Reason("test reason"))); | ||
assertTrue("Mail content should contain the details",content.toString().contains(Messages.ClaimEmailer_Details("localhost:8080/jenkins/jobs/TestBuild/"))); | ||
assertTrue("Mail content should assignment text",content.toString().contains(Messages.ClaimEmailer_Text("Test build", "assignedBy"))); | ||
} | ||
|
||
|
||
} |