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插件開發

相關文章
相關標籤/搜索