打开命令提示符,找到您想要存储新 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="demo@1.0-SNAPSHOT"> <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 输出。 它有许多有用的功能:它
在 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 官网上的指南一模一样? 因为那也是我翻译的(捂脸) 复制代码