Search code examples
jenkinsjenkins-pipeline

How to prevent matrix builds to share the same workspace in Jenkins pipelines?


I am trying to use Jenkins multibranch pipelines to build my multi-platform code. I saw declarative matrix as a good approach to achieve DRY.

Anyway, it seems that builds for each axis element are executed on the same checked out folder: this leads to a fail of the concurrent builds. If I build for a single platform everything works fine.

I am sure 100% the workspace is shared because, in the end, the workspace folder contains both rootfs_A.tar and rootfs_B.tar.

How can I rework this in such a way that ./build.sh works on a separate workspace?

This is the actual Jenkinsfile I am using.

pipeline {
    agent any
    stages {
        stage('Build') {
            matrix {
                axes {
                    axis {
                        name 'PLATFORM'
                        values 'A', 'B'
                    }
                }
                stages {
                    stage('Prep') {
                        steps {
                            sh "cp /opt/${PLATFORM}/rootfs.tar rootfs_${PLATFORM}.tar"
                        }
                    }
                    stage('Build') {
                        steps {
                            echo "Do Build for ${PLATFORM}"
                            sh "./build.sh -p ${PLATFORM}
                        }
                    }
                }
            }
        }
    }
}

Solution

  • You can configure matrix pipeline using the customWorkspace agent option to run each dimension on a separate workspace. Consider the following example:

    pipeline {
        agent none
    
        stages {
            stage("Build") {
                matrix {
                    agent {
                        node {
                            label ""
                            customWorkspace "workspace/${JOB_NAME}/PLATFORM/${PLATFORM}/" 
                        }
                    }
                    axes {
                        axis {
                            name "PLATFORM"
                            values "A", "B"                        
                        }
                    }
                    stages {
                        stage("Prepare") {
                            steps {
                                sh "pwd"
                                sh "ls -lah"
                            }
                        }
                    }
                }
            }
        }
    }
    

    The crucial part is the agent configuration inside the matrix block. Here I use the node agent with an empty label (which is the equivalent of agent any from your example) and I set a custom workspace inside the JENKINS_HOME relative path. This configuration runs every dimension inside the separate workspace (including cloning the repository to each custom workspace.)

    Below you can find an exemplary output that illustrates this declarative pipeline execution flow.

    [Pipeline] Start of Pipeline
    [Pipeline] stage
    [Pipeline] { (Build)
    [Pipeline] parallel
    [Pipeline] { (Branch: Matrix - PLATFORM = 'A')
    [Pipeline] { (Branch: Matrix - PLATFORM = 'B')
    [Pipeline] stage
    [Pipeline] { (Matrix - PLATFORM = 'A')
    [Pipeline] stage
    [Pipeline] { (Matrix - PLATFORM = 'B')
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] node
    Running on Jenkins in /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces_master
    [Pipeline] node
    [Pipeline] {
    [Pipeline] ws
    Running in /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces/master/PLATFORM/A
    [Pipeline] {
    [Pipeline] checkout
    Selected Git installation does not exist. Using Default
    The recommended git tool is: NONE
    No credentials specified
    Cloning the remote Git repository
    Cloning with configured refspecs honoured and without tags
    Cloning repository file:///home/wololock/workspace/jenkins-matrix-workspaces
     > git init /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces/master/PLATFORM/A # timeout=10
    Fetching upstream changes from file:///home/wololock/workspace/jenkins-matrix-workspaces
     > git --version # timeout=10
     > git --version # 'git version 2.26.3'
     > git fetch --no-tags --force --progress -- file:///home/wololock/workspace/jenkins-matrix-workspaces +refs/heads/*:refs/remotes/origin/* # timeout=10
     > git config remote.origin.url file:///home/wololock/workspace/jenkins-matrix-workspaces # timeout=10
     > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
    Avoid second fetch
    Checking out Revision c6083445649b0c73b70aefcb1bc662c30577bd00 (master)
     > git config core.sparsecheckout # timeout=10
     > git checkout -f c6083445649b0c73b70aefcb1bc662c30577bd00 # timeout=10
    Commit message: "update"
     > git rev-list --no-walk 8d67e2047ad7a0e65899f9855ae289eda90ea974 # timeout=10
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (Prepare)
    [Pipeline] sh
    + pwd
    /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces/master/PLATFORM/A
    [Pipeline] sh
    + ls -lah
    total 20K
    drwxrwxr-x 3 wololock wololock 4.0K Apr 21 12:17 .
    drwxrwxr-x 4 wololock wololock 4.0K Apr 21 12:17 ..
    -rw-rw-r-- 1 wololock wololock   11 Apr 21 12:17 file
    drwxrwxr-x 8 wololock wololock 4.0K Apr 21 12:17 .git
    -rw-rw-r-- 1 wololock wololock  762 Apr 21 12:17 Jenkinsfile
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // ws
    [Pipeline] }
    Running on Jenkins in /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces_master
    [Pipeline] // node
    [Pipeline] {
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] ws
    Running in /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces/master/PLATFORM/B
    [Pipeline] {
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] checkout
    Selected Git installation does not exist. Using Default
    The recommended git tool is: NONE
    No credentials specified
    Cloning the remote Git repository
    Cloning with configured refspecs honoured and without tags
    Cloning repository file:///home/wololock/workspace/jenkins-matrix-workspaces
     > git init /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces/master/PLATFORM/B # timeout=10
    Fetching upstream changes from file:///home/wololock/workspace/jenkins-matrix-workspaces
     > git --version # timeout=10
     > git --version # 'git version 2.26.3'
     > git fetch --no-tags --force --progress -- file:///home/wololock/workspace/jenkins-matrix-workspaces +refs/heads/*:refs/remotes/origin/* # timeout=10
     > git config remote.origin.url file:///home/wololock/workspace/jenkins-matrix-workspaces # timeout=10
     > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
    Avoid second fetch
    Checking out Revision c6083445649b0c73b70aefcb1bc662c30577bd00 (master)
     > git config core.sparsecheckout # timeout=10
     > git checkout -f c6083445649b0c73b70aefcb1bc662c30577bd00 # timeout=10
    Commit message: "update"
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (Prepare)
    [Pipeline] sh
    + pwd
    /home/wololock/.jenkins/workspace/jenkins-matrix-workspaces/master/PLATFORM/B
    [Pipeline] sh
    + ls -lah
    total 20K
    drwxrwxr-x 3 wololock wololock 4.0K Apr 21 12:17 .
    drwxrwxr-x 6 wololock wololock 4.0K Apr 21 12:17 ..
    -rw-rw-r-- 1 wololock wololock   11 Apr 21 12:17 file
    drwxrwxr-x 8 wololock wololock 4.0K Apr 21 12:17 .git
    -rw-rw-r-- 1 wololock wololock  762 Apr 21 12:17 Jenkinsfile
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // ws
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // parallel
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] End of Pipeline
    Finished: SUCCESS