Writing Build Phase Jenkins Plugin

While integrating the build process of my project with Jenkins, I was looking for a way to copy the static content from my local directory to job workspace so I can leverage it at time of build process, which I thought of sharing to encourage you as well to write your own Jenkins plugins and share them with the community.

In this article we will learn how to write a Jenkins CI Plugin that executes as part of a Build process. The complete source code is hosted on github build-phase-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>copy-files-jenkins-plugin</artifactId>
 <packaging>hpi</packaging>
 <version>0.0.1</version>
 <name>Copy Files To Workspace Plugin</name>
 <url>http://wiki.jenkins-ci.org/display/JENKINS/copy-files-jenkins-plugin</url>
 <dependencies>
 </dependencies>
 <build>
 <finalName>copy-files-jenkins-plugin</finalName>
 </build>
</project>

Step 3: Create a folder under src/main/java for me it’s com.jenkins.builder and copy the CopyFilesBuilder java class with below content inside it:

package com.jenkins.builder;

import hudson.Extension;
import hudson.Launcher;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.FreeStyleProject;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.kohsuke.stapler.DataBoundConstructor;

public class CopyFilesBuilder extends Builder {
private final String path;
 
 @DataBoundConstructor
 public CopyFilesBuilder(final String path) {
  this.path = path;
 }

 public String getPath() {
  return path;
 }

 @Override
 public boolean perform(
 @SuppressWarnings("rawtypes") final AbstractBuild build,
 final Launcher launcher, final BuildListener listener)
 throws IOException {
 
 //logic to be executed by plugin
  final File file = new File(path);
  final File destination = new File(build.getWorkspace().getRemote());
 
  if (file.isDirectory()) {
  FileUtils.copyDirectory(file, destination);
  } else {
  FileUtils.copyFileToDirectory(file, destination);
  }
 
 //logger which prints on job 'Console Output'
  listener.getLogger().printf("Copying files from %s to %s", path,
  build.getWorkspace());
  return true;
 }

 @Override
 public DescriptorImpl getDescriptor() {
  return (DescriptorImpl) super.getDescriptor();
 }

 @Extension
 public static class DescriptorImpl extends BuildStepDescriptor<Builder> {

  @Override
  public boolean isApplicable(
  @SuppressWarnings("rawtypes") Class<? extends AbstractProject> jobType) {
   return FreeStyleProject.class.isAssignableFrom(jobType);
  }

  @Override
  public String getDisplayName() {
   //String to be be displayed in 'Add Build Step' dropdown
   return "Copy Files To Workspace";
  }
 }
}

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 copy files to workspace.
</div>




Step 5: Create a folder with same name as of Java class under src/main/resources/ in my case it’s com/jenkins/builder/CopyFilesBuilder and then create config.jelly and help-path.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 "path" property. When submitted, it will be passed to the corresponding constructor parameter. -->
 <f:entry title="Path" field="path">
 <f:textbox />
 </f:entry>
</j:jelly>

help-path.html






<div>
<!-- Help file for fields are discovered through a file name convention. This file is help for the "path" field. -->
Specify the path to files or folder. For example, for a particular file
specify as /users/arpitaggarwal/file.txt and for a folder specify as
/users/arpitaggarwal/
</div>






After performing all the above steps, your project structure should look like as:

Jenkins Plugin Project Structure

Step 6: Compile and package the plugin:

$ cd copy-files-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