Multiple jenkinsfile in one repository

I achieved to have multiple pipelines (Jenkinsfile) in a single repository. It's not hacky but it was not exactly trivial, requires recent versions of Jenkins with updated Lockable Resources plugin and may require additional steps in the build procedure.

  • Create a "Source Code Management" only project. In Jenkins terminology it can be a Freestyle project that will only care about keeping the source code updated, with a SCM section and a triggered configured (example name "MyProjectSCM"). In my case I have a git repository with a polling schedule. Ensure the "Execute concurrent builds if necessary" flag is not checked;

  • In the project repository commit one or more Jenkins pipeline, for example "JenkinsfileBuild", "JenkinsfileRelease". Ensure the pipelines:

    1. has the the skipDefaultCheckout in the options section;

    2. has a trigger on the SCM project configured ("MyProjectSCM");

    3. locks the SCM project during build.

       pipeline {
           agent any
      
           options {
               disableConcurrentBuilds()   
               skipDefaultCheckout()
           }
      
           triggers {
               upstream(upstreamProjects: 'MyProjectSCM')
           }
      
           stages {
               stage('Build') {
                   lock('MyProjectSCM') {
                       steps {
                           echo 'Build within MyProjectSCM lock...'
                       }
                   }
               }
           }
       }
      
  • Create Pipeline projects, one per each Jenkinsfile you committed in the repository. The pipeline should have a configured "Pipeline script from SCM" (in this example the pipeline can be named "MyProject_Build", with a configured "JenkinsfileBuild"), with the "Lightweight checkout" flag checked (it's actually the default):

enter image description here

The skipDefaultCheckout directive in "MyProject_Build" pipeline will prevent the checkout of the repository in that workspace, "Lightweight checkout" flag itself strangely it's not enough to prevent the checkout. Because the "MyProject_Build" workspace it's actually empty you have to refer to the SCM only project directory in your build scripts, by means of environment variables or relative paths. The lock directive is useful so a new commit can't happen while actually building the project.


I'd suggest using the multi-branch pipeline plugin, then specifying the path to the appropriate jenkinsfile. So you'd have three pipeline jobs, one for app, lib1, and lib2.

enter image description here


RECENT UPDATE:

I later fixed this issue using following code snippet: If you see the command dir('servicelayer'), using this to move into the directory, executing git command to find the difference between the commits and raising a flag. This way i have managed 3 Jenkins files in a single repository.

stage('Validation') {
steps {
        //Moving in to the directory to execute the commands
        dir('servicelayer') {
            script {
                //Using the git command to check the difference between previous successful commit. ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} is an environment variable comes with GIT Jenkins plugin
                //There is a drawback though, if it is the first time you are running this job, this variable is not available and fails the build
                //For the first time i had to use ${env.GIT_COMMIT} itself at both places to pass the build. A hack but worth it for future builds.

                def strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep servicelayer | wc -l").trim()
                if(strCount=="0") {
                    echo "Skipping build no files updated"
                    CONTINUE_BUILD = false
                } else {
                    echo "Changes found in the servicelayer module"
                }
            }
        }
    }
}

OLD ANSWER:

You can do it in 2 ways:

a) Configure your build jobs by adding "Additional Behaviour" -> "Polling ignore commits in certain region" This behaviour will let you add "Whitelisted regions" or "Blacklist the regions" which you do not want to poll for triggering the build job.

b) Write a custom shell script to verify the files changed per commit and verify the location. This shell script can then be added to your Jenkinsfile and be it Declarative or Scripted you can tweak the behaviour accordingly.

I will recommend option a) as it is simpler to configure and maintain as well. Hope this helps.

Additional Behaviour