I stumbled over this issue as well (when using global vars from "vars/" and using classes from the "src/"), but was not able to resolve the problem to my satisfation:
- either the linter complains about the import (initial/old approach via @Library and import), while the pipeline works
- or the pipeline fails
I tried many unsuccessful approaches, here are some of them:
- Using library directive on top (before pipeline) and a second library for dynamic class usage
--- old/Jenkinsfile
+++ new/Jenkinsfile
-@Library('acme-shared-library') _
-import com.acme.Constants
+library('acme-shared-library')
pipeline {
...
steps {
script {
acme.setBuildDisplayName()
+
+ def lib = library('acme-shared-library').com.acme + echo lib.Constants.DEVOPS_EMAIL
}
}
}
- Interesting log output:
- Failure:
- Using library directive on top (before pipeline) (without a second library for dynamic class usage) and direct FQ access to class
--- old/Jenkinsfile
+++ new/Jenkinsfile
-@Library('acme-shared-library') _
-import com.acme.Constants
+library('acme-shared-library')
pipeline {
...
steps {
script {
acme.setBuildDisplayName()
+
+ echo "devops email: ${com.acme.Constants.DEVOPS_EMAIL}"
}
}
}
- No interesting log output anymore (cf. "Only using first definition of library acme-shared-library")
- Failure:
- Using library directive in pipeline before first global var usage
--- old/Jenkinsfile
+++ new/Jenkinsfile
-@Library('acme-shared-library') _
-import com.acme.Constants
pipeline {
...
steps {
script {
+ def lib = library('acme-shared-library').com.acme acme.setBuildDisplayName()
+ echo "devops email: ${lib.Constants.DEVOPS_EMAIL}" }
}
}
- Same for using library directive in pipeline before first global var usage and FQ access to class instead of preselect package
--- old/Jenkinsfile
+++ new/Jenkinsfile
-@Library('acme-shared-library') _
-import com.acme.Constants
pipeline {
...
steps {
script {
+ def lib = library('acme-shared-library')
acme.setBuildDisplayName()
+ echo "devops email: ${lib.com.acme.Constants.DEVOPS_EMAIL}"
}
}
- Using new libraries section in pipeline
--- old/Jenkinsfile
+++ new/Jenkinsfile
-@Library('acme-shared-library') _
-import com.acme.Constants
pipeline {
...
+ libraries {
+ lib('acme-shared-library')
+ }
+
steps {
script {
acme.setBuildDisplayName()
+ echo "devops email: ${com.acme.Constants.DEVOPS_EMAIL}"
}
}
Oh! The following approach seems to work (linter is happy and pipeline works), but is a rather inconvenient/surprising workaround; thus, this is rather interesting for the bug fix, but not a real workaround, let alone a solution, I claim:
- not using libraries block in pipeline block, but using library including suffix for class in "src/" (as seen above it does not work, if the first library statement is without class usage suffix!)
--- old/Jenkinsfile
+++ new/Jenkinsfile
-@Library('acme-shared-library') _
-import com.acme.Constants
pipeline {
...
steps {
script {
+ echo "devops email: ${library('acme-shared-library').com.acme.Constants.DEVOPS_EMAIL}"
acme.setBuildDisplayName()
+
}
}
IMHO this is very confusing and should be addressed in another issue, but presumably not in the linter (unless the initial/old approach via @Library and import will be re-recommended, and the linter accepts it).
First, I'd suggest upgrading to Declarative 1.1 and using the new libraries directive -
pipeline { agent any libraries { lib('gconftools') } stages { ... } }
And then let me know if that works, and if not, what the error is along with (ideally) a copy of the Jenkinsfile having the problem.