我正在为Jenkins创建一个插件,它添加了一种新的post build步骤(Publisher)。当我尝试创建一个新作业时,我只能添加一次新步骤(更糟糕的是,它在构建后步骤菜单中显示为灰色)。我希望能够将它多次添加到同一个作业中,每个作业都有不同的配置(即我的Publisher子类的不同实例)。如何做到这一点,以及詹金斯只允许一次添加它的原因是什么?
更新
我看起来这与<f:repeatable>
果冻元素有某种关联,但我无法弄清楚如何使用它,也找不到任何关于它的信息。我试图遵循HTML Publisher插件,但一直收到错误。如果有人可以解释如何使用它,或指向一个参考,那将是伟大的!
答案 0 :(得分:2)
最后能够在基于HTML Publisher插件的大量试验和错误后弄明白。
我正在创建的构建步骤是可重复的,这意味着您只能将其添加到每个作业一次,但您可以有效地添加它的多个“实例”。每个实例都有三个属性:name
,file
和height
。我的config.jelly
文件如下所示:
<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>
<f:repeatable field='targets'>
<f:textbox field='name' default='Report' />
<f:textbox field='file' default='report.html' />
<f:number field='height' default='300' /> px
<f:repeatableDeleteButton value='Delete report' />
</f:repeatable>
</f:entry>
</j:jelly>
这会在project-config屏幕中生成如下内容:
这是在此特定页面上手动添加和编辑两个“实例”之后。
关键是可重复的每个“实例”都需要构建到某种对象中。这就像通常从表单实例化构建步骤一样,除了它不是构建步骤本身,它是AbstractDescribablyImpl
的子类。我看起来像这样:
public static class Target extends AbstractDescribableImpl<Target>
{
public String name;
public String file;
public int height;
// Fields in config.jelly must match the parameter names in the "DataBoundConstructor"
@DataBoundConstructor
public Target(String name, String file, int height) {
this.name = name;
this.file = file;
this.height = height;
if(this.name == null) {
throw new RuntimeException("Name is NULL!");
}
}
public String getName() {
return this.name;
}
public String getFile() {
return this.file;
}
public int getHeight() {
return this.height;
}
@Extension
public static class DescriptorImpl extends Descriptor<Target> {
@Override
public String getDisplayName() {
return "";
}
}
}
这很简单,它基本上只是一个围绕字段的Object包装器。
那么为了实际实例化BuildStep本身,你必须接受你刚创建的那个类型的列表来表示步骤的每个“实例”(在我的例子中,是上面的Target
类,这是我构建步骤的内部类)。所以它看起来像这样:
public class EmbedReportPublisher extends Publisher
{
private List<Target> targets;
public static class Target extends AbstractDescribableImpl<Target>
{
// ... shown above ...
}
@DataBoundConstructor
public EmbedReportPublisher(List<Target> targets) {
if (targets == null) {
this.targets = new ArrayList<Target>(0);
}
else {
this.targets = new ArrayList<Target>(targets);
}
}
}
就是这样。现在,在perform
方法和getProjectActions
之类的内容中,您可以迭代this.targets
,例如,或者您需要做的任何事情。