Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiconfiguration / matrix build pipeline in Jenkins

What is modern best practice for multi-configuration builds (with Jenkins)?

I want to support multiple branches and multiple configurations.

For example for each version V1, V2 of the software I want builds targeting platforms P1 and P2.

We have managed to set up multi-branch declarative pipelines. Each build has its own docker so its easy to support multiple platforms.

pipeline { 
    agent none 
    stages {
        stage('Build, test and deploy for P1) {
            agent {
                dockerfile {
                   filename 'src/main/docker/Jenkins-P1.Dockerfile'
                }
            }
            steps {
               sh buildit...
            }
        }
        stage('Build, test and deploy for P2) {
            agent {
                dockerfile {
                   filename 'src/main/docker/Jenkins-P2.Dockerfile'
                }
            }
            steps {
               sh buildit...
            }
        }
    }
}

This gives one job covering multiple platforms but there is no separate red/blue status for each platform. There is good argument that this does not matter as you should not release unless the build works for all platforms.

However, I would like a separate status indicator for each configuration. This suggests I should use a multi-configuration build which triggers a parameterised build for each configuration as below (and the linked question):

pipeline { 
    parameters {
      choice(name: 'Platform',choices: ['P1', 'P2'], description: 'Target OS platform', )
    }
    agent {
       filename someMagicToGetDockerfilePathFromPlatform()
    }
    stages {
        stage('Build, test and deploy for P1) {
            steps {
               sh buildit...
            }
        }
    }
}

There are several problems with this:

  • A declarative pipeline has more constraints over how it is scripted
  • Multi-configuration builds cannot trigger declarative pipelines (even with the parameterized triggers plugin I get "project is not buildable").

This also begs the question what use are parameters in declarative pipelines?

Is there a strategy that gives the best of both worlds i.e:

  • pipeline as code
  • separate status indicators
  • limited repetition?
like image 633
Bruce Adams Avatar asked May 08 '19 17:05

Bruce Adams


People also ask

What is matrix in Jenkins pipeline?

Pipeline for multiple platforms and browsersThe new matrix directive lets me specify a set of axes . Each axis has a name and a list of one or more values . When the pipeline is run, Jenkins will take those and run my stages on all possible combinations of values from each axis.

How do I build a pipeline in Jenkins?

Click the New Item menu within Jenkins. Provide a name for your new item (e.g. My-Pipeline) and select Multibranch Pipeline. Click the Add Source button, choose the type of repository you want to use and fill in the details. Click the Save button and watch your first Pipeline run.

Which is the easiest way to build a pipeline in Jenkins?

To create a simple pipeline from the Jenkins interface, perform the following steps: Click New Item on your Jenkins home page, enter a name for your (pipeline) job, select Pipeline, and click OK. In the Script text area of the configuration screen, enter your pipeline syntax.

What is configuration matrix in Jenkins?

The Configuration Matrix allows you to specify what steps to duplicate, and create a multiple-axis graph of the type of builds to create. For example, let us say that we have a build that we want to create for several different targets alpha , beta , and we want to produce both debug and release outputs.


1 Answers

This is a partial answer. I think others with better experience will be able to improve on it.

This is currently untested. I may be barking up the wrong tree. Please comment or add a better answer.

  • Do not use pipeline parameters except where you need user input

  • Use a hybrid of a scripted and declarative pipeline (see also https://stackoverflow.com/a/46675227/1569204)

  • Have a function which declares a pipeline based on parameters: (see also https://jenkins.io/doc/book/pipeline/shared-libraries/)

  • Use nodes to create visible indicators in the pipeline (at least in blue ocean)

So something like the following:

    def build(string platform) {
       switch(platform) {
         case P1:
            dockerFile = 'foo'
            indicator = 'build for foo'
            break
         case P2:
            dockerFile = 'bar'
            indicator = 'build for bar'
            break
       }
       pipeline {
         agent {
            dockerfile {
               filename "$dockerFile"
            }
            node { 
               label "$indicator"
            }
         }
         stages {
           steps {
             echo "build it"
           }
         }
       }
    }
  • The relevant code could be moved to a shared library (even if you don't actually need to share it).
like image 58
Bruce Adams Avatar answered Oct 06 '22 19:10

Bruce Adams