Jenkins插件开发——新增全局参数配置
编辑前言
在jenkins插件开发的过程中,每一次build构建插件的时候,可能某些参数一直是固定的,对于这些固定的配置,可以通过jenkins插件中提供的全局参数功能来进行配置。本次就简单梳理下jenkins插件开发时如何进行全局参数的配置。
插件工程maven依赖配置
jenkins提供了一个父pom文件,它帮我们集成了开发jenkins插件所有需要的组件,同时我们需要在properties中指定jenkins的版本以及java的版本,具体的pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.4</version>
<relativePath/>
</parent>
<groupId>org.example</groupId>
<artifactId>jenkinsPlugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<!--指定jenkins版本 -->
<jenkins.version>2.303.1</jenkins.version>
<java.level>8</java.level>
</properties>
</project>
测试插件流程
本次提供的demo案例中,可以通过全局配置的一个开关设置是否打印对应的日志。
代码
首先,新增构建的主类,通过@DataBoundConstructor注解绑定页面参数:
public class MyBuilder extends Builder {
private final String name;
@DataBoundConstructor
public MyBuilder(String name) {
this.name = name;
}
}
之后新增一个内部类DescriptorImpl继承BuildStepDescriptor,注意这个类的访问级别需要是public的,同时设置@Extension注解(详细可参考jenkins源码):
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Builder> {}
在DescriptorImpl中,我们需要重写isApplicable和getDisplayName两个方法,分别表示插件是否可见以及插件默认显示名称:
@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}
// 插件任务在jenkins上面的显示名称
@NonNull
@Override
public String getDisplayName() {
return PLUGIN_NAME;
}
还需要重写DescriptorImpl中的config方法,该方法提供了一个JSONObject类型的参数,可以通过该参数获得页面传过来的全局参数,同时需要调用save方法,该方法是将当前的全局配置持久化到磁盘,jenkins默认保存的是xml格式:
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Builder> {
@Getter
@Setter
private boolean printLog;
@Getter
@Setter
private String log;
@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
// 获取页面参数
printLog = json.getBoolean("printLog");
log = json.getString("log");
// 将配置写入磁盘
save();
return super.configure(req, json);
}
}
这边的两个成员变量printLog,log和全局参数进行的绑定,具体可以看下下面的global.jelly参数文件。
完整构建主类代码如下:
/**
* 测试jenkins插件
*
* @author yuanzhihao
* @since 2022/6/14
*/
public class MyBuilder extends Builder {
private final String name;
@DataBoundConstructor
public MyBuilder(String name) {
this.name = name;
}
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
PrintStream logger = listener.getLogger();
logger.println("Hello " + name);
boolean printLog = getDescriptor().isPrintLog();
if (printLog) {
logger.println("Log is " + getDescriptor().getLog());
}
return true;
}
@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Builder> {
@Getter
@Setter
private boolean printLog;
@Getter
@Setter
private String log;
private static final String PLUGIN_NAME = "MyPlugin";
public DescriptorImpl() {
load();
}
@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}
// 插件任务在jenkins上面的显示名称
@NonNull
@Override
public String getDisplayName() {
return PLUGIN_NAME;
}
@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
printLog = json.getBoolean("printLog");
log = json.getString("log");
// 将配置写入磁盘
save();
return super.configure(req, json);
}
}
}
配置
在resources目录配置对应的页面文件:
-
构建的主类
-
jelly文件存放的目录,要和主类保持一致
-
config.jelly文件中配置通过@DataBoundConstructor注解绑定的页面参数,本次配置具体如下:
<?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="Name" field="name"> <f:textbox value="${name}"/> </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"> <f:section title="My First Jenkins Plugin"> <f:entry title="printLog" field="printLog" description="Check if print Log"> <f:checkbox checked="${printLog}" /> </f:entry> <f:entry title="log" field="log" description="The Log message"> <f:textbox value="${log}"/> </f:entry> </f:section> </j:jelly>
-
index.jelly需要放到resources目录下面,这个文件中配置了插件的描述:
<!-- This view is used to render the plugin list page. Since we don't really have anything dynamic here, let's just use static HTML. --> <?jelly escape-by-default='true'?> <div> My First Jenkins Plugin! </div>
调试
执行mvn hpi:run 命令,启动一个本地的jenkins,通过默认的路径http://localhost:8080/jenkins,可以访问默认安装开发插件的jenkins,之后可以验证我们开发的插件。
启动完成之后,在jenkins的配置页面http://localhost:8080/jenkins/configure ,可以看到我们新增的全局参数配置: 新增一个Job任务,选择我们开发的插件,添加参数: 构建任务,可以发现全局参数已经生效:
总结
参考链接:http://www.jenkins.io/zh/doc/developer/plugin-development/
代码地址:https://github.com/yzh19961031/blogDemo/tree/master/jenkinsPlugin