Can two different jenkins builders exist in the same hpi and share the same global configuration?

浪子不回头ぞ 提交于 2019-12-20 05:43:36

问题


I need to create two different Jenkins Builder classes. Each does different things and each requires its own .jelly, however, both require the same global configuration (global.jelly) which specifies a host and some user credentials.
Instances of both builder types, during their perform(), will connect to the host (specified in the global configuration) using the credentials (also specified in the global configuration).

The problem is that in Jenkins you place the resources of each builder in a folder corresponding to the builder class name AND that resource file includes the global.config.

If i copy the config to both builder's resource folders i'm getting two global configuration sections that are identical...

Is there away to create one .hpi with two Builder classes, each having its own config.jelly and help .html files, but both share the same global configuration (global.jelly)?


回答1:


Yes, this is very much possible but not in the regular way of extending Builder. You will need to use it as a JobProperty. Lets take an example to explain how this is done.

You will have 3 classes/packages at minimum.

  • MyPluginClass - Has fields for all your global configuration.
  • MyBuildStepAClass - Has the implementation of build step A.
  • MyBuildStepBClass - Has the implementation of build step B.

The code for your build step classes MyBuildStepAClass and MyBuildStepBClass will be same as you would normally write it for a plugin with a single build step. Below is a sample for 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";
         }
    }
}

To share the configuration between both the plugin classes, You will extend your MyPluginClass from JobProperty<Job<?,?>> (instead of Builder) and override the getDescriptor() method to return the descriptor using 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;
        }
}

The contents of your global.jelly and individual config.jelly files for each build step will be normal as you would be referring them. Hope this helps you in understanding how JobProperty helps you in having single configuration accessible in different build steps.

UPDATED to include information on jelly files.

You will have one global.jelly file in the package for MyPluginClass. This jelly file will contain the fields that you want to render/store in global configuration.

<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>

Each of your Build steps will have their own index.jelly files which will contain the jelly code specific to the Build step. Hope that makes it more clear..




回答2:


Avoid global.jelly altogether. This is semi-deprecated. JobProperty is also only suitable if you want per-job configuration, whereas the request is about global configuration.

Rather, use the GlobalConfiguration API which is designed for this purpose. There is a standard archetype showing how to use it.



来源:https://stackoverflow.com/questions/22754610/can-two-different-jenkins-builders-exist-in-the-same-hpi-and-share-the-same-glob

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!