jenkinsci / configuration-as-code-plugin

Jenkins Configuration as Code Plugin
https://plugins.jenkins.io/configuration-as-code
MIT License
2.69k stars 718 forks source link

Additional classpath support for seed jobs specificed in jenkins.yaml #1355

Open frezbo opened 4 years ago

frezbo commented 4 years ago

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.

timja commented 4 years ago

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

frezbo commented 4 years ago

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.

jetersen commented 4 years ago

Seems like a odd use case.

The same can be achieved by using shared libraries.

frezbo commented 4 years ago

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

jetersen commented 4 years ago

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

frezbo commented 4 years ago

@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.

timbrown5 commented 4 years ago

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.

slempinen commented 2 years ago

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.

mathieucoavoux commented 2 years ago

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.

cowai commented 2 years ago

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.