Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to only build one directory in a Jenkins multi-branch pipeline job?

I have a github repo called multibranch-test with two sub-directories Project1, Project2.

PS C:\Repos\multibranch-test> tree . Folder PATH listing for volume Windows Volume serial number is 2085-6D3D C:\REPOS\MULTIBRANCH-TEST ├───Project1 └───Project2

Each sub-directory has a Jenkinsfile and the code for that project.

In Jenkins I have two multibranch pipeline jobs - one for Project1 and one for Project2. In the configuration for Project1 I don't want a push notification or polling to build Project1 if a commit was pushed in sub-directory for Project2.

So in Project1 I have configured Additional Behaviours:

  • Advanced clone behaviours: Shallow clone is checked
  • Sparse checkout path is set to Project1#
  • Polling ignores commits in certain paths
    • Included Regions: Project1/*
    • Excluded Regions: *
  • Build Configuration: Script Path: Project1/Jenkinsfile

What is happening is if I push a commit to master in sub-directory Project2, both Project1 and Project2 jobs get built. I only want Project2 to build. Can someone point out what I'm doing wrong?

Jenkinsfiles for both Projects are similar and look like:

#!groovy
node  {
    stage ('checkout') {
        checkout scm
    }

    stage ('build') {
        dir ('Project1') {
            bat 'powershell -Command gci'
            bat 'powershell -Command gci env:'
            bat 'powershell -File .\\Project1.ps1'
        }
    }
like image 296
Mark Allison Avatar asked Jul 04 '17 08:07

Mark Allison


People also ask

How do I configure multiple branches in Jenkins?

Head over to your Jenkins instance and create a new item. Enter a name for the job, and select the “Multibranch Pipeline” option at the end of the screen. Then, click on the OK button. In the next screen, go to the “Branch sources” tab, click on the “Add source” button, and choose “Git” from the dropdown menu.

How do I change the workspace directory in Jenkins pipeline?

So if you wish to change the Jenkins workspace, all you've do is change the path of your JENKINS_HOME. For slave nodes, specify the default workspace on the slave machine in the slave configuration under Manage Jenkins > Manage Nodes > > Configure > Remote FS root.

Which of the below could be the use case of multi branch pipeline?

Multibranch Pipelines can be used for validating pull/change requests with the appropriate plugin. This functionality is provided by the following plugins: GitHub Branch Source. Bitbucket Branch Source.


2 Answers

Default Jenkins behavior is that projects get rebuilt if their repo gets a commit, so your commit in repo generates event for both Jenkins projects and triggers both builds. Take a look on Jenkins docs: https://jenkins.io/doc/book/pipeline/

From Jenkins point of view it's hard to tell if change went into project 1 or 2 - what is immediately visible is "new commit to watched repo".

Simples solution would be to split repo into two separate repos one for each project. Since they are supposed to build separately it shouldn't be a problem.

like image 143
stmi Avatar answered Oct 05 '22 23:10

stmi


This has been a big hassle for us, but we were able to solve it with some workarounds.

We have a master Jenkins job that's triggered by a GitHub commit hook. It figures out what changed since the last commit, and then triggers other service-specific Jenkins jobs.

We have some other conventions we're using (like naming conventions for services, directories, and Jenkins jobs) that aren't specified here, but hopefully this will help someone out.

Here's a breakdown of each component in the solution:

  1. Jenkins jobs and corresponding Jenkinsfiles for each service in the monorepo.

C:\REPOS\MULTIBRANCH-TEST\Project1\Jenkinsfile (your build logic here) C:\REPOS\MULTIBRANCH-TEST\Project2\Jenkinsfile (your build logic here)

  1. A shell script, that gets a list of what changed since the last commit (adapted from this blog post).

C:\REPOS\MULTIBRANCH-TEST\change-sets.sh

    #!/usr/bin/env bash

    changeSets=(`git diff-tree --name-status HEAD`)
    for(( i=0; i<${#changeSets[@]}; i++))
    do
      if [ ${changeSets[$i]} == "M" ]
      then
        echo ${changeSets[$i+1]}
      fi
    done
  1. A Jenkins job that builds on GitHub commit hook

C:\REPOS\MULTIBRANCH-TEST\Jenkinsfile

    #!/usr/bin/env groovy

    pipeline {
        agent any

        stages {

            stage('Define Services to Build') {
                steps {
                    script {

                        def SERVICES_TO_BUILD = sh script:"./change-sets.sh", returnStdout: true
                        SERVICES_TO_BUILD.split("\n").each {
                            echo "Triggering build for ${it}"
                            try {
                                build job: "${it}", propagate: false, wait: false
                            } catch (ex) {
                                echo "Failed to trigger build for ${it}: ${ex.message}"
                            }

                        }
                    }
                }
            }
        }
    }
like image 42
Garrett Clyde Avatar answered Oct 06 '22 01:10

Garrett Clyde