Plug-in Development of Jenkins Tour: within two days from the idea to publish (Part I)
It was just a few days ago when I was discussing with friends the challenges of managing Maven SNAPSHOT versions in dependency management. The issues we were facing were not unique, and I had previously struggled with similar problems. The difficulty of dealing with SNAPSHOT versions had left a lasting impression on me.
As I began to develop norms for Maven usage, I decided to ban SNAPSHOT versions from being sent to the production environment. To enforce this, I implemented a check during the Jenkins build process. Since I couldn’t find a plug-in that provided similar functionality, I resorted to using shell scripts. The approach I chose was to add an “Execute shell” step before the Jenkins Maven build task, which would check for the presence of the “SNAPSHOT” keyword in the pom.xml file. If found, the sub-construct would be marked as failed.
Here is the script:
#!/bin/bash
if [[ `grep -R --include="pom.xml" SNAPSHOT` =~ "SNAPSHOT" ]]; then
echo "SNAPSHOT check failed" && grep -R --include="pom.xml" SNAPSHOT && exit 1
else
echo "SNAPSHOT check success"
fi
Not long after, I stumbled upon the Jenkins plug-in development documentation and thought, “Why not implement it as a Jenkins plug-in?” So, I embarked on my first plug-in development journey.
Plug-in Development Process
Jenkins is a powerful open-source CI/CD engine developed in Java. The Jenkins ecosystem is vast, and its plug-in architecture allows users to extend its functionality. The Jenkins community boasts thousands of plug-ins, which users can select and customize according to their needs.
Ready to Plug-in Development
Before developing a plug-in, plug-in developers need to install JDK and Maven. These tools are essential for building and packaging plug-ins.
Create a Plug-in
Jenkins provides a Maven archetype for plug-in development. To create a new plug-in, open a command-line terminal and change to the directory where you want to store the plug-in source code. Run the following command:
mvn -U archetype:generate -Dfilter=io.jenkins.archetypes
This command allows you to use a prototyping project related to Jenkins.
Choose the archetype:
- remote → io.jenkins.archetypes: empty-plugin (Skeleton of a Jenkins plugin with a POM and an empty source tree.)
- remote → io.jenkins.archetypes: global-configuration-plugin (Skeleton of a Jenkins plugin with a POM and an example piece of global configuration.)
- remote → io.jenkins.archetypes: hello-world-plugin (Skeleton of a Jenkins plugin with a POM and an example build step.)
Choose a number or apply filter (format: [groupId:] artifactId, case sensitive contains): 3
Choose io.jenkins.archetypes: hello-world-plugin version:
- 1.12
- 1.23
- 1.34
- 1.4
Choose a number: 4
[INFO] Using property: groupId = unused
Define value for property ‘artifactId’: maven-snapshot-check
Define value for property ‘version’: 1.0-SNAPSHOT
[INFO] Using property: package = io.jenkins.plugins.sample
Confirm properties configuration:
groupId: unused
artifactId: maven-snapshot-check
version: 1.0-SNAPSHOT
package: io.jenkins.plugins.sample
Y: Y
I chose the hello-world-plugin prototype and filled in some parameters, such as artifactId and version. This became a project, and I used mvn verify to verify that it was successfully constructed.
Construction and Operation of Plug-ins
Maven HPI Plugin is used to build and package plug-ins. It provides a convenient way to run a current instance of Jenkins that already contains a plug-in. To do this, run the following command:
mvn hpi:run
This will install a Jenkins instance, and you can access it at http://localhost:8080/jenkins/.
Wait for the console output to complete, and then open a Web browser to view the plug-in.
Custom Development of Plug-ins
Jenkins plug-in development is made possible by a series of extension points. Developers can extend and implement custom functionality using these points.
Here are a few important concepts and instructions:
- Extension points (ExtensitonPoint): Jenkins is an extension point system that provides an interface or abstract class. The interface defines the methods that need to be implemented, and Jenkins plugins need to implement these methods.
- Data Binding: The front page of data needs to interact with the back-end server, which requires data binding. The front end of
config.jellypage code fragment is as follows:
This code fragment needs to be included in the parameters passed<?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 "> <F: entry title = "check" field = "check"> <F: checkbox /> </F: entry> </J: jelly>config.jellyrequired configuration information selection box, as Field Check, which can be configured in Jenkins, and then through binding DataBoundConstructor data, passing parameters to Java code. - Server-side Java code fragment is as follows:
@DataBoundConstructor public MavenCheck (boolean check) { this.check = check; }
Distribution Plug-in
The plug-in can be packaged as a suffix hpi binary package using the mvn package command, so that it can be distributed and installed in a Jenkins instance.
Plug Instruction
The following is a brief description of the use of plug-ins. If you check the checkbox below screenshot, Jenkins task when building will check the pom.xml contains SNAPSHOT. If it is checked, then, the time will build state marked as failed.
Articles on this Review
The process from idea to produce the finished plug-in development is reviewed in this article. The next article will introduce how the plug-in is developed into a managed Jenkins Update Center plugin so that all users can see it.