TL;DR Is there a way to import code into the Jenkinsfile
from the local repository (other than the load
step)?
I've experienced that for complex builds the Jenkinsfile
gets kind of bulky and not very maintainable.
Now that the build job is code, it would be wonderful to have the same means as for other code.
That is, I would like to divide it into smaller (more maintainable) units and unit test them.
load
Step: Allow for loading groovy scripts from the repository.Jenkinsfile
and import this library into the Jenkinsfile
?Similar to the directory structure described for shared libs I would like to have the following in a single repository.
(root)
+- someModule
| +- ...
+- jenkins # Classes/Scripts used by Jenkins in a separate module
| +- src # Groovy source files
| +- org
| +- foo
| +- Bar.groovy # for org.foo.Bar class
| +- test # Groovy test files
| +- org
| +- foo
| +- BarTest.groovy # Test for org.foo.Bar class
| +- pom.xml or build.groovy # Build for local library
+- Jenkinsfile # Build "someModule", uses classes from "jenkins" module
In Jenkins, go to Manage Jenkins → Configure System. Under Global Pipeline Libraries, add a library with the following settings: Name: pipeline-library-demo. Default version: Specify a Git reference (branch or commit SHA), e.g. master.
Creating Multi-branch Pipelines. The Multibranch Pipeline project type enables you to configure different jobs for different branches of the same project. In a multi-branch pipeline configuration, Jenkins automatically discovers, manages, and executes jobs for multiple source repositories and branches.
Workaround:
library identifier: 'shared-library@version', retriever: legacySCM(scm)
The approach currently taken in PR 37 will not work properly with build agents, and anyway will only work for scripts using the library
step, not the @Library
annotation.
By the way files loaded from the load
step do appear in Replay. But it is true that your script cannot statically refer to types defined in such files. In other words, you could simulate library vars/*.groovy
but not src/**/*.groovy
—the same limitation as the current PR 37.
I guess that proper way to do that is to implement a custom SCMRetriever
.
However, you can use the following hack:
Assuming jenkins/vars/log.groovy
in your local repo contains:
def info(message) {
echo "INFO: ${message}"
}
Your Jenkinsfile
can load that shared library from the jenkins/
directory using library
step:
node('node1') { // load library
checkout scm
// create new git repo inside jenkins subdirectory
sh('cd jenkins && git init && git add --all . && git commit -m init &> /dev/null')
def repoPath = sh(returnStdout: true, script: 'pwd').trim() + "/jenkins"
library identifier: 'local-lib@master', retriever: modernSCM([$class: 'GitSCMSource', remote: repoPath])
}
node('node2') {
stage('Build') {
log.info("called shared lib") // use the loaded library
}
}
You may take a look at plugin I wrote, that enables using subdirectories of repo where your pipeline is as shared libraries: https://github.com/karolgil/SharedLibrary
After building and installing it, you can simply put following in your pipeline:
@SharedLibrary('dir/in/repo') _
To start using dir/in/repo
as shared library for your pipelines.
Wanted to do the same and ended up creating this:
https://github.com/jenkinsci/workflow-cps-global-lib-plugin/pull/37
and here is how I use it:
https://github.com/syndesisio/syndesis-pipeline-library/blob/master/Jenkinsfile#L3
In my case I wanted to create a Jenkinsfile that actually tests
the pipeline library that the repository contains.
Let me know what you think and feel free to add your comments on the PR too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With