允许构建步骤插件多次运行

bri*_*rns 5 jenkins jenkins-plugins

我正在为Jenkins创建一个插件,它添加了一种新的post build步骤(Publisher).当我尝试创建一个新作业时,我只能添加一次新步骤(更糟糕的是,它在构建后步骤菜单中显示为灰色).我希望能够将它添加到同一个作业中,每个作业都有不同的配置(即我的Publisher子类的不同实例).如何做到这一点,以及詹金斯只允许一次添加它的原因是什么?

更新

我看起来这与<f:repeatable>果冻元素有某种关系,但我无法弄清楚如何使用它,并且无法找到它的任何信息.我试图遵循HTML Publisher插件,但一直收到错误.如果有人可以解释如何使用它,或指向一个参考,那将是伟大的!

bri*_*rns 2

经过多次尝试和错误后,终于能够基于 HTML Publisher 插件弄清楚了。

我正在创建的构建步骤是可重复的,这意味着您只能将其添加到每个作业一次,但您可以有效地添加它的多个“实例”。每个实例具有三个属性:namefileheight。我的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>
Run Code Online (Sandbox Code Playgroud)

这会在项目配置屏幕中生成类似以下内容的内容:

构建步骤配置

这是在该特定页面上手动添加和编辑两个“实例”之后发生的。

关键是可重复的每个“实例”都需要构建到某种对象中。这就像通常从表单实例化构建步骤一样,只不过它不是构建步骤本身,而是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 "";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这非常简单,它基本上只是字段周围的对象包装器。

因此,要实际实例化 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

就是这样。现在,在perform方法中,以及类似的东西getProjectActions,您可以迭代this.targets,例如,或者任何您需要做的事情。