I wrote it because there were few Japanese documents that describe how to develop the Jenkins plugin. It summarizes the knowledge you will need if you try to go one step further from the Tutorial (https://jenkins.io/doc/developer/tutorial/prepare/). Information as of April 2018.
JDK and maven are required for plugin development. Install jdk and maven by referring to Plugin Development Tutorial.
Generate a project template with maven.
mvn -U archetype:generate -Dfilter=io.jenkins.archetypes:
When you execute the command, you will be asked some questions such as the type of template and artifact ID (plug-in name) interactively, so please answer appropriately. After creating the template, check that Jenkins starts at http: // localhost: 8080 / jenkins with the following command.
mvn hpi:run
The developed plug-in will be inserted in Jenkins started here. You can check the operation of the plugin on this Jenkins.
Plugins are a class that inherits Jenkins extension points. When creating a plug-in, select an extension point that matches the function to be extended by the plug-in, and create a class that inherits it. Then, we will implement the function by overriding the method of the extension point. For example, if you override the perform method in a class that inherits Builder, which is an extension point of the build procedure, a plugin that adds a new build procedure. You can make an inn.
Extension point list allows you to see actual examples of plugins created by inheriting it for each extension point. Useful for selecting and implementing extension points.
You cannot use the plugin from Jenkins just by creating the main body class. In order to use the plugin, you need to notify Jenkins of the existence of the plugin. To do this, you need to create a Desctiptor as the inner class of the body class and annotate it with @Extention
.
For example, if you look at AWS CodeBuild Plugin Body Class, the DescriptorImpl class is It is defined as an inner class and annotated with @Extension
. DescriptorImpl inherits BuildStepDescriptor, but Descriptor defined as an inner class like this must inherit from the existing Descriptor. The Descriptor to inherit is different for each extension point. You can find out which Descriptor should be inherited from the example in Extension points list.
Plugins can have two settings, global and per job. Global settings are displayed in "Jenkins Management-> System Settings" on the Jenkins top page, and job-specific settings are displayed in "Settings" for each job. Here's how to add each setting.
Create global.jelly to display the settings input form. If the body of the plugin is located in src / main / java / jenkins / plugins / hoge / fuga, then global.jelly should be located in src / main / ** resources ** / jenkins / plugins / hoge / fuga .. It is good to refer to the existing plugin for how to write global.jelly. For example, if you want to add the name of MyPlugin as a setting, create the following global.jelly.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:section title="${%MyPlugin}" name="MyPlugin">
<f:entry title="${%name}" field="name">
<f:textbox />
</f:entry>
</f:section>
</j:jelly>
Next, modify the Descriptor so that it can read the entered settings. The settings are passed as an argument of type JSONObject to the configure method of Descriptor. In the case of global.jelly above, you can retrieve the name by modifying the Descriptor as follows.
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Builder> {
private String name;
public DescriptorImpl(){
load(); //Load previously saved global settings
}
@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
json = json.getJSONObject("MyPlugin"); //Global settings are passed in the json argument
name = json.getString("name");
save();//Save global settings
return true;
}
public String getName(){ //Prepare a getter so that the body class can retrieve the name
return name;
}
.
.
.
The body class must retrieve the value from the Descriptor to take advantage of the global settings. To do this, make the following modifications to the body class.
public class MyPlugin extends Builder implements SimpleBuildStep {
@Override
public Descriptor getDescriptor() { //Descriptor getter
return (Descriptor) super.getDescriptor();
}
@Override
public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {
getDescriptor().getName(); //Get name from Descriptor
}
.
.
.
}
Create config.jelly to display the configuration input form. As with adding global settings, if the plugin body is located in src / main / java / jenkins / plugins / hoge / fuga, config.jelly will be src / main / ** resources ** / Place it in jenkins / plugins / hoge / fuga. For example, if you want to add color as a setting, create the following config.jelly.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:entry title="${%Color}" field="color">
<f:textbox />
</f:entry>
</j:jelly>
In order to use the settings for each job in the body class, it is necessary to annotate the constructor with @DataBoundConstructor
and add an argument.
@DataBoundConstructor
public class MyPlugin extends Builder implements SimpleBuildStep {
final private String color;
@DataBoundConstructor
public MyPlugin(String color){
this.color = color; //Job-specific settings are passed as arguments
}
.
.
.
}
I explained the basic development method of the Jenkins plugin. For more practical things, I think you should learn from the examples in Extension Points.
document | URL |
---|---|
Jenkins developer documentation | https://jenkins.io/doc/developer/ |
Plugin creation tutorial | https://jenkins.io/doc/developer/tutorial/ |
List of functions that can be extended by plugins | https://jenkins.io/doc/developer/extensions/jenkins-core/ |
Jenkins developer wiki | https://wiki.jenkins.io/display/JENKINS/Extend+Jenkins |
Jenkins JavaDoc | http://javadoc.jenkins-ci.org/ |
Recommended Posts