Jenkins插件开发入门指南

背景

Jenkins作为一款开源的持续集成工具,在日常的开发、集成、部署等环节中应用十分广泛。Jenkins的环境搭建和配置就不多说了,网上有很多相关资料,总体使用流程也非常简单。Jenkins的一大特点就是基于插件的高可扩展性,在使用过程中我们可以发现,Jenkins的许多功能都是通过插件进行集成的,例如

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

在常规使用过程中,一些基本的插件就可以满足要求,但总有那么些奇怪的要求不能很快的找到对应的插件,那就需要自己开发了。

开发环境搭建

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

<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>
复制代码

开发和调试

官方的插件开发插件:链接。具体步骤如下:

  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为例,如下既可:

如何开发

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

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

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

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。

通知

  • 需求:既然已经提到了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文件的位置相匹配。

<?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插件开发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值