Jenkins multibranch pipeline only for subfolder
Asked Answered
I

3

18

I have git monorepo with different apps. Currently I have single Jenkinsfile in root folder that contains pipeline for app alls. It is very time consuming to execute full pipeline for all apps when commit changed only one app.

We use GitFlow-like approach to branching so Multibranch Pipeline jobs in Jenkins as perfect fit for our project.

I'm looking for a way to have several jobs in Jenkins, each one will be triggered only when code of appropriate application was changed.

Perfect solution for me looks like this:

I have several Multibranch Pipeline jobs in Jenkins. Each one looks for changes only to given directory and subdirectories. Each one uses own Jenkinsfile. Jobs pull git every X minutes and if there are changes to appropriate directories in existing branches - initiates build; if there are new branches with changes to appropriate directories - initiates build.

What stops me from this implementation

  1. I'm missing a way to define commit to which folders must be ignored during scan execution by Multibranch pipeline. "Additional behaviour" for Multibranch pipeline doesn't have "Polling ignores commits to certain paths" option, while Pipeline or Freestyle jobs have. But I want to use Multibranch pipeline.

  2. Solution described here doesnt work for me because if there will be new branch with changes only to "project1" then whenever Multibranch pipeline for "project2" will be triggered it will discover this new branch anyway and build it. Means for every new branch each of my Multibranch pipelines will be executed at least once no matter if there was changes to appropriate code or not.

Appreciate any help or suggestions how I can implement few Multibranch pipelines watching over same git repository but triggered only when appropriate pieces of code changed

Inmesh answered 12/2, 2018 at 16:23 Comment(2)
You can try to use wiki.jenkins.io/display/JENKINS/FSTrigger+Plugin. This one worked fine for me in pipeline and freestyle jobs but not in multibranch, even though config option appeared in job config UI. If you try, tell me what was the result or it's just my environmentIst
Did you find a solution ?Leptorrhine
U
12

This can be accomplished by using the Multibranch build strategy extension plugin. With this plugin, you can define a rule where the build only initiates when the changes belong to a sub-directory.

  1. Install the plugin
  2. On the Multibranch pipeline configuration, add a Build strategy
  3. Select Build included regions strategy
  4. Put a sub-folder on the field, such as subfolder/**

Sample image of the configuration here

This way the changes will still be discovered, but they won't initiate a build if it doesn't belong to a certain set of files or folders.

This is the best approach I'm aware so far. But I think the best way would be a case where the changes doesn't even get discovered.

Edit: Gerrit Code Review plugin configuration

In case you're using the Gerrit Code Review plugin, you can also prevent new changes to be discovered by using a custom query:

Gerrit Code Review configuration example

Unfriendly answered 27/1, 2020 at 11:43 Comment(1)
thank you thank you thank you thank you. I was like 5 jobs into porting over 20 repos into a monorepo and I just realized any change to the monorepo was triggering all 5 jobs... this is what I needed.Irisation
L
9

I solved this by creating a project that builds other projects depending on the files changed. For example, from your repo root:

/Jenkinsfile

#!/usr/bin/env groovy

pipeline {
    agent any
    options {
        timestamps()
    }
    triggers {
        bitbucketPush()
    }
    stages {
        stage('Build project A') {
            when {
                changeset "project-a/**"
            }
            steps {
                build 'project-a'
            }
        }
        stage('Build project B') {
            when {
                changeset "project-b/**"
            }
            steps {
                build 'project-b'
            }
        }
    }
}

You would then have other Pipeline projects with their own Jenkinsfile (i.e., project-a/Jenkinsfile).

Langue answered 26/7, 2018 at 18:39 Comment(4)
Could you please add little more info? I've been reading the build step docs but it's still confusing and when I used your example, all I got is: ERROR: No item named project-a foundCircumcise
I don't have a monorepo like this, but man do I love this tip. I have a stage that runs a time-costly validator on files that rarely change, and this is perfect for skipping that stage if nothing has changedWojcik
@Circumcise probably you have already solved the problem, just to have the solution here: you have to use the correct path to your Jenkins Job, simply go to the root job and then click on "Pipeline Syntax", then select "build: Build a job" from steps and fill in with correct information, input "Project to build" will help you to find the correct path to your project-a jobTissue
If I get this answer correctly it requires you to create a separate Jenkins job for every project. In this case, I don't get why the when/changeset condition would not be better kept in those projects/Jenkinsfile.Alarice
I
1

I know that this post is quite old, but I solved this problem by changing the "include branches" parameter for SVN repositories (this can possibly also be done using the property "Filter by name (with wildcards)" for git repos). Instead of supplying only the actual branch name, I also included the subfolder. So instead of only supplying "trunk", I used "trunk/subfolder". This limits scanning to only that specific directory. Note that I have not yet fully tested this solution.

Insurgent answered 23/12, 2019 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.