Monday, December 3, 2018

Jenkins 5: Combo Boxes

Combo boxes are the next UI element we will add to our builder.

Jenkins Tutorials

For a list of all jenkins related tutorials see Jenkins Tutorials Overview.

Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online.

Step 1: UI Definition

In the config.jelly file we simply define that we want to use a combo box:
 <f:entry title="Build Delay" field="buildDelay">
  <f:select />
 </f:entry>
The definition does not contain entries to select. These will be populated by the Descriptor class.

Step 2: Item Definition

Jenkins will look for a method called doFill<field>Items in our Descriptor class to populate the combo. We are doing a first approach now to understand the scheme:
  public ListBoxModel doFillBuildDelayItems() {
   ListBoxModel model = new ListBoxModel();
   
   model.add(new Option("None", "none"));
   model.add(new Option("Short", "short"));
   model.add(new Option("Long", "long"));
   
   return model;
  }
ListBoxModel is basically an ArrayList of Option instances. The first string represents the text visible to the user, the second one the value that will actually be stored in our variable (see next step).

If we would populate the combo this way, the first item would always be selected by default, even if we re-open a job that was configured differently. The Option constructor allows for a third parameter defining the selected state. We then just need to know the value that got stored with the job definition. Therefore we can inject the desired query parameter into our method parameters:
  public ListBoxModel doFillBuildDelayItems(@QueryParameter String buildDelay) {
   ListBoxModel model = new ListBoxModel();

   model.add(new Option("None", "none", "none".equals(buildDelay)));
   model.add(new Option("Short", "short", "short".equals(buildDelay)));
   model.add(new Option("Long", "long" , "long".equals(buildDelay)));

   return model;
  }
Now buildDelay contains the value that got stored by the user when the build step was originally configured. By comparing its string representation we can set the right option in the combo. Typically combo options could be populated from an Enum. To reduce the risk of typos we could write a small helper to create our Options:
 public static Option createOption(Enum<?> enumOption, String jobOption) {
  return new Option(enumOption.toString(), enumOption.name(), enumOption.name().equals(jobOption));
 }

Step 3: Glueing it all together

Finally we need to extend our constructor with the new parameter. Then we can use it in our build step:
public class HelloBuilder extends Builder implements SimpleBuildStep {

 private String fBuildDelay;

 @DataBoundConstructor
 public HelloBuilder(boolean failBuild, String buildMessage, String buildDelay) {
  fBuildDelay = buildDelay;
 }

 @Override
 public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener)
   throws InterruptedException, IOException {
  listener.getLogger().println("This is the Hello plugin!");
  listener.getLogger().println(getBuildMessage());

  switch (getBuildDelay()) {
  case "long":
   Thread.sleep(10 * 1000);
   break;

  case "short":
   Thread.sleep(3 * 1000);
   break;

  case "none":
   // fall through
  default:
   // nothing to do
  }

  if (isFailBuild())
   throw new AbortException("Build error forced by plugin settings");
 }

 public String getBuildDelay() {
  return fBuildDelay;
 }
}

No comments:

Post a Comment