Jenkins插件开发入门指南

背景

Jenkins做为一款开源的持续集成工具,在平常的开发、集成、部署等环节中应用十分普遍。Jenkins的环境搭建和配置就很少说了,网上有不少相关资料,整体使用流程也很是简单。Jenkins的一大特色就是基于插件的高可扩展性,在使用过程当中咱们能够发现,Jenkins的许多功能都是经过插件进行集成的,例如php

  • 支持python脚本
  • Pipeline功能
  • Git插件
  • 支持Gradle脚本
  • 各种结果通知插件
  • 等等

在常规使用过程当中,一些基本的插件就能够知足要求,但总有那么些奇怪的要求不能很快的找到对应的插件,那就须要本身开发了。html

开发环境搭建

安装JDK和maven,添加环境变量,增长maven配置java

<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>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>
    </profile>
  </profiles>
</settings>
复制代码

开发和调试

官方的插件开发插件:连接。具体步骤以下:python

  1. 建立项目,此时会有提示分别须要输入groupId和artifactId,前者可使用默认值,后者是插件的名称,并会被做为项目的文件夹名。
mvn -U hpi:create
复制代码
  1. 项目建立完毕后,可使用以下命令尝试进行检查。
cd plugin-name(artifactId)
mvn verify
复制代码
  1. 随后就能够进入正常开发,过程当中使用以下命令进行运行,此命令会打开一个本地的带当前开发插件的jenkins服务器,地址为http://localhost:8080/jenkins
mvn hpi:run
复制代码
  1. 若是须要断点调试,能够运行以下命令,此命令会在8000端口创建监听,而后能够在IDE中配置对应的Run/Debug Configuration,配置完后运行Debug就会自动触发插件编译和运行流程。
mvnDebug hpi:run
复制代码
  1. IDE配置以IntelliJ为例,以下既可:

IntelliJ配置图

如何开发

官方提供了一个样例教程:Extend the Plugin,样例介绍了如何开发一个继承自Action的组件,并显示在job运行状态页面的侧边栏上。shell

官方还有相关的API文档:文档api

固然整体来讲相关的插件开发文档并不算不少,接下来就以两个实际的需求场景来说解一下Jenkins插件的开发。bash

API

  • 需求:在代码仓库中,当一名开发人员向另外一名开发人员提pull request后但愿能够先自动构建代码,验证代码可用性。
  • 分析:对于这样的一个需求天然要用到代码仓库中的Web Hook功能,即在代码仓库中触发某些行为后会向开发者指定的url发送请求。那么此时咱们就须要在Jenkins的Server建立对应的API接口响应请求。

对于这样一个需求,是否须要额外开个端口响应请求呢?Jenkins有没有这样的扩展方式呢? 答案是确定的,Jenkins官方提供了Remote Access API相关功能及扩展。官方文档中提到了Jenkins自带的一些Remote Access API,那如何自定义一个API呢?具体步骤以下:服务器

  1. 继承Plugin类,并重写其getApi方法,方法中返回一个自定义的Api实例
public class HookPlugin extends Plugin {
    public Api getApi() {
        return new HookApi(this);
    }
}
复制代码
  1. 自定义一个Api类,建立一个方法,并为这个方法添加WebMethod注解
public class HookApi extends Api {
    @WebMethod(name = "pull_request_build")
	public void doPullRequestBuild(StaplerRequest req, StaplerResponse resp) throws IOException {
        // do something
	}
}
复制代码

到此为止,一个接口就开发完成了,过程至关简单。接口地址为{jenkins_host}/plugin/{plugin-name}/api/pull_request_build,其中plugin-name就是前文中建立插件时输入的artifactId。maven

通知

  • 需求:既然已经提到了pull request预构建,那构建过程总不能让用户干等着,得经过一些方式通知到用户。
  • 分析:这类功能属于jenkins中的常规功能需求,经常使用的就有E-mail Notification,而对于许多公司而言可能有公司内部或者第三方的即时通讯软件,那就须要本身开发插件来进行适配。
  1. 继承Notifier类,主要重写perfomr方法,Descriptor相关方法可选择,其主要是对插件的界面进行处理
public class IMNotifier extends Notifier {
    private final String user;
    @DataBoundConstructor
    public IMNotifier(String user) {
        this.user = user;
    }
  
    @Override
    public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
        // do something
    }
  
    // 使用自定义的Descriptor
    @Override
    public DescriptorImpl getDescriptor() {
        return (DescriptorImpl) super.getDescriptor();
    }
 
    @Extension
    public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> {
 
        @Override
        public boolean isApplicable(Class<? extends AbstractProject> aClass) {
            return true;
        }
 
        @Override
        public String getDisplayName() { // 插件在界面上展现的名字
            return "IM Notification";
        }
 
        public FormValidation doCheckDefaultUser(@QueryParameter String value) { // 对输入框进行校验
            if (value.length() == 0) {
                return FormValidation.error("Please set a user");
            }
            return FormValidation.ok();
        }
    }
}
复制代码
  1. 假设这个通知插件咱们须要在配置的时候指定一个用户,那就须要开发插件界面。jenkins插件的界面编写采用的是jelly,一个正常的插件分红3个jelly文件:
  • index.jelly表明此插件的概要描述,能够在插件列表中看到
  • global.jelly表明此插件的全局配置
  • config.jelly表明此插件在单个job中的配置

因此在这个需求中,咱们须要修改config.jelly,添加一个输入框,具体代码以下,须要注意其中field要和IMNotifier中的参数名一致,jelly文件的位置也须要和IMNotifier文件的位置相匹配。ide

<?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="User" field="user">
    <f:textbox />
  </f:entry>
</j:jelly>
复制代码

发布

插件功能开发完成后就可使用如下命令进行编译:

mvn clean install
复制代码

编译完成后会生成一个hpi文件,手动上传到jenkins服务器安装便可。

总结

从上文的两个样例来看,Jenkins插件并不复杂,其中的关键点在于找到系统相关的API做为切入点。例如Builder是构建过程,Notifier是构建后过程,远程接口就要继承Plugin等等。官方有一个扩展点的文档能够进行参考:扩展文档。开发过程当中能够根据实际需求在任何扩展点进行扩展。

参考文献

Play with Jenkins Remote Api

jenkins插件开发

相关文章
相关标签/搜索