1@NonCPS 2List generateMatrix(Map matrixAxes) { 3 List axes = [] 4 5 matrixAxes.each { axis, values -> 6 List axisList = [] 7 8 values.each { value -> 9 axisList << [(axis): value] 10 } 11 12 axes << axisList 13 } 14 15 axes.combinations()*.sum() 16} 17 18pipeline { 19 agent { 20 label 'docker' 21 } 22 23 stages { 24 stage('Build container') { 25 steps { 26 /* 27 * Using `--target` with the Dockerfile agent currently bugs out 28 * on Jenkins, producing an error along the lines of: 29 * 30 * Cannot retrieve .Id from 'docker inspect ...' 31 * 32 * Apparently it doesn't like multi-stage builds, so until 33 * we're on a version of the Docker workflow plugin that 34 * doesn't exhibit this bug, we just have to build the image 35 * ourselves. 36 * 37 * See: 38 * - https://github.com/jenkinsci/docker-workflow-plugin/pull/149 39 * - https://github.com/jenkinsci/docker-workflow-plugin/pull/162 40 * - https://github.com/jenkinsci/docker-workflow-plugin/pull/180 41 * 42 * Once the Docker workflow plugin has been updated, we should 43 * be able to get rid of this stage and use: 44 * 45 * agent { 46 * dockerfile { 47 * dir 'docker' 48 * filename 'Dockerfile' 49 * additionalBuildArgs '--target ci' 50 * } 51 * } 52 */ 53 54 sh """ \ 55 docker build -t scp-firmware:build-${currentBuild.number} \ 56 --build-arg JENKINS_UID=1000 \ 57 --build-arg JENKINS_GID=36293 \ 58 --target=jenkins docker 59 """ 60 } 61 } 62 63 stage('Run tests') { 64 parallel { 65 stage('Run legacy tests') { 66 agent { 67 docker { 68 image "scp-firmware:build-${currentBuild.number}" 69 args '-e ARMLMD_LICENSE_FILE' 70 } 71 } 72 73 steps { 74 sh '/usr/local/bin/init' 75 sh 'python3 ./tools/ci.py' 76 } 77 } 78 79 stage('Build and test') { 80 /* 81 * We are on an old enough version of the Jenkins pipeline 82 * workflow plugin that we do not have support for matrices. 83 * 84 * Without this support, we need to generate the stages as 85 * part of a scripted stage. 86 * 87 * See: 88 * - https://www.jenkins.io/blog/2019/11/22/welcome-to-the-matrix/ 89 * - https://www.jenkins.io/blog/2019/12/02/matrix-building-with-scripted-pipeline/ 90 * - https://stackoverflow.com/questions/60829465/jenkins-unknown-stage-section-matrix-in-declarative-pipeline 91 * 92 * Once the plugin has been updated, we can adopt a proper 93 * matrix. 94 */ 95 96 steps { 97 script { 98 /* 99 * This is, admittedly, not particularly clean, but 100 * should require very little adjustment. The 101 * premise is relatively simple: generate a list of 102 * all the possible matrix combinations, create a 103 * a list of closures returning a pipeline stage for 104 * each combination, then execute them in parallel. 105 */ 106 107 def axes = [ 108 generator: [ 'Ninja', 'Unix Makefiles' ], 109 buildType: [ 'Debug', 'Release', 'MinSizeRel', 110 'RelWithDebInfo' ] 111 ] 112 113 def tasks = generateMatrix(axes).collectEntries { config -> 114 ["Build and test (${config})", { 115 node('docker') { 116 docker 117 .image("scp-firmware:build-${currentBuild.number}") 118 .inside('-e ARMLMD_LICENSE_FILE') 119 { 120 /* 121 * If you need to adjust the 122 * behaviour of the generated stages 123 * then this is probably where you 124 * want to do it. 125 */ 126 127 stage("Build ${config}") { 128 checkout scm 129 130 /* 131 * Unfortunately, we don't have 132 * the CMake build plugin 133 * available to us, so we'll 134 * have to make do with shell 135 * scripts for now. 136 */ 137 138 sh '/usr/local/bin/init' 139 140 sh """ \ 141 cmake \ 142 -G "${config.generator}" \ 143 -DCMAKE_BUILD_TYPE="${config.buildType}" \ 144 . 145 """ 146 147 sh 'cmake --build .' 148 } 149 150 stage("Check ${config}") { 151 sh """ 152 cmake 153 --build . \ 154 --target check 155 """ 156 } 157 } 158 } 159 }] 160 } 161 162 parallel tasks 163 } 164 } 165 } 166 } 167 } 168 } 169} 170