Могут ли два разных компоновщика jenkins существовать в одном hpi и использовать одну и ту же глобальную конфигурацию?

Мне нужно создать два разных класса Jenkins Builder. Каждый из них выполняет разные функции, и каждый требует своего собственного.jelly, однако оба требуют одинаковой глобальной конфигурации (global.jelly), которая указывает хост и некоторые учетные данные пользователя.
Экземпляры обоих типов компоновщика во время их выполнения () будут подключаться к хосту (указанному в глобальной конфигурации) с использованием учетных данных (также указанных в глобальной конфигурации).

Проблема в том, что в Jenkins вы размещаете ресурсы каждого компоновщика в папке, соответствующей имени класса компоновщика И в этот файл ресурсов входит global.config.

Если я скопирую конфигурацию в обе папки ресурсов компоновщика, я получу два идентичных глобальных раздела конфигурации...

Можно ли создать один.hpi с двумя классами Builder, каждый из которых имеет свои собственные файлы config.jelly и help.html, но оба имеют одинаковую глобальную конфигурацию (global.jelly)?

2 ответа

Да, это очень возможно, но не в обычном способе расширения Builder. Вам нужно будет использовать его как JobProperty. Давайте рассмотрим пример, чтобы объяснить, как это делается.

У вас будет минимум 3 класса / пакета.

  • MyPluginClass - Имеет поля для всех ваших глобальных настроек.
  • MyBuildStepAClass - Имеет реализацию сборки шага А.
  • MyBuildStepBClass - Имеет реализацию этапа сборки B.

Код для ваших классов шагов сборки MyBuildStepAClass а также MyBuildStepBClass будет таким же, как вы обычно пишете для плагина с одним шагом сборки. Ниже приведен образец для MyBuildStepAClass..

public class MyBuildStepAClass {
    private String name;
    .....

    @DataBoundConstructor
    public MyBuildStepAClass(String name, ....) {
        this.name = name;
        ....
    }

    public String getName() {
        return name;
    }

    public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
       //logic for perform.
       ............
       return true;
    }

    @Extension
    public static class Descriptor extends BuildStepDescriptor<Builder> {

         public Descriptor() {
            load();
         }

         @Override
         public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
             req.bindJSON(this, formData);
             save();
             return super.configure(req,formData);
         }

         @Override
         public String getDisplayName() {
             return "My Build Step A";
         }
    }
}

Чтобы разделить конфигурацию между обоими классами плагинов, Вы расширите свой MyPluginClass от JobProperty<Job<?,?>> (вместо Builder) и переопределить getDescriptor() метод для возврата дескриптора, используя Jenkins.getInstance().getDescriptor(getclass());

public class MyPluginClass extends JobProperty<Job<?, ?>>  {

    @Override
    public MyPluginClassDescriptor getDescriptor() {
        return (MyPluginClassDescriptor)Jenkins.getInstance().getDescriptor(getClass());
    }

    public static MyPluginClassDescriptor getMyPluginClassDescriptor() {
        return (MyPluginClassDescriptor)Jenkins.getInstance().getDescriptor(MyPluginClass.class);
    }


    @Extension
    public static final class MyPluginClassDescriptor extends JobPropertyDescriptor {

        private String globalField1 = "";

        public MyPluginClassDescriptor() {
            super(MyPluginClass.class);
            load();
        }

        @Override
        public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
            req.bindJSON(this, formData);
            save();
            return super.configure(req,formData);
        }

        @DataBoundConstructor
        public MyPluginClassDescriptor(String globalField1, ....) {
            this.globalField1 = globalField1;
        }

        @Override
        public String getDisplayName() {
            return "IIBCI Plugin Configuration";
        }
        public getGlobalField1() {
            return globalField1;
        }
}

Содержимое ваших global.jelly и отдельных файлов config.jelly для каждого шага сборки будет нормальным, как вы бы сослались на них. Надеюсь, это поможет вам понять, как JobProperty помогает вам иметь единую конфигурацию, доступную на разных этапах сборки.

ОБНОВЛЕНО, чтобы включить информацию о файлах желе.

У вас будет один файл global.jelly в пакете для MyPluginClass, Этот желейный файл будет содержать поля, которые вы хотите отобразить / сохранить в глобальной конфигурации.

<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:section title="MyPlugin configuration">
    <f:entry title="Global field1" field="globalField1">
      <f:textbox  />
    </f:entry>
  </f:section>
</j:jelly>

Каждый из ваших шагов сборки будет иметь свои собственные файлы index.jelly, которые будут содержать код jelly, специфичный для шага сборки. Надеюсь, что это делает это более ясным..

Избежать global.jelly в целом. Это почти не рекомендуется. JobProperty также подходит, только если вам нужна конфигурация для каждого задания, тогда как запрос касается глобальной конфигурации.

Скорее используйте GlobalConfiguration API, который предназначен для этой цели. Существует стандартный архетип, показывающий, как его использовать.

Другие вопросы по тегам