Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-37125

ability to write and use groovy classes from pipeline repos / scripts

    • Icon: New Feature New Feature
    • Resolution: Duplicate
    • Icon: Major Major
    • pipeline
    • None

      The `load` DSL method for Pipelines provides a nice way to load scripts and reference objects from a Pipeline script. However, it seems like it can be really useful to define simple classes in the SCM repo for a Pipeline job. E.g. just classes that represent simple data structures that you'd like to refer to in various steps of your pipelines, or Enum definitions, etc.

      Currently there does not seem to be a way to add to the classpath for the pipeline script so that an import would be able to pull in these class definitions. It would be really nice if there was a DSL method for adding to the classpath, or a way to define a property for the job that would allow you to specify additional classpath entries. It'd be totally fine for the scripting sandbox security requirements to apply to the groovy code loaded from the additional classpath entries.

          [JENKINS-37125] ability to write and use groovy classes from pipeline repos / scripts

          Chris Price added a comment -

          I poked around in the issue tracker and didn't see a ticket that appeared to capture this, but if I missed something please feel free to close it as a dupe.

          Chris Price added a comment - I poked around in the issue tracker and didn't see a ticket that appeared to capture this, but if I missed something please feel free to close it as a dupe.

          Chris Price added a comment - - edited

          I wrote a plugin that provides an addToClasspath step for pipeline jobs:

          https://github.com/cprice404/pipeline-classpath-step-plugin

          It works well for cases where your Jenkinsfile doesn't need to import any classes, but rather just calls load on other groovy scripts, and those groovy scripts import classes. However, if I try to put any import statements directly in my Jenkinsfile, they seem to get processed before any other lines in the file, so the addToClasspath step doesn't get a chance to execute and the import fails.

          In IRC it was mentioned that perhaps the pipeline jobs could automatically add .jenkins/src to their classpath, but it'd be much nicer if that was configurable somehow. e.g. if there was some property that could be set on the job to achieve it. If anyone can provide any hints on how that might be achievable I would be happy to try to work on the implementation further.

          Chris Price added a comment - - edited I wrote a plugin that provides an addToClasspath step for pipeline jobs: https://github.com/cprice404/pipeline-classpath-step-plugin It works well for cases where your Jenkinsfile doesn't need to import any classes, but rather just calls load on other groovy scripts, and those groovy scripts import classes. However, if I try to put any import statements directly in my Jenkinsfile , they seem to get processed before any other lines in the file, so the addToClasspath step doesn't get a chance to execute and the import fails. In IRC it was mentioned that perhaps the pipeline jobs could automatically add .jenkins/src to their classpath, but it'd be much nicer if that was configurable somehow. e.g. if there was some property that could be set on the job to achieve it. If anyone can provide any hints on how that might be achievable I would be happy to try to work on the implementation further.

          Chris Price added a comment - - edited

          Also, FWIW, for my particular use case I'm creating the pipeline jobs via the JobDSL plugin (because we have multiple Jenkinsfiles in a single repo), so if there was a way to add classpath setter method to the Pipeline job type and then call that from the JobDSL plugin that would work for us (though I imagine that coming up with a more general solution would be useful for many other users).

          Chris Price added a comment - - edited Also, FWIW, for my particular use case I'm creating the pipeline jobs via the JobDSL plugin (because we have multiple Jenkinsfiles in a single repo), so if there was a way to add classpath setter method to the Pipeline job type and then call that from the JobDSL plugin that would work for us (though I imagine that coming up with a more general solution would be useful for many other users).

          Chris Price added a comment - - edited

          It seems like this could be achieved by adding an additionalClasspathEntries or similar argument to the constructor of CpsScmFlowDefinition here, and then adding that to the GroovyShell somewhere around here.

          Does that seem like a reasonable idea? Can these FlowDefinition classes support multiple constructors so that this new argument could be optional and avoid breaking backward compatibility? I would be happy to try to work up a PR for this if it seems reasonable.

          Chris Price added a comment - - edited It seems like this could be achieved by adding an additionalClasspathEntries or similar argument to the constructor of CpsScmFlowDefinition here , and then adding that to the GroovyShell somewhere around here . Does that seem like a reasonable idea? Can these FlowDefinition classes support multiple constructors so that this new argument could be optional and avoid breaking backward compatibility? I would be happy to try to work up a PR for this if it seems reasonable.

          Chris Price added a comment - - edited

          jglick, in IRC, pointed me at GroovyShellDecorator. I can imagine adding a GroovyShellDecorator to the plugin, and having it check for a file like $workspace/.jenkins/additional_classpath_entries and if it finds it, read lines from the file and add them to the classpath for the GroovyShell. However, jglick warned that this won't work for jobs that are running on jenkins nodes other than the master because their workspaces will be remote :/

          Chris Price added a comment - - edited jglick, in IRC, pointed me at GroovyShellDecorator . I can imagine adding a GroovyShellDecorator to the plugin, and having it check for a file like $workspace/.jenkins/additional_classpath_entries and if it finds it, read lines from the file and add them to the classpath for the GroovyShell . However, jglick warned that this won't work for jobs that are running on jenkins nodes other than the master because their workspaces will be remote :/

          Jesse Glick added a comment -

          Fully covered by JENKINS-31155 I think.

          Jesse Glick added a comment - Fully covered by JENKINS-31155 I think.

            jglick Jesse Glick
            cprice404 Chris Price
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: