In previous post we learnt how to write Writing Build Phase Jenkins Plugin, now in this article we will learn how to write a Jenkins CI Plugin that executes post build process. The complete source code is hosted on github post-build-jenkins-plugin
Step 1: Edit the settings.xml in .m2 directory or if it is not there create it with below content:
<settings>
<pluginGroups>
<pluginGroup>org.jenkins-ci.tools</pluginGroup>
</pluginGroups>
<profiles>
<profile>
<id>jenkins</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
</settings>
Step 2: Create a Maven project and edit the pom.xml as:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.580.1</version>
<relativePath />
</parent>
<groupId>com.jenkins</groupId>
<artifactId>post-build-jenkins-plugin</artifactId>
<packaging>hpi</packaging>
<version>0.0.1</version>
<name>Email Plugin</name>
<url>http://wiki.jenkins-ci.org/display/JENKINS/post-build-jenkins-plugin</url>
<dependencies>
</dependencies>
<build>
<finalName>post-build-jenkins-plugin</finalName>
</build>
</project>
Step 3: Create a folder under src/main/java for me it’s com.jenkins.publisher and copy the EmailPublisher java class with below content inside it:
package com.jenkins.publisher;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Notifier;
import hudson.tasks.Publisher;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
public class EmailPublisher extends Notifier {
private final String emailId;
private static Properties properties = new Properties();
static {
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", "smtp.gmail.com");
properties.put("mail.smtp.port", "587");
}
@DataBoundConstructor
public EmailPublisher(final String emailId) {
this.emailId = emailId;
}
public String getEmailId() {
return emailId;
}
@Override
public boolean perform(
@SuppressWarnings("rawtypes") final AbstractBuild build,
final Launcher launcher, final BuildListener listener) {
// logic to be executed by plugin
try {
// logger which prints on job 'Console Output'
listener.getLogger().println("Starting Post Build Action");
sendMail();
} catch (Exception e) {
listener.getLogger().printf("Error Occurred : %s ", e);
}
listener.getLogger().println("Finished Post Build Action");
return true;
}
@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
/**
* Global configuration information variables. If you don't want fields
* to be persisted, use <tt>transient</tt>.
*/
private String username;
private String password;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
/**
* In order to load the persisted global configuration, you have to call
* load() in the constructor.
*/
public DescriptorImpl() {
load();
}
@Override
public boolean configure(StaplerRequest req, JSONObject formData)
throws FormException {
// To persist global configuration information, set that to
// properties and call save().
username = formData.getString("username");
password = formData.getString("password");
save();
return super.configure(req, formData);
}
@Override
public boolean isApplicable(
@SuppressWarnings("rawtypes") Class<? extends AbstractProject> jobType) {
// Indicates that this builder can be used with all kinds of project
// types.
return true;
}
@Override
public String getDisplayName() {
return "Send Email";
}
}
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
private void sendMail() throws Exception {
final String username = getDescriptor().getUsername();
final String password = getDescriptor().getPassword();
Session session = Session.getInstance(properties,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("aggarwalarpit.89@gmail.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(emailId));
message.setSubject("Jenkins Post Build Mail");
message.setText("Jenkins Post Build Mail");
Transport.send(message);
}
}
Step 4: Create a index.jelly file under src/main/resources folder and copy the below content to it:
<?jelly escape-by-default='true'?>
<!-- This view is used to render the installed plugins page. -->
<div>
This plugin send mail post build.
</div>
Step 5: Create a folder with same name as of Java class under src/main/resources/ in my case it’s
com/jenkins/publisher/EmailPublisher and then create config.jelly, global.jelly, help-emailId.html, help-username.html and help-password.html inside it with below content:
config.jelly
<?jelly escape-by-default='true'?>
<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">
<!-- Creates a text field that shows the value of the "emailId" property. When submitted, it will be passed to the corresponding constructor parameter. -->
<f:entry title="Email Id" field="emailId">
<f:textbox />
</f:entry>
</j:jelly>
global.jelly
<?jelly escape-by-default='true'?>
<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. -->
<f:section title="Email Publisher">
<f:entry title="Username" field="username">
<f:textbox />
</f:entry>
<f:entry title="Password" field="password">
<f:textbox />
</f:entry>
</f:section>
</j:jelly>
help-emailId.html
<!-- Help file for fields are discovered through a file name convention. This file is help for the "emailId" field. -->
<div>Specify the email id to which mail to be sent. For example,
you can specify as aggarwalarpit.89@gmail.com
</div>
help-username.html
<!-- This HTML fragment will be injected into the configuration screen when the user clicks the 'help' icon of filed 'username'. -->
<div>Specify the username of gmail account from which mail to be
sent. For example, you can specify as aggarwalarpit.89@gmail.com
</div>
help-password.html
<!-- This HTML fragment will be injected into the configuration screen when the user clicks the 'help' icon of filed 'password'. -->
<div>Specify the password of gmail account from which mail to be
sent. For example, you can specify as password@gmail
</div>
After performing all the above steps, your project structure should look like as:

Step 6: Compile and package the plugin:
$ cd post-build-jenkins-plugin
$ mvn package
After packaging the plugin you should find a .hpi file in the target folder.