0

I am trying to find a way to inherit/override environment variables in jenkins jobs defined via jenkins-job-builder (jjb).

Here is one template that does not work:

#!/usr/bin/env jenkins-jobs test
- defaults: &sample_defaults
    name: sample_defaults

- job-template:
    name: 'sample-{product_version}'
    project-type: pipeline
    dsl: ''
    parameters:
      - string:
          name: FOO
          default: some-foo-value-defined-at-template-level
      - string:
          name: BAR
          default: me-bar

- project:
    defaults: sample_defaults
    name: sample-{product_version}
    parameters:
      - string:
          name: FOO
          value: value-defined-at-project-level
    jobs:
      - 'sample-{product_version}':
          product_version:
              - '1.0':
                   parameters:
                     - string:
                         name: FOO
                         value: value-defined-at-job-level-1
              - '2.0':
                # this job should have:
                # FOO=value-defined-at-project-level
                # BAR=me-bar

Please note that it is key to be able to override these parameters at job or project level instead of template.

Requirements * be able to add as many environment variables like this without having to add one JJB variable for each of them * user should not be forced to define these at template or job levels * those var need to endup being exposed as environment variables at runtime for pipelines and freestyle jobs. * syntax is flexible but a dictionary approach would be highly appreciated, like:

vars:
  FOO: xxx
  BAR: yyy
sorin
  • 161,544
  • 178
  • 535
  • 806

1 Answers1

1

The first thing to understand is how JJB priorities where it will pull variables in from.

  1. job-group section definition
  2. project section definition
  3. job-template variable definition
  4. defaults definition

(This is not an exhaustive list but it's covers the features I use)

From this list we can immediately see that if we want to make job-templates have override-able then using JJB defaults configuration is useless as it has the lowest precedence when JJB is deciding where to pull from.

On the other side of the spectrum, job-groups has the highest precedence. Which unfortunately means if you define a variable in a job-group with the intention of of overriding it at the project level then you are out of luck. For this reason I avoid setting variables in job-groups unless I want to enforce a setting for a set of jobs.

Declaring variable defaults

With that out of the way there are 2 ways JJB allows us to define defaults for a parameter in a job-template:

Method 1) Using {var|default}

In this method we can define the default along with the definition of the variable. For example:

- job-template:
    name: '{project-name}-verify'
    parameters:
      - string:
          name: BRANCH
          default: {branch|master}

However where this method falls apart if you need to use the same JJB variable in more than one place as you will have multiple places to define the default value for the template. For example:

- job-template:
    name: '{project-name}-verify'
    parameters:
      - string:
          name: BRANCH
          default: {branch|master}

    scm:
      - git:
         refspec: 'refs/heads/{branch|master}'

As you can see we now have 2 places were we are declaring {branch|master} not ideal.

Method 2) Defining the default variable value in the job-template itself

With this method we declare the default value of the variable in the job-template itself just once. I like to section off my job-templates like this:

- job-template:
    name: '{project-name}-verify'

    #####################
    # Variable Defaults #
    #####################

    branch: master

    #####################
    # Job Configuration #
    #####################

    parameters:
      - string:
          name: BRANCH
          default: {branch}

    scm:
      - git:
         refspec: 'refs/heads/{branch}'

In this case there is still 2 branch definitions for the job-template. However we also provide the default value for the {branch} variable at the top of the file. Just once. This will be the value that the job takes on if it is not passed in by a project using the template.

Overriding job-templates variables

When a project now wants to use a job-template I like to use one of 2 methods depending on the situation.

- project:
    name: foo
    jobs:
      - '{project-name}-merge'
      - '{project-name}-verify'

    branch: master

This is the standard way that most folks use and it will set branch: master for every job-template in the list. However sometimes you may want to provide an alternative value for only 1 job in the list. In this case the more specific declaration takes precendence.

- project:
    name: foo
    jobs:
      - '{project-name}-merge':
          branch: production
      - '{project-name}-verify'

    branch: master

In this case the verify job will get he value "master" but the merge job will instead get the branch value "production".

zxiiro
  • 92
  • 5