10

I can use Jenkins.instance.getItem('job_name') to access a job by name, either in the script console or in a Jenkinsfile.

But I am not able to do it for multibranch pipelines or any other job that's in a folder. If I try using the project's full name (including folder) like Jenkins.instance.getItem('folder_name/job_name'), I just get null as a result.

How do I access jobs in folders?

PortMan
  • 4,205
  • 9
  • 35
  • 61
  • 1
    Did you try using the `getItemByFullName`: `Jenkins.instance.getItemByFullName('folder_name/job_name')`? It may require an approval to use it in a Jenkinsfile. – Unforgettable631 Aug 07 '19 at 17:53

1 Answers1

20

You can use getItemByFullName to access a job by name: Jenkins.instance.getItemByFullName('folder_name/job_name'). It may require an approval to use it in a Jenkinsfile. This also opens up more possibilities by retrieving build statusses:

def buildName = Jenkins.instance.getItemByFullName('folder_name/job_name')
echo "Last success: ${buildName.getLastSuccessfulBuild()}"
echo "All builds: ${buildName.getBuilds().collect{ it.getNumber()}}"
echo "Last build: ${buildName.getLastBuild()}"
echo "Is building: ${job.isBuilding()}"

BUT, all of these may require an approval when using it via a Jenkinsfile. Output for example:

[Pipeline] echo
Last success: folder/job_name #761
[Pipeline] echo
All builds: [767, 766, 765, 764, 763, 762, 761, 760]
[Pipeline] echo
Last build: folder/job_name #767
[Pipeline] echo
Is building: true
Unforgettable631
  • 940
  • 6
  • 10
  • If I use this approach I do see the correct output but also get the exception: `java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob`. Any ideas why? – user1876484 Apr 05 '21 at 11:07
  • This line `def buildName = Jenkins.instance.getItemByFullName('folder_name/job_name')` seems to cause problems... Interesting that this exception doesn't happen on some places in Jenkinsfile and on others not... – user1876484 Apr 05 '21 at 11:33
  • [This](https://support.cloudbees.com/hc/en-us/articles/230612967-Pipeline-The-pipeline-even-if-successful-ends-with-java-io-NotSerializableException) has solved my issue. – user1876484 Apr 05 '21 at 13:17
  • There are two conditions for running into `NotSerializableException` in Jenkins. First, some built-in function returns a value of data type that is not serializable. Second, you store that value into a variable that stays in scope long enough to run into problems. Jenkins doesn't do "is every value in scope serializable?" checks all the time, but they are done before some specific steps (e.g. `echo`), it can also happen at any time, if e.g. Jenkins is restarted at this moment. – Gene Pavlovsky Apr 25 '23 at 09:56
  • One simple example: the `=~` regexp-matching operator returns a `Matcher`, which is not serializable. So if you save it to a variable, to do things like `def res = str =~ /.*(some-pattern).*/; if (res.matches()) echo res.group(1)` you may get an exception. But if you just do `if (str =~ /some-pattern/)` (this implicitly converts the result of `=~` to a bool), the non-serializable `Matcher` is not stored anywhere, it's used and then disposed of, so you will not run into any troubles. – Gene Pavlovsky Apr 25 '23 at 10:00
  • Finally, for solutions: when possible, avoid using data types that are not serializable. E.g. use the `readJSON` step or `groovy.json.JsonSlurperClassic` instead of `groovy.json.JsonSlurper` (which produces non-serializable `groovy.json.internal.LazyMap`). Second, if you must use non-serializable data, e.g. you want to use `=~` with groups, extract this code into a function and mark it with `@NonCPS` (don't forget to add `import com.cloudbees.groovy.cps.NonCPS`). Obviously the non-serializable data must not leave the function, all the work on such data should be done in the function. – Gene Pavlovsky Apr 25 '23 at 10:03
  • Finally, although I recommend using `@NonCPS` functions, sometimes you can get away without, by making sure you unset the variable containing non-serializable data as soon as you don't need it any longer. E.g. in your example, as soon as you're done working with `buildName`, do `buildName = null`. With this done, there are no longer any references to the non-serializable data. – Gene Pavlovsky Apr 25 '23 at 10:06