configuration-as-code-plugin icon indicating copy to clipboard operation
configuration-as-code-plugin copied to clipboard

Additional classpath support for seed jobs specificed in jenkins.yaml

Open frezbo opened this issue 4 years ago • 10 comments

Additional classpath support for seed jobs specificed in jenkins.yaml

Feature Request

It would be nice to support having additional classpaths for initial seed job. We have a utility class that is re-used across multiple seed jobs.

frezbo avatar Apr 14 '20 12:04 frezbo

Can you give more details, with an example script as well please

timja avatar Apr 14 '20 12:04 timja

jenkins.yaml

jobs:                                                                                                              │
        - file: /var/jenkins_home/seed-jobs/seeds.groovy

/var/jenkins_home/seed-jobs/seeds.groovy

import JenkinsUtils

JenkinsUtils.createTFJob('foobar')

The JenkinsUtils is an external class present in /var/jenkins_home/seed-jobs. I would like to set the additional classpath for the seed job as /var/jenkins_home/seed-jobs and load all the shared code from there.

Let me know if this expains the use case.

frezbo avatar Apr 14 '20 12:04 frezbo

Seems like a odd use case.

The same can be achieved by using shared libraries.

jetersen avatar Apr 14 '20 12:04 jetersen

@jetersen Shared libraries are for pipeline DSL, not job DSL.

frezbo avatar Apr 14 '20 12:04 frezbo

depending how you write your seed job you can use a pipeline job for your seed.

jetersen avatar Apr 14 '20 12:04 jetersen

@jetersen I thought of that, but my seed jobs created a lot of other seed jobs, it just was too much complexity. :D. And the initial ones are so many so we pass in a hash map which gets parsed and creates the job. Now I have all my code with all utlities, just was trying to make it simpler and avoid code duplication.

frezbo avatar Apr 14 '20 13:04 frezbo

We have a similar requirement. All of our auto-generated jobs are generated using JCasC but we don't use seed jobs at all. This is because all of our jobs are defined in the same repo as our Jenkins container. When we launch our container JCasC loads .yml configs, similar to the one below:

jobs:
  - file: /var/jenkins_casc/groovy/jobs/platform_jobs.groovy

This will call a script which generated the jobs using JobDSL.

We currently have a lot of duplicate code and want to refactor. We have tried using classes, but they fail to load (I believe) because we cannot set the class-path to allow us to include the class.

I think I can work around this by moving all my jobs into one .groovy file, but this seems like it would become cumbersome quickly.

timbrown5 avatar Aug 24 '20 12:08 timbrown5

Any updates on this? From what I can tell right now there is no way to share code between JobDSL files when they are processed with JCasC.

slempinen avatar Jan 28 '22 14:01 slempinen

Hi, It may not be exactly what you are looking for but you can import a shared library with the following:

@Grapes(
    @Grab(group='org.yaml', module='snakeyaml', version='1.25')
)

import org.yaml.snakeyaml.Yaml

/* define a function that is using the shared library */
def getConfig(config_file) {
    Yaml parser = new Yaml()
    return parser.load((config_file as File).text)
}

job('/myjob') {
  label(getConfig('myfile.yml'))
  /* rest of the code
  */
}

In this example the shared library is available in mavenrepository Hope it helps.

mathieucoavoux avatar May 22 '22 21:05 mathieucoavoux

I found a workaround to load the other groovy on Job DSL while using JCasC and Job DSL:

// external.groovy
class Util {
  public static final String CREDENTIAL_ID = 'token_id'
  public static final STAGES = ['production', 'development', 'staging']
  public static hello(String something) {
    return "Hello, " + something
  }
}
// seed-job.groovy
String classSource = new File('/your/file/path/external.groovy').getText("UTF-8")
Class utilClass = new GroovyClassLoader().parseClass(classSource)
def util = utilClass.newInstance()

println util.CREDENTIAL_ID
println util.hello("world")
util.STAGES.each { stage ->
  println stage
}

Hope it helps.

cowai avatar Jul 26 '22 03:07 cowai