-
Notifications
You must be signed in to change notification settings - Fork 830
User Power Moves
When you get a little bit expert in your usage of the Job DSL and Plugin, you might want to try the following Power Moves:
Before you push a new DSL script to jenkins, it's helpful to run it locally and eyeball the resulting XML. To do this follow these steps:
- git clone https://github.com/jenkinsci/job-dsl-plugin.git
- cd job-dsl-plugin
- ./gradlew :job-dsl-core:oneJar
- DSL_JAR=$(find job-dsl-core -name '*standalone.jar'|tail -1)
- java -jar $DSL_JAR sample.dsl.groovy
If you already have the source code checked out then you can ignore step 1.
What's going on here is that there's a static main method that can run the DSL, you just have to give it a filename. It'll output all the jobs' XML to the current directory. Likewise, if you use "using" (the templates-like feature) it'll look in the current directory for a file with the name of the job appended with ".xml" at the end of it.
-
Add some job dsl content to a file, say job.dsl
-
Run the gradle command: ./gradlew run -Pargs=job.dsl
Note: the run task loads the file relative to the job-dsl-core directory, so I always just put my test files in there. Note2: if your dsl code contains a job named "myJob", the run task will generate myJob.xml.
The original discussion about this on the Newsgroup
To access the Jenkins Environment variables (such as BUILD_NUMBER) from within DSL scripts just wrap them in '${}'. E.g.:
println " BUILD_NUMBER = ${BUILD_NUMBER}"
Some of the available variables are as follows:
- BUILD_CAUSE
- BUILD_CAUSE_USERIDCAUSE
- BUILD_ID
- BUILD_NUMBER
- BUILD_TAG
- EXECUTOR_NUMBER
- HOME
- HUDSON_HOME
- HUDSON_SERVER_COOKIE
- JENKINS_HOME
- JENKINS_SERVER_COOKIE
- JOB_NAME
- LANG
- LOGNAME
- NODE_LABELS
- NODE_NAME
- OLDPWD
- PWD
- SHELL
- TERM
- TMPDIR
- USER
Original discussion on the newsgroup
Build parameters are exposed as environment variables in Jenkins. A seed job build parameter named FOO
is available as
FOO
variable in the DSL scripts. See the section about environment variables above.
The job you create could be running on a slave, while the plugin runs on the master. Which means you shouldn't directly reference files on filesystem, since we're in a distributed system. The good news is that we added a method to help with this. See the docs for "Reading Files from Workspace" on https://github.com/jenkinsci/job-dsl-plugin/wiki/Job-DSL-Commands
Original discussion on the newsgroup
Knowing when to overwrite or append to the XML is a fundamental problem with our approach. In the beginning of the project we though to append always, but we quickly learned that it takes a lot more work to intelligently append. We then took the approach to append when possible and easy, otherwise just overwrite. Since then many users have found themselves just building up jobs from scratch and not worrying about existing values in templates, essentially taking a "we leave you alone if you leave us alone" approach.
I'd be interested in hearing from the community how often templates are used (aka using() syntax) and if the manipulations are additive (adding to exist structures) or constructive (creating new structures).
Users should also note that we're pretty bad about multiple calls being made in your DSL script to the same command, and we could be better. E.g. calling environmentVariables multiple times would leave the result of the last call as the winner. An alternative to this would be to defer its creation, accumulating the vars as we went. Once again, that takes more work and its something we can add later if needed. We should also document this better. So, if people see one behavior or other, please add it to the docs or bring it to our attention.
Original discussion on the newsgroup
If you want more than one SVN location in your SCM block:
scm {
svn('http://svn-mirror.xxx.lan/svn/internal/zzz/trunk', 'trunk') {
it / locations << 'hudson.scm.SubversionSCM_-ModuleLocation' {
remote 'http://svn-mirror.xxx.lan/svn/zzz/trunk'
local 'trunk/community'
}
}
}
Original discussion on the newsgroup
Libraries can be used in a Job DSL script by adding them to the Additional classpath option in the Process Job DSLs build step. The library's JAR files must be available in the workspace of the seed job. For libraries without transitive dependencies this can be achieved by using the Artifact Resolver build step of the Repository Connector Plugin prior to the Process Job DSLs build step. For more complex setups, an extra Gradle build step (Gradle Plugin) can be used.
For example, to use Koshuke's GitHub API, the following build.gradle
will copy all
necessary libraries to a lib
directory:
defaultTasks 'libs'
repositories {
jcenter()
}
configurations {
libs
}
dependencies {
libs 'org.kohsuke:github-api:1.50'
}
task clean(type: Delete) {
delete 'lib'
}
task libs(type: Copy) {
into 'lib'
from configurations.libs
}
task wrapper(type: Wrapper) {
gradleVersion = '2.2.1'
}
The Additional classpath option in the Process Job DSLs build step must be set to lib/*.jar
to pick up all
libraries. And then the library can be used in a Job DSL script:
import org.kohsuke.github.GitHub
def gh = GitHub.connectAnonymously()
gh.getOrganization('jenkinsci').listRepositories().each { repo ->
job(repo.name) {
scm {
gitHub(repo.fullName)
}
steps {
// ...
}
}
}
Sometimes you want your DSL script to be able to grab a list of the files in the workspace. Use the Hudson API to achieve this:
hudson.FilePath workspace = hudson.model.Executor.currentExecutor().getCurrentWorkspace()
If you don't want the output job config.xml to start with a "project" node, you can use this little hack:
configure { project ->
project.name = 'com.cloudbees.plugins.flow.BuildFlow'
}
But note, this will only work if the BuildFlow project type uses the same sub-elements as the free style project type. If this is not the case, you need to modify the root node further and things will get even uglier. (Hint, you can use configure)
Gradle provides a way to build and test your scripts and supporting classes. See job-dsl-gradle-example for an example.
Stack Overflow | Mailing List | API Reference | Issue Tracker | Playground | Plugin | Wiki | GitHub
Home
Release Notes
Migration
Talks and Blog Posts
Documentation
Tutorial
Dynamic DSL
Configure Blocks
Job DSL Commands
Script Security
Handling Credentials
Configuration as Code
FAQ
Real World Examples
User Power Moves
IDE Support
Testing DSL Scripts
For Developers
Extending the DSL
Job DSL Architecture