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.