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目录配置对应的页面文件:

jenkins系统管理 全局工具配置 jenkins新增全局变量_jenkins系统管理 全局工具配置

  1. 构建的主类
  2. jelly文件存放的目录,要和主类保持一致
  3. 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>
  1. 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>
  1. 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,可以看到我们新增的全局参数配置:

jenkins系统管理 全局工具配置 jenkins新增全局变量_json_02


新增一个Job任务,选择我们开发的插件,添加参数:

jenkins系统管理 全局工具配置 jenkins新增全局变量_xml_03


构建任务,可以发现全局参数已经生效:

jenkins系统管理 全局工具配置 jenkins新增全局变量_jenkins_04

总结

参考链接:http://www.jenkins.io/zh/doc/developer/plugin-development/

代码地址:https://github.com/yzh19961031/blogDemo/tree/master/jenkinsPlugin