Writing Post Build Jenkins Plugin

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:

Post Build Jenkins Plugin Project Structure

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s