Load Jenkins Pipeline Shared Library from same repository

schnatterer picture schnatterer · Sep 14, 2017 · Viewed 18.1k times · Source

TL;DR Is there a way to import code into the Jenkinsfile from the local repository (other than the load step)?

Why?

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.

What I tried

  • shared libraries: allow for dividing our Jenkins Pipeline logic into smaller files in a separate module and even unit test it.
    However, they need to be in different repository and (if not on GitHub) must be configured into Jenkins.
  • load Step: Allow for loading groovy scripts from the repository.
    However, the files must be scripts and not "full" groovy classes, making it difficult to have multiple files or classes that depend on each other. For example inheritance is impossible.
    In addition, theses files are not displayed when doing a replay on a Jenkins job, which makes them hard to develop and debug.

My Questions

  • Is there a way (or workaround) to create a shared library in the same repository as the Jenkinsfile and import this library into the Jenkinsfile?
  • Or is there even another way I haven't tried, yet?

Example directory structure

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

Answer

Jesse Glick picture Jesse Glick · Mar 5, 2018

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.