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

依然范特西╮ 提交于 2019-11-30 12:39:41

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}"
                            }

                        }
                    }
                }
            }
        }
    }

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.

You could create a job for the whole repo, which looks at the changes the commits brought you and then trigger the corresponding Jenkinsfile of project 1 or 2 or both

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!