Search code examples
gradlejenkins-job-dsl

gradle generates xml from job-dsl-plugin


Has anyone setup a gradle build to generate Jobs DSL xml locally?

So I added a sourceSet for jobs and the plugin dependency. So I can build the groovy into classes. Now I think I want to add an execution task that I link to compile or maybe test that generates in a gradle equivalent to the following but I'm not quite sure of the best way to do this.

I have access to the jar already via classpath (in theory) so I should be able to exec easily

curl -O https://repo.jenkins-ci.org/public/org/jenkins-ci/plugins/job-dsl-core/@version@/job-dsl-core-@version@-standalone.jar
java -jar job-dsl-core-@version@-standalone.jar sample.dsl.groovy

build.gradle

sourceSets {
...
    jobs {
        groovy {
            srcDirs 'jenkins-job-dsl'
            compileClasspath += main.compileClasspath
        }
    }
}

dependencies {
...
compile "org.jenkins-ci.plugins:job-dsl-core:$version"
}

task buildOneUsingClassFile(type: JavaExec) {
    group = "Execution"
    classpath = sourceSets.jobs.runtimeClasspath + sourceSets.jobs.compileClasspath
    main = 'my_pipeline_dsl_job_class_name'
}

task generateDSLXml(type: JavaExec) {
    group = "Execution"
    description = "generate all found groovy dsl files"
    classpath = sourceSets.jobs.compileClasspath
    main = 'javaposse.jobdsl.Run'
    args sourceSets.jobs.groovy
      .filter { it.path.endsWith('.groovy') }
      .collect {it.path.toString() }
      .unique()
}

The above mostly works, except that I see failures that work on jenkins itself even with the same version. However, I see those same failures on https://job-dsl.herokuapp.com/ too so they may represent a different issue


Solution

  • Gradle

    • Add source set for job-dsl files
    • Add output dir for job-dsl ext.jobDslOutputDir
    • Add dependencies for job-dsl
    • Add task for job-dsl
    buildscript {
        ...
        ext {
        ...
            jobDslOutputDir = new File(buildDir, 'generated/jenkins-job-dsl')
        }
    
    }
    
    sourceSets {
        // our shared library internal code
        main {
            groovy {
                srcDirs = ['src']
            }
            resources {
                srcDirs = ['resources']
            }
        }
        // out shared library test code
        test {
            groovy {
                srcDirs = ['test']
            }
            resources {
                srcDirs = ['resources']
            }
        }
        // job DSL files
        jobs {
            groovy {
                srcDirs 'jenkins-job-dsl'
                compileClasspath += main.compileClasspath
            }
        }
    }
    
    dependencies {
        ...
        compile 'org.jenkins-ci.plugins.workflow:workflow-multibranch:2.24@jar'
        compile 'org.jenkins-ci.plugins:job-dsl-core:1.77'
    }
    
    
    // Generate Task
    task generateDSLXml(type: JavaExec) {
        doFirst {
            // ensure Project's ext.jobDslOutputDir directory exists
            jobDslOutputDir.mkdirs()
        }
    
        group = "Execution"
        description = "generate job xml for all found groovy dsl files"
        classpath = sourceSets.jobs.compileClasspath
        main = 'javaposse.jobdsl.Run'
        workingDir = jobDslOutputDir
        // collect all the groovy files found in the jobs source set for they represent
        // the job dsl files creating jobs
        args sourceSets.jobs.groovy.filter { it.path.endsWith('.groovy') }.collect { it.path.toString() }.unique()
    }
    
    // disable spotbugs for job DSL
    task spotbugs(
            group: "Verification",
            description: """Marker task to enable Spotbugs (disabled by default)."""
    )
    gradle.taskGraph.whenReady { taskGraph ->
        tasks.spotbugsMain.onlyIf { taskGraph.hasTask tasks.spotbugs }
        tasks.spotbugsTest.onlyIf { taskGraph.hasTask tasks.spotbugs }
        tasks.spotbugsJobs.onlyIf { false } // skip for job dsl
    }
    
    

    Job DSL multi branch and missing method problems

    For multi branch we should be able to use

    multibranchPipelineJob('my-build') {
        factory {
            workflowBranchProjectFactory {
                scriptPath('path-to-Jenkinsfile')
            }
        }
    }
    

    However this fails with a missing method error. When we refactor thus found here, generation works on dsl playground and via gradle

    
            it / factory(class: 'org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory') {
                owner(class: 'org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject', reference: '../..')
                scriptPath("jenkinsfile")
            }
        }