patternModerate
Triggering specific pipeline builds for monorepos in Jenkins
Viewed 0 times
buildsjenkinsforspecifictriggeringpipelinemonorepos
Problem
I'm in the process of converting multiple repositories into a single repository, our CI tool of choice is Jenkins due to the conversion of multiple repository structures into a single one 2 main issues have arisen.
-
Build/test times have increased significantly as all the builds/tests have to be run for every single commit. This is partially alleviated by using a build tool, in our case we have gone with using Buck.
-
After all the tests associated with the committed code are run, I have a deployment Jenkinsfile for each project. How will I be able to only trigger the Jenkinsfiles for projects that need to be re-deployed? And if I am able to do so, is this a correct practice?
-
Build/test times have increased significantly as all the builds/tests have to be run for every single commit. This is partially alleviated by using a build tool, in our case we have gone with using Buck.
-
After all the tests associated with the committed code are run, I have a deployment Jenkinsfile for each project. How will I be able to only trigger the Jenkinsfiles for projects that need to be re-deployed? And if I am able to do so, is this a correct practice?
Solution
You can use the "when" block combined with the built in "changeset" condition to conditionally run only certain stages of your monorepo's pipeline. From the when.changeset documentation:
changeset-
Executes the stage if the build’s SCM changeset contains one or more files matching the given string or glob. Example: when { changeset "**/*.js" }
Here is an example Jenkinsfile using this strategy:
, applicable to the monorepo project structure shown below:
This strategy won't scale past small codebases because it would be hard to keep track of which modules depend one each other. You would be better off using a build system like Bazel. Your CI job would simply issue a bazel build //... (build everything), and Bazel would calculate what actually needs to be built, and what needs to be tested. Further, there even exist bazel rules such as rules_docker and rules_k8s which can calculate which of your containers need to be rebuilt and pushed to a container registry, and which of your applications need to be redeployed to Kubernetes.
changeset-
Executes the stage if the build’s SCM changeset contains one or more files matching the given string or glob. Example: when { changeset "**/*.js" }
Here is an example Jenkinsfile using this strategy:
pipeline {
agent any
stages {
stage('build matchengine') {
when {
changeset "**/matchengine/*.*"
}
steps {
echo 'building match engine'
}
}
stage('build posttrade') {
when {
changeset "**/posttrade/*.*"
}
steps {
echo 'building post trade'
}
}
}
}, applicable to the monorepo project structure shown below:
.(my-project)
|-- Jenkinsfile
|-- matchengine
|-- posttrade
|-- serverless
|-- uiThis strategy won't scale past small codebases because it would be hard to keep track of which modules depend one each other. You would be better off using a build system like Bazel. Your CI job would simply issue a bazel build //... (build everything), and Bazel would calculate what actually needs to be built, and what needs to be tested. Further, there even exist bazel rules such as rules_docker and rules_k8s which can calculate which of your containers need to be rebuilt and pushed to a container registry, and which of your applications need to be redeployed to Kubernetes.
Code Snippets
pipeline {
agent any
stages {
stage('build matchengine') {
when {
changeset "**/matchengine/*.*"
}
steps {
echo 'building match engine'
}
}
stage('build posttrade') {
when {
changeset "**/posttrade/*.*"
}
steps {
echo 'building post trade'
}
}
}
}.(my-project)
|-- Jenkinsfile
|-- matchengine
|-- posttrade
|-- serverless
|-- uiContext
StackExchange DevOps Q#4355, answer score: 15
Revisions (0)
No revisions yet.