我是如何一步步開發我的第一個 Jenkins plugin 的
開發環境
Java 8 及以上
Maven 3.3.9 以上
複製程式碼
建立你的第一個外掛
使用示例外掛原型建立專案結構
開啟命令提示符,找到您想要儲存新 Jenkins 外掛的目錄,然後執行以下命令:
$ mvn -U archetype:generate -Dfilter=io.jenkins.archetypes:
複製程式碼
使用 hello-world
原型。選擇 1.4
,artifactId
輸入 demo
。一路回車。
$ mvn -U archetype:generate -Dfilter=io.jenkins.archetypes:
…
Choose archetype:
1: remote -> io.jenkins.archetypes:empty-plugin (Skeleton of a Jenkins plugin with a POM and an empty source tree.)
2: remote -> io.jenkins.archetypes:global-configuration-plugin (Skeleton of a Jenkins plugin with a POM and an example piece of global configuration.)
3: remote -> io.jenkins.archetypes:global-shared-library (Uses the Jenkins Pipeline Unit mock library to test the usage of a Global Shared Library)
4: remote -> io.jenkins.archetypes:hello-world-plugin (Skeleton of a Jenkins plugin with a POM and an example build step.)
5: remote -> io.jenkins.archetypes:scripted-pipeline (Uses the Jenkins Pipeline Unit mock library to test the logic inside a Pipeline script.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 4
Choose io.jenkins.archetypes:hello-world-plugin version:
1: 1.1
2: 1.2
3: 1.3
4: 1.4
Choose a number: 4: 4
[INFO] Using property: groupId = unused
Define value for property artifactId: demo
Define value for property version 1.0-SNAPSHOT: :
[INFO] Using property: package = io.jenkins.plugins.sample
Confirm properties configuration:
groupId: unused
artifactId: demo
version: 1.0-SNAPSHOT
package: io.jenkins.plugins.sample
Y: : y
複製程式碼
構建外掛
$ mv demo demo-plugin
$ cd demo-plugin
$ mvn verify
複製程式碼
Maven 將下載更多的依賴項,然後遍歷配置的構建週期,包括靜態分析(FindBugs)和測試,直到它顯示像下面的文字:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:24 min
[INFO] Finished at: 2018-11-19T20:48:40+08:00
[INFO] Final Memory: 73M/872M
[INFO] ------------------------------------------------------------------------
複製程式碼
構建並執行外掛
Maven HPI 外掛用於構建和打包 Jenkins 外掛。 它還提供了一個使用外掛執行 Jenkins 例項的便捷方式:
$ mvn hpi:run
複製程式碼
這將在 http://localhost:8080/jenkins/
建立一個 Jenkins
例項。等待以下控制檯輸出,然後開啟 Web 瀏覽器並檢視外掛的功能。
資訊: Jenkins is fully up and running
複製程式碼
在 Jenkins 建立一個自由風格的專案,並給它任意起一個名稱。
然後新增 “Say hello world” 構建步驟
輸入名稱,儲存專案並開始新的構建。找到 UI 上的構建,然後單擊檢視 構建日誌。 它將包含由剛剛配置的構建步驟輸出的訊息:
Started by user anonymous
Building in workspace /Users/mrjenkins/demo/work/workspace/testjob
Hello, Jenkins!
Finished: SUCCESS
複製程式碼
擴充套件你的外掛
記錄名稱
首先,在與 HelloWorldBuilder 相同的包中建立一個名為 HelloWorldAction 的類。 該類需要實現 Action。 Actions 是 Jenkins 中可擴充套件性的基本構建塊:它們可以附加到許多模型物件上並被儲存起來,並可以新增到它們的 UI 中。
package io.jenkins.plugins.sample;
import hudson.model.Action;
public class HelloWorldAction implements Action {
@Override
public String getIconFileName() {
return null;
}
@Override
public String getDisplayName() {
return null;
}
@Override
public String getUrlName() {
return null;
}
}
複製程式碼
由於我們要儲存問候中使用的名稱,因此我們需要為此類新增一個 getter。我們還將新增一個以 name 為引數的構造方法。
(...)
public class HelloWorldAction implements Action {
private String name;
public HelloWorldAction(String name) {
this.name = name;
}
public String getName() {
return name;
}
(...)
複製程式碼
現在,我們實際上需要在構建步驟執行時建立該類的一個例項。 我們需要擴充套件 HelloWorldBuilder 類中的 perform 方法來把我們建立的動作的一個例項新增到正在執行的構建中:
(...)
@Override
public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {
run.addAction(new HelloWorldAction(name));
if (useFrench) {
listener.getLogger().println("Bonjour, " + name + "!");
} else {
listener.getLogger().println("Hello, " + name + "!");
}
}
(...)
複製程式碼
儲存這些修改,然後用 mvn hpi:run
再次執行外掛。
每當修改 Java 原始碼或新增刪除資原始檔時,您都需要重新啟動 Jenkins 例項才能使修改生效。 Jenkins 通過 hpi:run 執行時只能編輯一些資原始檔。
現在,使用此構建步驟執行構建時,該操作將被新增到構建資料中。 我們可以通過檢視與work/jobs/JOBNAME/builds/BUILDNUMBER/
目錄中的構建版本相對應的 build.xml
檔案來確認。
我們可以看到,這個構建中有兩個動作:
<build>
<actions>
<hudson.model.CauseAction>
<causes>
<hudson.model.Cause_-UserIdCause/>
</causes>
</hudson.model.CauseAction>
<io.jenkins.plugins.sample.HelloWorldAction plugin="[email protected]">
<name>Jenkins</name>
</io.jenkins.plugins.sample.HelloWorldAction>
</actions>
(...)
</build>
複製程式碼
新增一個顯示名稱的檢視
接下來,我們需要使我們正在儲存的構建視覺化。
首先,我們需要回到過去 HelloWorldAction
並定義圖示,標題和 URL 名稱:
@Override
public String getIconFileName() {
return "document.png";
}
@Override
public String getDisplayName() {
return "Greeting";
}
@Override
public String getUrlName() {
return "greeting";
}
複製程式碼
通過這些修改,操作將顯示在構建的側面板中,並連結到 URL http://JENKINS/job/JOBNAME/BUILDNUMBER/greeting/。
接下來,需要定義出現在該 URL 上的頁面。 為了在 Jenkins 建立這樣的 檢視 , 通常使用 Apache Commons Jelly。 Jelly 允許用 XML 定義 XML 和 XHTML 輸出。 它有許多有用的功能:它
- 支援條件和迴圈
- 允許包含在其他地方定義的 view fragments
- 可用於定義可重用的UI元件
在src/main/resources/io/jenkins/plugins/sample/
中, 我們需要建立一個新的名為HelloWorldAction/
的目錄。 該目錄與 HelloWorldAction
類對應幷包含相關資源。 在 src/main/resources/io/jenkins/plugins/sample/HelloWorldAction/
目錄建立名為 index.jelly
的檔案。 這將會顯示在 http://JENKINS/job/JOBNAME/BUILDNUMBER/greeting/
URL 上。 新增以下內容:
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout" xmlns:st="jelly:stapler">
<l:layout title="Greeting">
<l:main-panel>
<h1>
Name: ${it.name}
</h1>
</l:main-panel>
</l:layout>
</j:jelly>
複製程式碼
將構建的側面板新增到檢視
在上面的輸出中沒有側面板,由於此檢視與特定版本相關,因此應該顯示該版本的側面板。 為此,我們首先需要獲取對我們動作中相應構建的引用,然後在動作檢視中包含構建的側面檢視 fragment
為了獲得 HelloWorldAction
所屬的構建(或者更一般地說, Run
的引用),我們需要改變現有的類以使其實現 RunAction2
該介面添加了兩個方法,當執行首次連線到構建時 onAttached(Run)
,以及從磁碟 onLoad(Run)
載入操作和執行時分別呼叫該方法。
(...)
import hudson.model.Run;
import jenkins.model.RunAction2;
public class HelloWorldAction implements RunAction2 {
private transient Run run;
@Override
public void onAttached(Run<?, ?> run) {
this.run = run;
}
@Override
public void onLoad(Run<?, ?> run) {
this.run = run;
}
public Run getRun() {
return run;
}
(...)
複製程式碼
這些一旦完成之後,我們需要將擴充套件這個檢視來將 Run
的側面板檢視片段 包含 進來:
(...)
<l:layout title="Greeting">
<l:side-panel>
<st:include page="sidepanel.jelly" it="${it.run}" optional="true" />
</l:side-panel>
<l:main-panel>
(...)
</l:main-panel>
</l:layout>
(...)
複製程式碼
有了這些修改,我們建立的檢視與 Jenkins UI 正確整合,與構建版本相關的內建頁面沒有任何區別。
恭喜,您已成功建立並大幅擴充套件了 Jenkins 外掛!
覺得和 Jenkins 官網上的指南一模一樣?
因為那也是我翻譯的(捂臉)
複製程式碼