SlideShare a Scribd company logo
An example on how to introduce the Job DSL Plugin in a real life company
Rule Jenkins with Configuration as Code
Jenkins World, 14.09.2016
….…............................ An example on how to introduce Job DSL in a real life company
What this talk is about
• Configuration as code with the Job DSL Plugin
• How to take it to the next level
• Pitfalls and how to make them foolproof
Intro Configuration as Code Test your codeThe next level
An example on how to introduce Job DSL in a real life company
What this talk is not about
• Job DSL in detail – please refer to:
Adoption of the Job DSL Plugin at Netflix
by Justin Ryan
Configuration as Code: The Job DSL Plugin
by Daniel Spilker at JUC Europe 2015
Jenkins + Groovy with the Job DSL Plugin
by Matt Sheehan at GR8Conf US 2015
….…............................Intro Configuration as Code Test your codeThe next level
Christian Rasp / christian.rasp@PAYBACK.net / @crasp
An example on how to introduce Job DSL in a real life company
• Software Developer DevOps
• Jenkins & Nexus Admin
• Build Engineer for CI & CD
….…............................Intro Configuration as Code Test your codeThe next level
PAYBACK is continuously expanding into new countries
An example on how to introduce Job DSL in a real life company
2000
2009
2014 2010
2012
2015
….…............................Intro Configuration as Code Test your codeThe next level
PAYBACK – Biggest loyalty program and largest multichannel marketing platform
An example on how to introduce Job DSL in a real life company
In 2015, 20 bn coupons were distributed to
customers in Germany
Points to the value of € 338 m were
collected in 2015
95% of all PAYBACK points get
redeemed!
8 out of 10 Germans are familiar
with the PAYBACK brand
Sales of more than € 27 bn
are generated with PAYBACK cards
at partner stores (2015)
The PAYBACK card is the third most
important card in German wallets
(after debit cards and credit cards, TNS Emnid survey, 2014)
….…............................Intro Configuration as Code Test your codeThe next level
An example on how to introduce Job DSL in a real life company
In May 2015 PAYBACK was launched in the US under the name "Plenti"
….…............................Intro Configuration as Code Test your codeThe next level
….…............................ An example on how to introduce Job DSL in a real life company
Intro Configuration as Code Test your codeThe next level
Configuration as code with the Job DSL Plugin
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
The initial problem
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
• What is this job doing?
The initial problem
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
• What is this job doing?
• Is the job still in use?
The initial problem
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
The initial problem
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
The initial problem
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
The initial problem
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
The initial problem
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
All Jenkins job configuration is setup manually:
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for a group of jobs?
The initial problem
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• Script console
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• Script console
• Templates
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• Script console
• Templates
• Job generator Plugin
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• Script console
• Templates
• Job generator Plugin
• REST API or CLI
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• Script console
• Templates
• Job generator Plugin
• REST API or CLI
• Pipeline Plugin
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• Script console
• Templates
• Job generator Plugin
• REST API or CLI
• Pipeline Plugin
• Job DSL Plugin
Possible solutions
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• Script console
• Templates
• Job generator Plugin
• REST API or CLI
• Pipeline Plugin
• Job DSL Plugin
Describe jobs using a Groovy-based language
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
Describe jobs using a Groovy-based language
An example on how to introduce Job DSL in a real life company
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
logRotator(-1, 30)
jdk('jdk-1.8.0_45')
wrappers {
mavenRelease {
releaseGoals('-Dresume=false release:prepare release:perform')
dryRunGoals('-Dresume=false -DdryRun=true release:prepare')
numberOfReleaseBuildsToKeep(2)
selectScmCredentials(true)
}
}
goals('clean install --batch-mode --update-snapshots')
mavenInstallation('maven-3.2.2')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk") {
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
….…............................Intro Configuration as Code Test your codeThe next level
Describe jobs using a Groovy-based language
An example on how to introduce Job DSL in a real life company
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
logRotator(-1, 30)
jdk('jdk-1.8.0_45')
wrappers {
mavenRelease {
releaseGoals('-Dresume=false release:prepare release:perform')
dryRunGoals('-Dresume=false -DdryRun=true release:prepare')
numberOfReleaseBuildsToKeep(2)
selectScmCredentials(true)
}
}
goals('clean install --batch-mode --update-snapshots')
mavenInstallation('maven-3.2.2')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk") {
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
….…............................Intro Configuration as Code Test your codeThe next level
It still does not fit our needs
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for subset of jobs?
It still does not fit our needs
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for subset of jobs?
It still does not fit our needs
An example on how to introduce Job DSL in a real life company
• New scripting language
• New DSL reference to learn
….…............................Intro Configuration as Code Test your codeThe next level
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for subset of jobs?
An example on how to introduce Job DSL in a real life company
How to take it to the next level
….…............................Intro Configuration as Code Test your codeThe next level
Make a developers life as easy as possible
An example on how to introduce Job DSL in a real life company
Things a Jenkins user should not need to know about:
….…............................Intro Configuration as Code Test your codeThe next level
Make a developers life as easy as possible
An example on how to introduce Job DSL in a real life company
• Standard log rotation
Things a Jenkins user should not need to know about:
….…............................Intro Configuration as Code Test your codeThe next level
Make a developers life as easy as possible
An example on how to introduce Job DSL in a real life company
• Standard log rotation
• Configuration pitfalls
Things a Jenkins user should not need to know about:
….…............................Intro Configuration as Code Test your codeThe next level
Make a developers life as easy as possible
An example on how to introduce Job DSL in a real life company
• Standard log rotation
• Configuration pitfalls
• Credentials for tech. users
Things a Jenkins user should not need to know about:
….…............................Intro Configuration as Code Test your codeThe next level
Make a developers life as easy as possible
An example on how to introduce Job DSL in a real life company
• Standard log rotation
• Configuration pitfalls
• Credentials for tech. users
• Naming conventions
Things a Jenkins user should not need to know about:
….…............................Intro Configuration as Code Test your codeThe next level
Make a developers life as easy as possible
An example on how to introduce Job DSL in a real life company
• Standard log rotation
• Configuration pitfalls
• Credentials for tech. users
• Naming conventions
• Jenkins Maven magic
Things a Jenkins user should not need to know about:
….…............................Intro Configuration as Code Test your codeThe next level
Make a developers life as easy as possible
An example on how to introduce Job DSL in a real life company
• Standard log rotation
• Configuration pitfalls
• Credentials for tech. users
• Naming conventions
• Jenkins Maven magic
• Default settings
Things a Jenkins user should not need to know about:
….…............................Intro Configuration as Code Test your codeThe next level
So what IS the next level?
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
• Standards
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
• Standards
• Convention
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
• Standards
• Convention
• Clean project structure
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
• Standards
• Convention
• Clean project structure
• Dependency management
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
• Standards
• Convention
• Clean project structure
• Dependency management
• Reviews
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
• Standards
• Convention
• Clean project structure
• Dependency management
• Reviews
• Tests!
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
So what IS the next level?
An example on how to introduce Job DSL in a real life company
• Inheritance
• Standards
• Convention
• Clean project structure
• Dependency management
• Reviews
• Tests!
• More tests!
….…............................Intro Configuration as Code Test your codeThe next level
Build your own tool with standard software engineering approaches:
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
logRotator(-1, 30)
jdk('jdk-1.8.0_45')
wrappers {
mavenRelease {
releaseGoals('-Dresume=false release:prepare release:perform')
dryRunGoals('-Dresume=false -DdryRun=true release:prepare')
numberOfReleaseBuildsToKeep(2)
selectScmCredentials(true)
}
}
goals('clean install --batch-mode --update-snapshots')
mavenInstallation('maven-3.2.2')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk")
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
Reduce the configuration to a bare minimum
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
jdk('jdk-1.8.0_45')
wrappers {
mavenRelease {
releaseGoals('-Dresume=false release:prepare release:perform')
dryRunGoals('-Dresume=false -DdryRun=true release:prepare')
numberOfReleaseBuildsToKeep(2)
selectScmCredentials(true)
}
}
goals('clean install --batch-mode --update-snapshots')
mavenInstallation('maven-3.2.2')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk")
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
Reduce the configuration to a bare minimum
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
wrappers {
mavenRelease {
releaseGoals('-Dresume=false release:prepare release:perform')
dryRunGoals('-Dresume=false -DdryRun=true release:prepare')
numberOfReleaseBuildsToKeep(2)
selectScmCredentials(true)
}
}
goals('clean install --batch-mode --update-snapshots')
mavenInstallation('maven-3.2.2')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk")
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
Reduce the configuration to a bare minimum
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
goals('clean install --batch-mode --update-snapshots')
mavenInstallation('maven-3.2.2')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk")
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
Reduce the configuration to a bare minimum
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
mavenInstallation('maven-3.2.2')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk")
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
Reduce the configuration to a bare minimum
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
description('I'm sorry Dave, I'm afraid I can't do that')
scm {
svn {
location("${Repositories.DISCOVERY.url()}/dave/trunk")
checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT)
}
}
[...]
Reduce the configuration to a bare minimum
An example on how to introduce Job DSL in a real life company
….…............................Intro Configuration as Code Test your codeThe next level
Reduce the configuration to a bare minimum
An example on how to introduce Job DSL in a real life company
new MavenJobBuilder(this, 'HAL9000').make {
description("I'm sorry Dave, I'm afraid I can't do that")
svn(Repositories.DISCOVERY, '/trunk')
}
….…............................Intro Configuration as Code Test your codeThe next level
Use builder pattern to create simple job builders
An example on how to introduce Job DSL in a real life company
http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html
Groovy Goodness from
the Blog of MrHaki
….…..................….......Intro Configuration as Code Test your codeThe next level
Use builder pattern to create simple job builders
An example on how to introduce Job DSL in a real life company
// Build your own closures to expand Job DSL
private runClosure(Closure runClosure) {
// Create clone of closure for threading access.
Closure runClone = runClosure.clone()
// Set delegate of closure to this builder.
runClone.delegate = this
// And only use this builder as the closure delegate.
runClone.resolveStrategy = Closure.DELEGATE_ONLY
// Run closure code.
runClone()
}
http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html
Groovy Goodness from
the Blog of MrHaki
….…..................….......Intro Configuration as Code Test your codeThe next level
Use builder pattern to create simple job builders
An example on how to introduce Job DSL in a real life company
// Build your own closures to expand Job DSL
private runClosure(Closure runClosure) {
// Create clone of closure for threading access.
Closure runClone = runClosure.clone()
// Set delegate of closure to this builder.
runClone.delegate = this
// And only use this builder as the closure delegate.
runClone.resolveStrategy = Closure.DELEGATE_ONLY
// Run closure code.
runClone()
}
http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html
Groovy Goodness from
the Blog of MrHaki
….…..................….......Intro Configuration as Code Test your codeThe next level
// Delegate everything else to Job DSL
def methodMissing(String name, argument) {
job.invokeMethod(name, (Object[]) argument)
}
Use builder pattern to create simple job builders
An example on how to introduce Job DSL in a real life company
http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html
Groovy Goodness from
the Blog of MrHaki
….…..................….......Intro Configuration as Code Test your codeThe next level
new JobBuilder(this, 'adjust-permissions').make {
// Own function via runClosure
restrictPermissions('ernie', 'bert', 'jenkins-admins')
// Original Job DSL syntax via methodMissing
steps {
shell('ls -l')
}
}
Set some standards automatically
public class JobBuilder extends Builder {
protected Job job
// Create a new job object
JobBuilder(DslFactory dslFactory, String jobName) {
this.job = dslFactory.job(jobName)
}
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Set some standards automatically
public class JobBuilder extends Builder {
protected Job job
// Create a new job object
JobBuilder(DslFactory dslFactory, String jobName) {
this.job = dslFactory.job(jobName)
}
// Defines initial state for a job
Job make(Closure additionalConfig) {
// Standards for all jobs
job.logRotator
job.jdk
job.label
// every other configurations
runClosure additionalConfig
job
}
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Set some standards automatically
// Defines initial state for a job
Job make(Closure additionalConfig) {
// Standards for all jobs
job.logRotator
job.jdk
job.label
// every other configurations
runClosure additionalConfig
job
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
[...]
logRotator(-1, 30)
jdk('jdk-1.8.0_45')
[...]
}
Set some standards automatically
// Defines initial state for a job
Job make(Closure additionalConfig) {
// Standards for all jobs
job.logRotator
job.jdk
job.label
// every other configurations
runClosure additionalConfig
job
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
[...]
logRotator(-1, 30)
jdk('jdk-1.8.0_45')
[...]
}
Set some standards automatically
// Defines initial state for a job
Job make(Closure additionalConfig) {
// Standards for all jobs
job.logRotator
job.jdk
job.label
// every other configurations
runClosure additionalConfig
job
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
mavenJob('HAL9000') {
[...]
logRotator(-1, 30)
jdk('jdk-1.8.0_45')
[...]
}
What are the standard settings?
Hide complex configuration settings
An example on how to introduce Job DSL in a real life company
class MavenJobBuilder extends JobBuilder {
MavenJobBuilder(DslFactory dslFactory, String jobName) {
super(dslFactory.mavenJob(jobName))
}
MavenJob make(Closure additionalConfig) {
job.wrappers {
mavenRelease {
releaseGoals
numberOfReleaseBuildsToKeep
}
}
job.goals
job.mavenInstallation
[...]
super.make(additionalConfig)
job as MavenJob
}
}
….…..................….......Intro Configuration as Code Test your codeThe next level
Hide complex configuration settings
An example on how to introduce Job DSL in a real life company
job.wrappers {
mavenRelease {
releaseGoals
numberOfReleaseBuildsToKeep
}
}
job.goals
job.mavenInstallation
….…..................….......Intro Configuration as Code Test your codeThe next level
Hide complex configuration settings
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
new MavenJobBuilder(this, 'YourEasyMavenJobHere').make {
[...]
}
Encapsulate common DSL patterns
void svn(Repositories repository,
String loc,
String dir = '.',
SvnCheckoutStrategy strategy = SvnCheckoutStrategy.UPDATE_WITH_REVERT) {
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Encapsulate common DSL patterns
void svn(Repositories repository,
String loc,
String dir = '.',
SvnCheckoutStrategy strategy = SvnCheckoutStrategy.UPDATE_WITH_REVERT) {
job.scm {
svn {
location("${repository.url()}${loc}") {
credentials(repository.credential())
directory(dir)
}
checkoutStrategy(strategy)
}
}
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Encapsulate common DSL patterns
svn(Repositories.FOO, '/UTIL/trunk')
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Encapsulate common DSL patterns
svn(Repositories.FOO, '/UTIL/trunk')
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Encapsulate common DSL patterns
svn(Repositories.FOO, '/UTIL/trunk')
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Why is it configured that way?
Encapsulate common DSL patterns
void cron(Cron c) {
job.triggers {
cron(c.getTab())
}
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Encapsulate common DSL patterns
void cron(Cron c) {
job.triggers {
cron(c.getTab())
}
}
enum Cron {
FIVE_MINUTES( 'H/5 * * * *', 'Once in five minutes'),
FIFTEEN_MINUTES( 'H/15 * * * *', 'Once in fifteen minutes'),
THIRTY_MINUTES( 'H/30 * * * *', 'Once every thirty minutes'),
HOURLY( 'H * * * *', 'Once an hour'),
WEEKDAY_TWO_HOURLY('H 8-18/2 * * 1-5', 'Once every two hours every weekday'),
MIDNIGHT( 'H H(0-2) * * *', 'Once right after midnight'),
DAILY( 'H H * * *', 'Once a day'),
WEEKLY( 'H H * * H', 'Once a week'),
MONTHLY( 'H H H * *', 'Once a month')
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Encapsulate common DSL patterns
cron(Cron.FIFTEEN_MINUTES)
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Easy-to-read configurations
new JobBuilder(this, 'run-script').make {
steps {
shell('''ssh $KEY_FILE $USER@FOO <<'END' java -jar cli.jar PROJECTIMPORT 
-host localhost 
-port 12345 
-HTTP 
-user "${USER}" 
-password "${PASSWORD}" 
-project "${PROJECT_NAME}" 
-projectFile "${PROJECT_FILE}" 
-dbuser '"$(grep "content.jdbc.USER" database.conf | cut -d "=" -f2-)"' 
-dbpassword '"$(grep "content.jdbc.PASSWORD" database.conf | cut -d "=" -f2-)"' 
-dburl '"$(grep "content.jdbc.URL" database.conf | cut -d "=" -f2-)"' 
-dbschema '"$(grep "content.jdbc.SCHEMA" database.conf | cut -d "=" -f2-)"'
END''')
}
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Easy-to-read configurations
new JobBuilder(this, 'run-script').make {
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
def scriptfile = readFileFromWorkspace('src/main/resources/bin/scriptfile.sh')
steps {
shell(scriptfile)
}
}
Easy-to-read configurations
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Easy-to-read configurations
new MavenJobBuilder(this, 'build-new-deathstar').make {
svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball')
cronScm(Cron.EVERY_MOVIE)
sendMail('darth.vader@empire.dark.net')
sendMail('sheev.palpatine@empire.dark.net')
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Easy-to-read configurations
new MavenJobBuilder(this, 'build-new-deathstar').make {
svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball')
cronScm(Cron.EVERY_MOVIE)
sendMail('darth.vader@empire.dark.net')
sendMail('sheev.palpatine@empire.dark.net')
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
new MavenJobBuilder(this, 'build-super-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.WEEKLY)
expandMavenGoals('--activate-profiles super')
}
Easy-to-read configurations
new MavenJobBuilder(this, 'build-new-deathstar').make {
svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball')
cronScm(Cron.EVERY_MOVIE)
sendMail('darth.vader@empire.dark.net')
sendMail('sheev.palpatine@empire.dark.net')
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
new MavenJobBuilder(this, 'build-super-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.WEEKLY)
expandMavenGoals('--activate-profiles super')
}
new MavenJobBuilder(this, 'build-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.DAILY)
reportEmpireAcceptanceTests()
}
Easy-to-read configurations
new MavenJobBuilder(this, 'build-new-deathstar').make {
svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball')
cronScm(Cron.EVERY_MOVIE)
sendMail('darth.vader@empire.dark.net')
sendMail('sheev.palpatine@empire.dark.net')
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
new MavenJobBuilder(this, 'build-super-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.WEEKLY)
expandMavenGoals('--activate-profiles super')
}
new MavenJobBuilder(this, 'build-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.DAILY)
reportEmpireAcceptanceTests()
}
Who is responsible for this job?
Easy-to-read configurations
new MavenJobBuilder(this, 'build-new-deathstar').make {
svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball')
cronScm(Cron.EVERY_MOVIE)
sendMail('darth.vader@empire.dark.net')
sendMail('sheev.palpatine@empire.dark.net')
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
new MavenJobBuilder(this, 'build-super-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.WEEKLY)
expandMavenGoals('--activate-profiles super')
}
new MavenJobBuilder(this, 'build-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.DAILY)
reportEmpireAcceptanceTests()
}
Who is responsible for this job?
What is this job doing?
Easy-to-read configurations
new MavenJobBuilder(this, 'build-new-deathstar').make {
svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball')
cronScm(Cron.EVERY_MOVIE)
sendMail('darth.vader@empire.dark.net')
sendMail('sheev.palpatine@empire.dark.net')
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
new MavenJobBuilder(this, 'build-super-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.WEEKLY)
expandMavenGoals('--activate-profiles super')
}
new MavenJobBuilder(this, 'build-star-destroyers').make {
svn(Repositories.DARKEMPIRE, '/spaceships/destroyers')
cronScm(Cron.DAILY)
reportEmpireAcceptanceTests()
}
How to change settings for
a group of jobs?
Who is responsible for this job?
What is this job doing?
Easy-to-read configurations
DevEnvironment.values().each { environment ->
new DeployJobBuilder(this, 'Deploy-${environment.getEnvName()}').make {
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Easy-to-read configurations
DevEnvironment.values().each { environment ->
new DeployJobBuilder(this, 'Deploy-${environment.getEnvName()}').make {
job.environmentVariables {
env('ENVIRONMENT_NAME', environment.getEnvName())
env('BRANCH', environment.getBranch())
env('TEST_DATA', environment.getTestData())
if (DevEnvironment.UAT.equals(environment)) {
env('UAT', true)
}
[...]
}
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Easy-to-read configurations
DevEnvironment.values().each { environment ->
new DeployJobBuilder(this, 'Deploy-${environment.getEnvName()}').make {
job.environmentVariables {
env('ENVIRONMENT_NAME', environment.getEnvName())
env('BRANCH', environment.getBranch())
env('TEST_DATA', environment.getTestData())
if (DevEnvironment.UAT.equals(environment)) {
env('UAT', true)
}
[...]
}
}
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
enum DevEnvironment {
STAGE1('system-integration', Branch.SIT, '#customer'),
STAGE2('performance', Branch.PRF, '#customer'),
UAT( 'external-test', Branch.ET, '#customer#partner'),
PROD( 'production', Branch.MASTER, '#full')
}
Project structure
.
├── pom.xml # build file
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Project structure
.
├── pom.xml # build file
├── src
│ ├── main
│ │ ├── groovy # job builder and support classes
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Project structure
.
├── pom.xml # build file
├── src
│ ├── main
│ │ ├── groovy # job builder and support classes
│ │ └── resources
│ │ ├── bin # common scripts (shell, batch, groovy etc.)
│ │ ├── jobs # DSL script files for jobs
│ │ └── views # DSL script files for views
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Project structure
.
├── pom.xml # build file
├── src
│ ├── main
│ │ ├── groovy # job builder and support classes
│ │ └── resources
│ │ ├── bin # common scripts (shell, batch, groovy etc.)
│ │ ├── jobs # DSL script files for jobs
│ │ └── views # DSL script files for views
│ └── test
│ ├── groovy # specs for the job builders and their functionality
│ └── resources # script files for tests
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Project structure
.
├── pom.xml # build file
├── src
│ ├── main
│ │ ├── groovy # job builder and support classes
│ │ └── resources
│ │ ├── bin # common scripts (shell, batch, groovy etc.)
│ │ ├── jobs # DSL script files for jobs
│ │ └── views # DSL script files for views
│ └── test
│ ├── groovy # specs for the job builders and their functionality
│ └── resources # script files for tests
└── target
└── debug-xml # output directory for all generated items during test
├── jobs # Useful to diff job changes
└── views
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
Project dependencies
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
<dependency>
<groupId>net.payback.ci</groupId>
<artifactId>dslbuilder</artifactId>
<version>${dslbuilder.version}</version>
</dependency>
<modules>
<module>dev-bi</module>
<module>dev-core</module>
<module>dev-performance</module>
<module>dev-portal</module>
[…]
<module>dev-vagrant</module>
</modules>
Project dependencies
Main project with common builders, functions
and tests. Has its own release cycle.
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
<dependency>
<groupId>net.payback.ci</groupId>
<artifactId>dslbuilder</artifactId>
<version>${dslbuilder.version}</version>
</dependency>
<modules>
<module>dev-bi</module>
<module>dev-core</module>
<module>dev-performance</module>
<module>dev-portal</module>
[…]
<module>dev-vagrant</module>
</modules>
Project dependencies
Main project with common builders, functions
and tests. Has its own release cycle.
Own modules for every team, department or
the same area of responsibility
An example on how to introduce Job DSL in a real life company
….…..................….......Intro Configuration as Code Test your codeThe next level
<dependency>
<groupId>net.payback.ci</groupId>
<artifactId>dslbuilder</artifactId>
<version>${dslbuilder.version}</version>
</dependency>
<modules>
<module>dev-bi</module>
<module>dev-core</module>
<module>dev-performance</module>
<module>dev-portal</module>
[…]
<module>dev-vagrant</module>
</modules>
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
….…..................….......Intro Configuration as Code Test your codeThe next level
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
….…..................….......Intro Configuration as Code Test your codeThe next level
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Get all the benefits from VCS
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for
a group of jobs?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Get all the benefits from VCS
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for
a group of jobs?
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Get all the benefits from VCS
Refactor or search and replace
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for
a group of jobs?
• New scripting language
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Get all the benefits from VCS
Refactor or search and replace
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for
a group of jobs?
• New scripting language
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Get all the benefits from VCS
Refactor or search and replace
Simplified with custom builders
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for
a group of jobs?
• New scripting language
• New DSL reference to learn
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Get all the benefits from VCS
Refactor or search and replace
Simplified with custom builders
Resolve ALL the issues
An example on how to introduce Job DSL in a real life company
http://knowyourmeme.com/memes/x-all-the-y
• What is this job doing?
• Is the job still in use?
• Who is responsible for this job?
• Why is it configured that way?
• What are the standard settings?
• Who changed what and when?
• How to change settings for
a group of jobs?
• New scripting language
• New DSL reference to learn
….…..................….......Intro Configuration as Code Test your codeThe next level
Minimum config, easy to read
Look at the commits
Everyone can read it, own modules
Simple methods for complex stuff
Set basics in job builders
Get all the benefits from VCS
Refactor or search and replace
Simplified with custom builders
Outstanding API viewer ;)
An example on how to introduce Job DSL in a real life company
How to make it foolproof
.........................….......Intro Configuration as Code Test your codeThe next level
How to make it foolproof
An example on how to introduce Job DSL in a real life company
People will do the same thing in the code, as they did before via the UI
.........................….......Intro Configuration as Code Test your codeThe next level
How to make it foolproof
• Copy & Paste of job builders
An example on how to introduce Job DSL in a real life company
People will do the same thing in the code, as they did before via the UI
.........................….......Intro Configuration as Code Test your codeThe next level
How to make it foolproof
• Copy & Paste of job builders
• Write jobs in pure dsl syntax, but forget about standards
An example on how to introduce Job DSL in a real life company
People will do the same thing in the code, as they did before via the UI
.........................….......Intro Configuration as Code Test your codeThe next level
How to make it foolproof
• Copy & Paste of job builders
• Write jobs in pure dsl syntax, but forget about standards
• Use anti-patterns in code, configuration will be unreadable again
An example on how to introduce Job DSL in a real life company
People will do the same thing in the code, as they did before via the UI
.........................….......Intro Configuration as Code Test your codeThe next level
How to make it foolproof
• Copy & Paste of job builders
• Write jobs in pure dsl syntax, but forget about standards
• Use anti-patterns in code, configuration will be unreadable again
An example on how to introduce Job DSL in a real life company
People will do the same thing in the code, as they did before via the UI
.........................….......Intro Configuration as Code Test your codeThe next level
WRITE TESTS
How to make it foolproof
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
Test Example from https://github.com/sheehan/job-dsl-gradle-example
An example on how to introduce Job DSL in a real life company
class JobScriptsSpec extends Specification {
@Unroll
void 'test script #file.name'(File file) {
given:
when:
then:
where:
[...]
}
...................................Intro Configuration as Code Test your codeThe next level
Test Example from https://github.com/sheehan/job-dsl-gradle-example
An example on how to introduce Job DSL in a real life company
class JobScriptsSpec extends Specification {
@Unroll
void 'test script #file.name'(File file) {
given:
JobManagement jm = Spy(MemoryJobManagement)
[...]
when:
then:
where:
[...]
}
...................................Intro Configuration as Code Test your codeThe next level
Test Example from https://github.com/sheehan/job-dsl-gradle-example
An example on how to introduce Job DSL in a real life company
class JobScriptsSpec extends Specification {
@Unroll
void 'test script #file.name'(File file) {
given:
JobManagement jm = Spy(MemoryJobManagement)
[...]
when:
DslScriptLoader(jm).runScript(file.text)
then:
where:
[...]
}
...................................Intro Configuration as Code Test your codeThe next level
Test Example from https://github.com/sheehan/job-dsl-gradle-example
An example on how to introduce Job DSL in a real life company
class JobScriptsSpec extends Specification {
@Unroll
void 'test script #file.name'(File file) {
given:
JobManagement jm = Spy(MemoryJobManagement)
[...]
when:
DslScriptLoader(jm).runScript(file.text)
then:
noExceptionThrown()
where:
[...]
}
...................................Intro Configuration as Code Test your codeThe next level
Test Example from https://github.com/sheehan/job-dsl-gradle-example
An example on how to introduce Job DSL in a real life company
class JobScriptsSpec extends Specification {
@Unroll
void 'test script #file.name'(File file) {
given:
JobManagement jm = Spy(MemoryJobManagement)
[...]
when:
DslScriptLoader(jm).runScript(file.text)
then:
noExceptionThrown()
where:
file << jobFiles
}
[...]
}
...................................Intro Configuration as Code Test your codeThe next level
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
........................…........Intro Configuration as Code Test your codeThe next level
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
........................…........Intro Configuration as Code Test your codeThe next level
<project>
<triggers>
<hudson.triggers.TimerTrigger>
<spec>H * * * *</spec>
</hudson.triggers.TimerTrigger>
</triggers>
</project>
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
// is any trigger set?
triggers
........................…........Intro Configuration as Code Test your codeThe next level
<project>
<triggers>
<hudson.triggers.TimerTrigger>
<spec>H * * * *</spec>
</hudson.triggers.TimerTrigger>
</triggers>
</project>
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
// is any trigger set?
triggers
// is trigger a timer trigger?
triggers.'hudson.triggers.TimerTrigger'
........................…........Intro Configuration as Code Test your codeThe next level
<project>
<triggers>
<hudson.triggers.TimerTrigger>
<spec>H * * * *</spec>
</hudson.triggers.TimerTrigger>
</triggers>
</project>
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
// is any trigger set?
triggers
// is trigger a timer trigger?
triggers.'hudson.triggers.TimerTrigger'
// trigger is NOT an scm trigger?
!triggers.'hudson.triggers.SCMTrigger'
........................…........Intro Configuration as Code Test your codeThe next level
<project>
<triggers>
<hudson.triggers.TimerTrigger>
<spec>H * * * *</spec>
</hudson.triggers.TimerTrigger>
</triggers>
</project>
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
// is any trigger set?
triggers
// is trigger a timer trigger?
triggers.'hudson.triggers.TimerTrigger'
// trigger is NOT an scm trigger?
!triggers.'hudson.triggers.SCMTrigger'
// has trigger a specific value?
triggers.text().equals('H * * * *')
........................…........Intro Configuration as Code Test your codeThe next level
<project>
<triggers>
<hudson.triggers.TimerTrigger>
<spec>H * * * *</spec>
</hudson.triggers.TimerTrigger>
</triggers>
</project>
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
// is any trigger set?
triggers
// is trigger a timer trigger?
triggers.'hudson.triggers.TimerTrigger'
// trigger is NOT an scm trigger?
!triggers.'hudson.triggers.SCMTrigger'
// has trigger a specific value?
triggers.text().equals('H * * * *')
// has timer trigger a specific value?
triggers.'hudson.triggers.TimerTrigger'.text().equals('H * * * *')
........................…........Intro Configuration as Code Test your codeThe next level
<project>
<triggers>
<hudson.triggers.TimerTrigger>
<spec>H * * * *</spec>
</hudson.triggers.TimerTrigger>
</triggers>
</project>
What can be tested?
An example on how to introduce Job DSL in a real life company
def 'this one has a timer trigger set, but no scm trigger'() {
setup:
Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) }
expect:
with(job.node) {
// is any trigger set?
triggers
// is trigger a timer trigger?
triggers.'hudson.triggers.TimerTrigger'
// trigger is NOT an scm trigger?
!triggers.'hudson.triggers.SCMTrigger'
// has trigger a specific value?
triggers.text().equals('H * * * *')
// has timer trigger a specific value?
triggers.'hudson.triggers.TimerTrigger'.text().equals('H * * * *')
// trigger has a tag with value timer trigger
triggers.get(0).value().get(0).name().equals('hudson.triggers.TimerTrigger')
}
}
........................…........Intro Configuration as Code Test your codeThe next level
<project>
<triggers>
<hudson.triggers.TimerTrigger>
<spec>H * * * *</spec>
</hudson.triggers.TimerTrigger>
</triggers>
</project>
Write tests for all job configurations
An example on how to introduce Job DSL in a real life company
def setupSpec() {
jobManagement = new MemoryJobManagement()
List<ScriptRequest> scriptRequests = []
ResourceHelper.getAllJobDslFiles().each { File script ->
URL scriptURL = new File(script.getPath()).toURI().toURL()
scriptRequests.add(new ScriptRequest(script.name, null, scriptURL))
}
new DslScriptLoader(jobManagement).runScripts(scriptRequests)
}
........................…........Intro Configuration as Code Test your codeThe next level
Write tests for all job configurations
An example on how to introduce Job DSL in a real life company
def setupSpec() {
jobManagement = new MemoryJobManagement()
List<ScriptRequest> scriptRequests = []
ResourceHelper.getAllJobDslFiles().each { File script ->
URL scriptURL = new File(script.getPath()).toURI().toURL()
scriptRequests.add(new ScriptRequest(script.name, null, scriptURL))
}
new DslScriptLoader(jobManagement).runScripts(scriptRequests)
}
@Unroll
def 'Always activate log rotation for "#config.key"'(Map.Entry<String, String> config) {
expect:
with(new XmlParser().parse(new StringReader(config.value))) {
!logRotator.text().isEmpty()
}
where:
script << jobManagement.savedConfigs
}
........................…........Intro Configuration as Code Test your codeThe next level
Overall Testing: Enforce scripting standards
@Unroll
def 'Turn off debug output for shell steps in "#config.key"'(Map.Entry<String, String> config) {
expect:
with(new XmlParser().parse(new StringReader(config.value))) {
}
where:
script << jobManagement.savedConfigs
}
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
Overall Testing: Enforce scripting standards
@Unroll
def 'Turn off debug output for shell steps in "#config.key"'(Map.Entry<String, String> config) {
expect:
with(new XmlParser().parse(new StringReader(config.value))) {
def scriptCommands = builders.get(0).children().findAll { buildStep ->
buildStep.name().equals('hudson.tasks.Shell')
}.collect { shellStep ->
shellStep.get('command').text()
}
}
where:
script << jobManagement.savedConfigs
}
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
Overall Testing: Enforce scripting standards
@Unroll
def 'Turn off debug output for shell steps in "#config.key"'(Map.Entry<String, String> config) {
expect:
with(new XmlParser().parse(new StringReader(config.value))) {
def scriptCommands = builders.get(0).children().findAll { buildStep ->
buildStep.name().equals('hudson.tasks.Shell')
}.collect { shellStep ->
shellStep.get('command').text()
}
// make sure every script has debug disabled by default
scriptCommands.findAll {
!it.startsWith('#!/bin/sh -en')
}.findAll {
!it.startsWith('@echo offn')
}.isEmpty()
}
where:
script << jobManagement.savedConfigs
}
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
Functional tests
def 'test functional stuff for your job builders'() {
when:
Job job = new JobBuilder(jobParent, 'foo').make {
parameters {
StringParam('IMPORTANT_PARAMETER', 'wrong!')
}
}
then:
thrown IllegalStateException('wrong parameter used!')
}
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
Some examples for the impact in the actual teams
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
Some examples for the impact in the actual teams
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
• Web development: Huge release process with a bunch of manual branches
-> Now it's a one-klick release
Some examples for the impact in the actual teams
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
• Web development: Huge release process with a bunch of manual branches
-> Now it's a one-klick release
• Business Intelligence: Hardly any automated processes via Jenkins
-> Now they automated everything
Some examples for the impact in the actual teams
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
• Web development: Huge release process with a bunch of manual branches
-> Now it's a one-klick release
• Business Intelligence: Hardly any automated processes via Jenkins
-> Now they automated everything
• Core development: Huge deploy job blob that no one understood
-> One-klick deploy jobs for every environment (350+ jobs)
Some examples for the impact in the actual teams
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
• Web development: Huge release process with a bunch of manual branches
-> Now it's a one-klick release
• Business Intelligence: Hardly any automated processes via Jenkins
-> Now they automated everything
• Core development: Huge deploy job blob that no one understood
-> One-klick deploy jobs for every environment (350+ jobs)
Teams can work
autonomously
Benefits
• Refactor jobs without fear due to regression testing and debug output
• Reduced configuration mistakes due to functional testing
• No conflicts between distributed teams
• Easy change rollout
• Minimal configuration
• Maximal convention
An example on how to introduce Job DSL in a real life company
.........................….......Intro Configuration as Code Test your codeThe next level
THANK YOU!
PAYBACK GmbH
Christian rasp
Software Developer DevOps
Theresienhöhe 12
80339 München
Phone +49 (0) 89 997 41 – 1637
christian.rasp@PAYBACK.net
PAYBACK.net | PAYBACK.de

More Related Content

PDF
The Job DSL Plugin: Introduction & What’s New
PPTX
Configuration As Code: The Job DSL Plugin
PDF
Managing Jenkins with Python
PPTX
Job DSL Plugin for Jenkins
PPTX
Jenkins Job DSL plugin
PDF
Configuration As Code - Adoption of the Job DSL Plugin at Netflix
PPTX
Continuous integration of_puppet_code
PDF
JUC Europe 2015: Configuration as Code: The Job DSL Plugin
The Job DSL Plugin: Introduction & What’s New
Configuration As Code: The Job DSL Plugin
Managing Jenkins with Python
Job DSL Plugin for Jenkins
Jenkins Job DSL plugin
Configuration As Code - Adoption of the Job DSL Plugin at Netflix
Continuous integration of_puppet_code
JUC Europe 2015: Configuration as Code: The Job DSL Plugin

What's hot (18)

PPTX
Puppetcamp r10kyaml
PDF
Stackato v6
PDF
Writing less code with Serverless on AWS at FrOSCon 2021
PDF
How adding a further tool can be a good thing
PDF
Pietro Di Bello, Paolo D'Incau - Continuous Delivery su progetti Java: cosa a...
ZIP
Drupal Deployment
PDF
2021 04-15 operational verification (with notes)
PPTX
vBrownBag DevOps Series: Puppetinabox
PDF
Perl-Critic
PPT
Infrastructure Automation at Scale
PDF
Implementing your own Google App Engine
PDF
Jenkins Workflow Webinar - Dec 10, 2014
PPTX
Jenkins talk at Silicon valley DevOps meetup
PDF
Build your application in seconds and optimize workflow as much as you can us...
ODP
Node.js architecture (EN)
PPTX
Docs as Part of the Product - Open Source Summit North America 2018
PDF
Learn How Selenium And Jenkins Fit In DevOps | Edureka Live
PPTX
Big datatraining.in devops-part1
Puppetcamp r10kyaml
Stackato v6
Writing less code with Serverless on AWS at FrOSCon 2021
How adding a further tool can be a good thing
Pietro Di Bello, Paolo D'Incau - Continuous Delivery su progetti Java: cosa a...
Drupal Deployment
2021 04-15 operational verification (with notes)
vBrownBag DevOps Series: Puppetinabox
Perl-Critic
Infrastructure Automation at Scale
Implementing your own Google App Engine
Jenkins Workflow Webinar - Dec 10, 2014
Jenkins talk at Silicon valley DevOps meetup
Build your application in seconds and optimize workflow as much as you can us...
Node.js architecture (EN)
Docs as Part of the Product - Open Source Summit North America 2018
Learn How Selenium And Jenkins Fit In DevOps | Edureka Live
Big datatraining.in devops-part1
Ad

Viewers also liked (7)

PDF
Build automation best practices
PPTX
Build Automation in Android
PDF
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
PPTX
XPages build automation and testing
PPTX
Continuous Integration & Package Management 101
PPTX
Abdominal wall closure
PPT
Management of the burst abdomen.ppt
Build automation best practices
Build Automation in Android
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
XPages build automation and testing
Continuous Integration & Package Management 101
Abdominal wall closure
Management of the burst abdomen.ppt
Ad

Similar to Rule jenkins with configuration as code (19)

PDF
Getting out of the Job Jungle with Jenkins
PDF
Brujug Jenkins pipeline scalability
PPTX
Configuration as Code: The Job DSL Plugin
PPT
Learn jobDSL for Jenkins
PDF
CICD Pipeline configuration as a code
PDF
Take control of your Jenkins jobs via job DSL.
PDF
Belgium jenkins-meetup-job-jungle-0.1
PDF
Jenkins JobDSL - Configuration as code
PPTX
Gluecon 2018 JaC
PPTX
Jenkins as a Service - Code all the way down
PDF
DSL Construction with Ruby - ThoughtWorks Masterclass Series 2009
PDF
Codifying the Build and Release Process with a Jenkins Pipeline Shared Library
PPTX
Bdd and dsl как способ построения коммуникации на проекте
PPTX
BDD or DSL как способ построения коммуникации на проекте - опыт комплексного ...
PDF
Cultivating the jenkins job jungle with groovy - Patrick van Dissel
PPT
PDF
ModelTalk - When Everything is a Domain Specific Language
PDF
PuppetConf 2016: Continuous Delivery and DevOps with Jenkins and Puppet Enter...
PPTX
Greg Maxey - Electric Cloud - Process as Code: An Introduction to the Electri...
Getting out of the Job Jungle with Jenkins
Brujug Jenkins pipeline scalability
Configuration as Code: The Job DSL Plugin
Learn jobDSL for Jenkins
CICD Pipeline configuration as a code
Take control of your Jenkins jobs via job DSL.
Belgium jenkins-meetup-job-jungle-0.1
Jenkins JobDSL - Configuration as code
Gluecon 2018 JaC
Jenkins as a Service - Code all the way down
DSL Construction with Ruby - ThoughtWorks Masterclass Series 2009
Codifying the Build and Release Process with a Jenkins Pipeline Shared Library
Bdd and dsl как способ построения коммуникации на проекте
BDD or DSL как способ построения коммуникации на проекте - опыт комплексного ...
Cultivating the jenkins job jungle with groovy - Patrick van Dissel
ModelTalk - When Everything is a Domain Specific Language
PuppetConf 2016: Continuous Delivery and DevOps with Jenkins and Puppet Enter...
Greg Maxey - Electric Cloud - Process as Code: An Introduction to the Electri...

Recently uploaded (20)

PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PPTX
Transform Your Business with a Software ERP System
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
medical staffing services at VALiNTRY
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Nekopoi APK 2025 free lastest update
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
history of c programming in notes for students .pptx
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
System and Network Administration Chapter 2
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Softaken Excel to vCard Converter Software.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
How to Migrate SBCGlobal Email to Yahoo Easily
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Transform Your Business with a Software ERP System
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
medical staffing services at VALiNTRY
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Reimagine Home Health with the Power of Agentic AI​
Nekopoi APK 2025 free lastest update
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
history of c programming in notes for students .pptx
Upgrade and Innovation Strategies for SAP ERP Customers
Adobe Illustrator 28.6 Crack My Vision of Vector Design
System and Network Administration Chapter 2
Operating system designcfffgfgggggggvggggggggg
Softaken Excel to vCard Converter Software.pdf

Rule jenkins with configuration as code

  • 1. An example on how to introduce the Job DSL Plugin in a real life company Rule Jenkins with Configuration as Code Jenkins World, 14.09.2016
  • 2. ….…............................ An example on how to introduce Job DSL in a real life company What this talk is about • Configuration as code with the Job DSL Plugin • How to take it to the next level • Pitfalls and how to make them foolproof Intro Configuration as Code Test your codeThe next level
  • 3. An example on how to introduce Job DSL in a real life company What this talk is not about • Job DSL in detail – please refer to: Adoption of the Job DSL Plugin at Netflix by Justin Ryan Configuration as Code: The Job DSL Plugin by Daniel Spilker at JUC Europe 2015 Jenkins + Groovy with the Job DSL Plugin by Matt Sheehan at GR8Conf US 2015 ….…............................Intro Configuration as Code Test your codeThe next level
  • 4. Christian Rasp / christian.rasp@PAYBACK.net / @crasp An example on how to introduce Job DSL in a real life company • Software Developer DevOps • Jenkins & Nexus Admin • Build Engineer for CI & CD ….…............................Intro Configuration as Code Test your codeThe next level
  • 5. PAYBACK is continuously expanding into new countries An example on how to introduce Job DSL in a real life company 2000 2009 2014 2010 2012 2015 ….…............................Intro Configuration as Code Test your codeThe next level
  • 6. PAYBACK – Biggest loyalty program and largest multichannel marketing platform An example on how to introduce Job DSL in a real life company In 2015, 20 bn coupons were distributed to customers in Germany Points to the value of € 338 m were collected in 2015 95% of all PAYBACK points get redeemed! 8 out of 10 Germans are familiar with the PAYBACK brand Sales of more than € 27 bn are generated with PAYBACK cards at partner stores (2015) The PAYBACK card is the third most important card in German wallets (after debit cards and credit cards, TNS Emnid survey, 2014) ….…............................Intro Configuration as Code Test your codeThe next level
  • 7. An example on how to introduce Job DSL in a real life company In May 2015 PAYBACK was launched in the US under the name "Plenti" ….…............................Intro Configuration as Code Test your codeThe next level
  • 8. ….…............................ An example on how to introduce Job DSL in a real life company Intro Configuration as Code Test your codeThe next level Configuration as code with the Job DSL Plugin
  • 9. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: The initial problem
  • 10. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: • What is this job doing? The initial problem
  • 11. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: • What is this job doing? • Is the job still in use? The initial problem
  • 12. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: • What is this job doing? • Is the job still in use? • Who is responsible for this job? The initial problem
  • 13. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? The initial problem
  • 14. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? The initial problem
  • 15. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? The initial problem
  • 16. An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level All Jenkins job configuration is setup manually: • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for a group of jobs? The initial problem
  • 17. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 18. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • Script console
  • 19. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • Script console • Templates
  • 20. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • Script console • Templates • Job generator Plugin
  • 21. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • Script console • Templates • Job generator Plugin • REST API or CLI
  • 22. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • Script console • Templates • Job generator Plugin • REST API or CLI • Pipeline Plugin
  • 23. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • Script console • Templates • Job generator Plugin • REST API or CLI • Pipeline Plugin • Job DSL Plugin
  • 24. Possible solutions An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • Script console • Templates • Job generator Plugin • REST API or CLI • Pipeline Plugin • Job DSL Plugin
  • 25. Describe jobs using a Groovy-based language An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 26. Describe jobs using a Groovy-based language An example on how to introduce Job DSL in a real life company mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') logRotator(-1, 30) jdk('jdk-1.8.0_45') wrappers { mavenRelease { releaseGoals('-Dresume=false release:prepare release:perform') dryRunGoals('-Dresume=false -DdryRun=true release:prepare') numberOfReleaseBuildsToKeep(2) selectScmCredentials(true) } } goals('clean install --batch-mode --update-snapshots') mavenInstallation('maven-3.2.2') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") { checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] ….…............................Intro Configuration as Code Test your codeThe next level
  • 27. Describe jobs using a Groovy-based language An example on how to introduce Job DSL in a real life company mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') logRotator(-1, 30) jdk('jdk-1.8.0_45') wrappers { mavenRelease { releaseGoals('-Dresume=false release:prepare release:perform') dryRunGoals('-Dresume=false -DdryRun=true release:prepare') numberOfReleaseBuildsToKeep(2) selectScmCredentials(true) } } goals('clean install --batch-mode --update-snapshots') mavenInstallation('maven-3.2.2') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") { checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] ….…............................Intro Configuration as Code Test your codeThe next level
  • 28. It still does not fit our needs An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for subset of jobs?
  • 29. It still does not fit our needs An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for subset of jobs?
  • 30. It still does not fit our needs An example on how to introduce Job DSL in a real life company • New scripting language • New DSL reference to learn ….…............................Intro Configuration as Code Test your codeThe next level • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for subset of jobs?
  • 31. An example on how to introduce Job DSL in a real life company How to take it to the next level ….…............................Intro Configuration as Code Test your codeThe next level
  • 32. Make a developers life as easy as possible An example on how to introduce Job DSL in a real life company Things a Jenkins user should not need to know about: ….…............................Intro Configuration as Code Test your codeThe next level
  • 33. Make a developers life as easy as possible An example on how to introduce Job DSL in a real life company • Standard log rotation Things a Jenkins user should not need to know about: ….…............................Intro Configuration as Code Test your codeThe next level
  • 34. Make a developers life as easy as possible An example on how to introduce Job DSL in a real life company • Standard log rotation • Configuration pitfalls Things a Jenkins user should not need to know about: ….…............................Intro Configuration as Code Test your codeThe next level
  • 35. Make a developers life as easy as possible An example on how to introduce Job DSL in a real life company • Standard log rotation • Configuration pitfalls • Credentials for tech. users Things a Jenkins user should not need to know about: ….…............................Intro Configuration as Code Test your codeThe next level
  • 36. Make a developers life as easy as possible An example on how to introduce Job DSL in a real life company • Standard log rotation • Configuration pitfalls • Credentials for tech. users • Naming conventions Things a Jenkins user should not need to know about: ….…............................Intro Configuration as Code Test your codeThe next level
  • 37. Make a developers life as easy as possible An example on how to introduce Job DSL in a real life company • Standard log rotation • Configuration pitfalls • Credentials for tech. users • Naming conventions • Jenkins Maven magic Things a Jenkins user should not need to know about: ….…............................Intro Configuration as Code Test your codeThe next level
  • 38. Make a developers life as easy as possible An example on how to introduce Job DSL in a real life company • Standard log rotation • Configuration pitfalls • Credentials for tech. users • Naming conventions • Jenkins Maven magic • Default settings Things a Jenkins user should not need to know about: ….…............................Intro Configuration as Code Test your codeThe next level
  • 39. So what IS the next level? An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 40. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 41. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance • Standards ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 42. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance • Standards • Convention ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 43. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance • Standards • Convention • Clean project structure ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 44. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance • Standards • Convention • Clean project structure • Dependency management ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 45. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance • Standards • Convention • Clean project structure • Dependency management • Reviews ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 46. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance • Standards • Convention • Clean project structure • Dependency management • Reviews • Tests! ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 47. So what IS the next level? An example on how to introduce Job DSL in a real life company • Inheritance • Standards • Convention • Clean project structure • Dependency management • Reviews • Tests! • More tests! ….…............................Intro Configuration as Code Test your codeThe next level Build your own tool with standard software engineering approaches:
  • 48. mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') logRotator(-1, 30) jdk('jdk-1.8.0_45') wrappers { mavenRelease { releaseGoals('-Dresume=false release:prepare release:perform') dryRunGoals('-Dresume=false -DdryRun=true release:prepare') numberOfReleaseBuildsToKeep(2) selectScmCredentials(true) } } goals('clean install --batch-mode --update-snapshots') mavenInstallation('maven-3.2.2') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] Reduce the configuration to a bare minimum An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 49. mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') jdk('jdk-1.8.0_45') wrappers { mavenRelease { releaseGoals('-Dresume=false release:prepare release:perform') dryRunGoals('-Dresume=false -DdryRun=true release:prepare') numberOfReleaseBuildsToKeep(2) selectScmCredentials(true) } } goals('clean install --batch-mode --update-snapshots') mavenInstallation('maven-3.2.2') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] Reduce the configuration to a bare minimum An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 50. mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') wrappers { mavenRelease { releaseGoals('-Dresume=false release:prepare release:perform') dryRunGoals('-Dresume=false -DdryRun=true release:prepare') numberOfReleaseBuildsToKeep(2) selectScmCredentials(true) } } goals('clean install --batch-mode --update-snapshots') mavenInstallation('maven-3.2.2') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] Reduce the configuration to a bare minimum An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 51. mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') goals('clean install --batch-mode --update-snapshots') mavenInstallation('maven-3.2.2') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] Reduce the configuration to a bare minimum An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 52. mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') mavenInstallation('maven-3.2.2') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] Reduce the configuration to a bare minimum An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 53. mavenJob('HAL9000') { description('I'm sorry Dave, I'm afraid I can't do that') scm { svn { location("${Repositories.DISCOVERY.url()}/dave/trunk") checkoutStrategy(SvnCheckoutStrategy.UPDATE_WITH_REVERT) } } [...] Reduce the configuration to a bare minimum An example on how to introduce Job DSL in a real life company ….…............................Intro Configuration as Code Test your codeThe next level
  • 54. Reduce the configuration to a bare minimum An example on how to introduce Job DSL in a real life company new MavenJobBuilder(this, 'HAL9000').make { description("I'm sorry Dave, I'm afraid I can't do that") svn(Repositories.DISCOVERY, '/trunk') } ….…............................Intro Configuration as Code Test your codeThe next level
  • 55. Use builder pattern to create simple job builders An example on how to introduce Job DSL in a real life company http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html Groovy Goodness from the Blog of MrHaki ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 56. Use builder pattern to create simple job builders An example on how to introduce Job DSL in a real life company // Build your own closures to expand Job DSL private runClosure(Closure runClosure) { // Create clone of closure for threading access. Closure runClone = runClosure.clone() // Set delegate of closure to this builder. runClone.delegate = this // And only use this builder as the closure delegate. runClone.resolveStrategy = Closure.DELEGATE_ONLY // Run closure code. runClone() } http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html Groovy Goodness from the Blog of MrHaki ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 57. Use builder pattern to create simple job builders An example on how to introduce Job DSL in a real life company // Build your own closures to expand Job DSL private runClosure(Closure runClosure) { // Create clone of closure for threading access. Closure runClone = runClosure.clone() // Set delegate of closure to this builder. runClone.delegate = this // And only use this builder as the closure delegate. runClone.resolveStrategy = Closure.DELEGATE_ONLY // Run closure code. runClone() } http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html Groovy Goodness from the Blog of MrHaki ….…..................….......Intro Configuration as Code Test your codeThe next level // Delegate everything else to Job DSL def methodMissing(String name, argument) { job.invokeMethod(name, (Object[]) argument) }
  • 58. Use builder pattern to create simple job builders An example on how to introduce Job DSL in a real life company http://mrhaki.blogspot.de/2011/11/groovy-goodness-create-simple-builders.html Groovy Goodness from the Blog of MrHaki ….…..................….......Intro Configuration as Code Test your codeThe next level new JobBuilder(this, 'adjust-permissions').make { // Own function via runClosure restrictPermissions('ernie', 'bert', 'jenkins-admins') // Original Job DSL syntax via methodMissing steps { shell('ls -l') } }
  • 59. Set some standards automatically public class JobBuilder extends Builder { protected Job job // Create a new job object JobBuilder(DslFactory dslFactory, String jobName) { this.job = dslFactory.job(jobName) } } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 60. Set some standards automatically public class JobBuilder extends Builder { protected Job job // Create a new job object JobBuilder(DslFactory dslFactory, String jobName) { this.job = dslFactory.job(jobName) } // Defines initial state for a job Job make(Closure additionalConfig) { // Standards for all jobs job.logRotator job.jdk job.label // every other configurations runClosure additionalConfig job } } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 61. Set some standards automatically // Defines initial state for a job Job make(Closure additionalConfig) { // Standards for all jobs job.logRotator job.jdk job.label // every other configurations runClosure additionalConfig job } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level mavenJob('HAL9000') { [...] logRotator(-1, 30) jdk('jdk-1.8.0_45') [...] }
  • 62. Set some standards automatically // Defines initial state for a job Job make(Closure additionalConfig) { // Standards for all jobs job.logRotator job.jdk job.label // every other configurations runClosure additionalConfig job } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level mavenJob('HAL9000') { [...] logRotator(-1, 30) jdk('jdk-1.8.0_45') [...] }
  • 63. Set some standards automatically // Defines initial state for a job Job make(Closure additionalConfig) { // Standards for all jobs job.logRotator job.jdk job.label // every other configurations runClosure additionalConfig job } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level mavenJob('HAL9000') { [...] logRotator(-1, 30) jdk('jdk-1.8.0_45') [...] } What are the standard settings?
  • 64. Hide complex configuration settings An example on how to introduce Job DSL in a real life company class MavenJobBuilder extends JobBuilder { MavenJobBuilder(DslFactory dslFactory, String jobName) { super(dslFactory.mavenJob(jobName)) } MavenJob make(Closure additionalConfig) { job.wrappers { mavenRelease { releaseGoals numberOfReleaseBuildsToKeep } } job.goals job.mavenInstallation [...] super.make(additionalConfig) job as MavenJob } } ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 65. Hide complex configuration settings An example on how to introduce Job DSL in a real life company job.wrappers { mavenRelease { releaseGoals numberOfReleaseBuildsToKeep } } job.goals job.mavenInstallation ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 66. Hide complex configuration settings An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level new MavenJobBuilder(this, 'YourEasyMavenJobHere').make { [...] }
  • 67. Encapsulate common DSL patterns void svn(Repositories repository, String loc, String dir = '.', SvnCheckoutStrategy strategy = SvnCheckoutStrategy.UPDATE_WITH_REVERT) { An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 68. Encapsulate common DSL patterns void svn(Repositories repository, String loc, String dir = '.', SvnCheckoutStrategy strategy = SvnCheckoutStrategy.UPDATE_WITH_REVERT) { job.scm { svn { location("${repository.url()}${loc}") { credentials(repository.credential()) directory(dir) } checkoutStrategy(strategy) } } } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 69. Encapsulate common DSL patterns svn(Repositories.FOO, '/UTIL/trunk') An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 70. Encapsulate common DSL patterns svn(Repositories.FOO, '/UTIL/trunk') An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 71. Encapsulate common DSL patterns svn(Repositories.FOO, '/UTIL/trunk') An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level Why is it configured that way?
  • 72. Encapsulate common DSL patterns void cron(Cron c) { job.triggers { cron(c.getTab()) } } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 73. Encapsulate common DSL patterns void cron(Cron c) { job.triggers { cron(c.getTab()) } } enum Cron { FIVE_MINUTES( 'H/5 * * * *', 'Once in five minutes'), FIFTEEN_MINUTES( 'H/15 * * * *', 'Once in fifteen minutes'), THIRTY_MINUTES( 'H/30 * * * *', 'Once every thirty minutes'), HOURLY( 'H * * * *', 'Once an hour'), WEEKDAY_TWO_HOURLY('H 8-18/2 * * 1-5', 'Once every two hours every weekday'), MIDNIGHT( 'H H(0-2) * * *', 'Once right after midnight'), DAILY( 'H H * * *', 'Once a day'), WEEKLY( 'H H * * H', 'Once a week'), MONTHLY( 'H H H * *', 'Once a month') } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 74. Encapsulate common DSL patterns cron(Cron.FIFTEEN_MINUTES) An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 75. Easy-to-read configurations new JobBuilder(this, 'run-script').make { steps { shell('''ssh $KEY_FILE $USER@FOO <<'END' java -jar cli.jar PROJECTIMPORT -host localhost -port 12345 -HTTP -user "${USER}" -password "${PASSWORD}" -project "${PROJECT_NAME}" -projectFile "${PROJECT_FILE}" -dbuser '"$(grep "content.jdbc.USER" database.conf | cut -d "=" -f2-)"' -dbpassword '"$(grep "content.jdbc.PASSWORD" database.conf | cut -d "=" -f2-)"' -dburl '"$(grep "content.jdbc.URL" database.conf | cut -d "=" -f2-)"' -dbschema '"$(grep "content.jdbc.SCHEMA" database.conf | cut -d "=" -f2-)"' END''') } } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 76. Easy-to-read configurations new JobBuilder(this, 'run-script').make { An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level def scriptfile = readFileFromWorkspace('src/main/resources/bin/scriptfile.sh') steps { shell(scriptfile) } }
  • 77. Easy-to-read configurations An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 78. Easy-to-read configurations new MavenJobBuilder(this, 'build-new-deathstar').make { svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball') cronScm(Cron.EVERY_MOVIE) sendMail('darth.vader@empire.dark.net') sendMail('sheev.palpatine@empire.dark.net') } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 79. Easy-to-read configurations new MavenJobBuilder(this, 'build-new-deathstar').make { svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball') cronScm(Cron.EVERY_MOVIE) sendMail('darth.vader@empire.dark.net') sendMail('sheev.palpatine@empire.dark.net') } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level new MavenJobBuilder(this, 'build-super-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.WEEKLY) expandMavenGoals('--activate-profiles super') }
  • 80. Easy-to-read configurations new MavenJobBuilder(this, 'build-new-deathstar').make { svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball') cronScm(Cron.EVERY_MOVIE) sendMail('darth.vader@empire.dark.net') sendMail('sheev.palpatine@empire.dark.net') } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level new MavenJobBuilder(this, 'build-super-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.WEEKLY) expandMavenGoals('--activate-profiles super') } new MavenJobBuilder(this, 'build-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.DAILY) reportEmpireAcceptanceTests() }
  • 81. Easy-to-read configurations new MavenJobBuilder(this, 'build-new-deathstar').make { svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball') cronScm(Cron.EVERY_MOVIE) sendMail('darth.vader@empire.dark.net') sendMail('sheev.palpatine@empire.dark.net') } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level new MavenJobBuilder(this, 'build-super-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.WEEKLY) expandMavenGoals('--activate-profiles super') } new MavenJobBuilder(this, 'build-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.DAILY) reportEmpireAcceptanceTests() } Who is responsible for this job?
  • 82. Easy-to-read configurations new MavenJobBuilder(this, 'build-new-deathstar').make { svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball') cronScm(Cron.EVERY_MOVIE) sendMail('darth.vader@empire.dark.net') sendMail('sheev.palpatine@empire.dark.net') } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level new MavenJobBuilder(this, 'build-super-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.WEEKLY) expandMavenGoals('--activate-profiles super') } new MavenJobBuilder(this, 'build-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.DAILY) reportEmpireAcceptanceTests() } Who is responsible for this job? What is this job doing?
  • 83. Easy-to-read configurations new MavenJobBuilder(this, 'build-new-deathstar').make { svn(Repositories.DARKEMPIRE, '/spaceships/deathstar/shapes/ball') cronScm(Cron.EVERY_MOVIE) sendMail('darth.vader@empire.dark.net') sendMail('sheev.palpatine@empire.dark.net') } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level new MavenJobBuilder(this, 'build-super-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.WEEKLY) expandMavenGoals('--activate-profiles super') } new MavenJobBuilder(this, 'build-star-destroyers').make { svn(Repositories.DARKEMPIRE, '/spaceships/destroyers') cronScm(Cron.DAILY) reportEmpireAcceptanceTests() } How to change settings for a group of jobs? Who is responsible for this job? What is this job doing?
  • 84. Easy-to-read configurations DevEnvironment.values().each { environment -> new DeployJobBuilder(this, 'Deploy-${environment.getEnvName()}').make { } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 85. Easy-to-read configurations DevEnvironment.values().each { environment -> new DeployJobBuilder(this, 'Deploy-${environment.getEnvName()}').make { job.environmentVariables { env('ENVIRONMENT_NAME', environment.getEnvName()) env('BRANCH', environment.getBranch()) env('TEST_DATA', environment.getTestData()) if (DevEnvironment.UAT.equals(environment)) { env('UAT', true) } [...] } } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 86. Easy-to-read configurations DevEnvironment.values().each { environment -> new DeployJobBuilder(this, 'Deploy-${environment.getEnvName()}').make { job.environmentVariables { env('ENVIRONMENT_NAME', environment.getEnvName()) env('BRANCH', environment.getBranch()) env('TEST_DATA', environment.getTestData()) if (DevEnvironment.UAT.equals(environment)) { env('UAT', true) } [...] } } An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level enum DevEnvironment { STAGE1('system-integration', Branch.SIT, '#customer'), STAGE2('performance', Branch.PRF, '#customer'), UAT( 'external-test', Branch.ET, '#customer#partner'), PROD( 'production', Branch.MASTER, '#full') }
  • 87. Project structure . ├── pom.xml # build file An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 88. Project structure . ├── pom.xml # build file ├── src │ ├── main │ │ ├── groovy # job builder and support classes An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 89. Project structure . ├── pom.xml # build file ├── src │ ├── main │ │ ├── groovy # job builder and support classes │ │ └── resources │ │ ├── bin # common scripts (shell, batch, groovy etc.) │ │ ├── jobs # DSL script files for jobs │ │ └── views # DSL script files for views An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 90. Project structure . ├── pom.xml # build file ├── src │ ├── main │ │ ├── groovy # job builder and support classes │ │ └── resources │ │ ├── bin # common scripts (shell, batch, groovy etc.) │ │ ├── jobs # DSL script files for jobs │ │ └── views # DSL script files for views │ └── test │ ├── groovy # specs for the job builders and their functionality │ └── resources # script files for tests An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 91. Project structure . ├── pom.xml # build file ├── src │ ├── main │ │ ├── groovy # job builder and support classes │ │ └── resources │ │ ├── bin # common scripts (shell, batch, groovy etc.) │ │ ├── jobs # DSL script files for jobs │ │ └── views # DSL script files for views │ └── test │ ├── groovy # specs for the job builders and their functionality │ └── resources # script files for tests └── target └── debug-xml # output directory for all generated items during test ├── jobs # Useful to diff job changes └── views An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 92. Project dependencies An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level <dependency> <groupId>net.payback.ci</groupId> <artifactId>dslbuilder</artifactId> <version>${dslbuilder.version}</version> </dependency> <modules> <module>dev-bi</module> <module>dev-core</module> <module>dev-performance</module> <module>dev-portal</module> […] <module>dev-vagrant</module> </modules>
  • 93. Project dependencies Main project with common builders, functions and tests. Has its own release cycle. An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level <dependency> <groupId>net.payback.ci</groupId> <artifactId>dslbuilder</artifactId> <version>${dslbuilder.version}</version> </dependency> <modules> <module>dev-bi</module> <module>dev-core</module> <module>dev-performance</module> <module>dev-portal</module> […] <module>dev-vagrant</module> </modules>
  • 94. Project dependencies Main project with common builders, functions and tests. Has its own release cycle. Own modules for every team, department or the same area of responsibility An example on how to introduce Job DSL in a real life company ….…..................….......Intro Configuration as Code Test your codeThe next level <dependency> <groupId>net.payback.ci</groupId> <artifactId>dslbuilder</artifactId> <version>${dslbuilder.version}</version> </dependency> <modules> <module>dev-bi</module> <module>dev-core</module> <module>dev-performance</module> <module>dev-portal</module> […] <module>dev-vagrant</module> </modules>
  • 95. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 96. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? ….…..................….......Intro Configuration as Code Test your codeThe next level
  • 97. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read
  • 98. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read
  • 99. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits
  • 100. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits
  • 101. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules
  • 102. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules
  • 103. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff
  • 104. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff
  • 105. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders
  • 106. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders
  • 107. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders Get all the benefits from VCS
  • 108. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for a group of jobs? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders Get all the benefits from VCS
  • 109. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for a group of jobs? ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders Get all the benefits from VCS Refactor or search and replace
  • 110. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for a group of jobs? • New scripting language ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders Get all the benefits from VCS Refactor or search and replace
  • 111. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for a group of jobs? • New scripting language ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders Get all the benefits from VCS Refactor or search and replace Simplified with custom builders
  • 112. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for a group of jobs? • New scripting language • New DSL reference to learn ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders Get all the benefits from VCS Refactor or search and replace Simplified with custom builders
  • 113. Resolve ALL the issues An example on how to introduce Job DSL in a real life company http://knowyourmeme.com/memes/x-all-the-y • What is this job doing? • Is the job still in use? • Who is responsible for this job? • Why is it configured that way? • What are the standard settings? • Who changed what and when? • How to change settings for a group of jobs? • New scripting language • New DSL reference to learn ….…..................….......Intro Configuration as Code Test your codeThe next level Minimum config, easy to read Look at the commits Everyone can read it, own modules Simple methods for complex stuff Set basics in job builders Get all the benefits from VCS Refactor or search and replace Simplified with custom builders Outstanding API viewer ;)
  • 114. An example on how to introduce Job DSL in a real life company How to make it foolproof .........................….......Intro Configuration as Code Test your codeThe next level
  • 115. How to make it foolproof An example on how to introduce Job DSL in a real life company People will do the same thing in the code, as they did before via the UI .........................….......Intro Configuration as Code Test your codeThe next level
  • 116. How to make it foolproof • Copy & Paste of job builders An example on how to introduce Job DSL in a real life company People will do the same thing in the code, as they did before via the UI .........................….......Intro Configuration as Code Test your codeThe next level
  • 117. How to make it foolproof • Copy & Paste of job builders • Write jobs in pure dsl syntax, but forget about standards An example on how to introduce Job DSL in a real life company People will do the same thing in the code, as they did before via the UI .........................….......Intro Configuration as Code Test your codeThe next level
  • 118. How to make it foolproof • Copy & Paste of job builders • Write jobs in pure dsl syntax, but forget about standards • Use anti-patterns in code, configuration will be unreadable again An example on how to introduce Job DSL in a real life company People will do the same thing in the code, as they did before via the UI .........................….......Intro Configuration as Code Test your codeThe next level
  • 119. How to make it foolproof • Copy & Paste of job builders • Write jobs in pure dsl syntax, but forget about standards • Use anti-patterns in code, configuration will be unreadable again An example on how to introduce Job DSL in a real life company People will do the same thing in the code, as they did before via the UI .........................….......Intro Configuration as Code Test your codeThe next level WRITE TESTS
  • 120. How to make it foolproof An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level
  • 121. Test Example from https://github.com/sheehan/job-dsl-gradle-example An example on how to introduce Job DSL in a real life company class JobScriptsSpec extends Specification { @Unroll void 'test script #file.name'(File file) { given: when: then: where: [...] } ...................................Intro Configuration as Code Test your codeThe next level
  • 122. Test Example from https://github.com/sheehan/job-dsl-gradle-example An example on how to introduce Job DSL in a real life company class JobScriptsSpec extends Specification { @Unroll void 'test script #file.name'(File file) { given: JobManagement jm = Spy(MemoryJobManagement) [...] when: then: where: [...] } ...................................Intro Configuration as Code Test your codeThe next level
  • 123. Test Example from https://github.com/sheehan/job-dsl-gradle-example An example on how to introduce Job DSL in a real life company class JobScriptsSpec extends Specification { @Unroll void 'test script #file.name'(File file) { given: JobManagement jm = Spy(MemoryJobManagement) [...] when: DslScriptLoader(jm).runScript(file.text) then: where: [...] } ...................................Intro Configuration as Code Test your codeThe next level
  • 124. Test Example from https://github.com/sheehan/job-dsl-gradle-example An example on how to introduce Job DSL in a real life company class JobScriptsSpec extends Specification { @Unroll void 'test script #file.name'(File file) { given: JobManagement jm = Spy(MemoryJobManagement) [...] when: DslScriptLoader(jm).runScript(file.text) then: noExceptionThrown() where: [...] } ...................................Intro Configuration as Code Test your codeThe next level
  • 125. Test Example from https://github.com/sheehan/job-dsl-gradle-example An example on how to introduce Job DSL in a real life company class JobScriptsSpec extends Specification { @Unroll void 'test script #file.name'(File file) { given: JobManagement jm = Spy(MemoryJobManagement) [...] when: DslScriptLoader(jm).runScript(file.text) then: noExceptionThrown() where: file << jobFiles } [...] } ...................................Intro Configuration as Code Test your codeThe next level
  • 126. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { ........................…........Intro Configuration as Code Test your codeThe next level
  • 127. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { ........................…........Intro Configuration as Code Test your codeThe next level <project> <triggers> <hudson.triggers.TimerTrigger> <spec>H * * * *</spec> </hudson.triggers.TimerTrigger> </triggers> </project>
  • 128. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { // is any trigger set? triggers ........................…........Intro Configuration as Code Test your codeThe next level <project> <triggers> <hudson.triggers.TimerTrigger> <spec>H * * * *</spec> </hudson.triggers.TimerTrigger> </triggers> </project>
  • 129. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { // is any trigger set? triggers // is trigger a timer trigger? triggers.'hudson.triggers.TimerTrigger' ........................…........Intro Configuration as Code Test your codeThe next level <project> <triggers> <hudson.triggers.TimerTrigger> <spec>H * * * *</spec> </hudson.triggers.TimerTrigger> </triggers> </project>
  • 130. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { // is any trigger set? triggers // is trigger a timer trigger? triggers.'hudson.triggers.TimerTrigger' // trigger is NOT an scm trigger? !triggers.'hudson.triggers.SCMTrigger' ........................…........Intro Configuration as Code Test your codeThe next level <project> <triggers> <hudson.triggers.TimerTrigger> <spec>H * * * *</spec> </hudson.triggers.TimerTrigger> </triggers> </project>
  • 131. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { // is any trigger set? triggers // is trigger a timer trigger? triggers.'hudson.triggers.TimerTrigger' // trigger is NOT an scm trigger? !triggers.'hudson.triggers.SCMTrigger' // has trigger a specific value? triggers.text().equals('H * * * *') ........................…........Intro Configuration as Code Test your codeThe next level <project> <triggers> <hudson.triggers.TimerTrigger> <spec>H * * * *</spec> </hudson.triggers.TimerTrigger> </triggers> </project>
  • 132. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { // is any trigger set? triggers // is trigger a timer trigger? triggers.'hudson.triggers.TimerTrigger' // trigger is NOT an scm trigger? !triggers.'hudson.triggers.SCMTrigger' // has trigger a specific value? triggers.text().equals('H * * * *') // has timer trigger a specific value? triggers.'hudson.triggers.TimerTrigger'.text().equals('H * * * *') ........................…........Intro Configuration as Code Test your codeThe next level <project> <triggers> <hudson.triggers.TimerTrigger> <spec>H * * * *</spec> </hudson.triggers.TimerTrigger> </triggers> </project>
  • 133. What can be tested? An example on how to introduce Job DSL in a real life company def 'this one has a timer trigger set, but no scm trigger'() { setup: Job job = new JobBuilder(jobParent, 'foo').make { cron(Cron.HOURLY) } expect: with(job.node) { // is any trigger set? triggers // is trigger a timer trigger? triggers.'hudson.triggers.TimerTrigger' // trigger is NOT an scm trigger? !triggers.'hudson.triggers.SCMTrigger' // has trigger a specific value? triggers.text().equals('H * * * *') // has timer trigger a specific value? triggers.'hudson.triggers.TimerTrigger'.text().equals('H * * * *') // trigger has a tag with value timer trigger triggers.get(0).value().get(0).name().equals('hudson.triggers.TimerTrigger') } } ........................…........Intro Configuration as Code Test your codeThe next level <project> <triggers> <hudson.triggers.TimerTrigger> <spec>H * * * *</spec> </hudson.triggers.TimerTrigger> </triggers> </project>
  • 134. Write tests for all job configurations An example on how to introduce Job DSL in a real life company def setupSpec() { jobManagement = new MemoryJobManagement() List<ScriptRequest> scriptRequests = [] ResourceHelper.getAllJobDslFiles().each { File script -> URL scriptURL = new File(script.getPath()).toURI().toURL() scriptRequests.add(new ScriptRequest(script.name, null, scriptURL)) } new DslScriptLoader(jobManagement).runScripts(scriptRequests) } ........................…........Intro Configuration as Code Test your codeThe next level
  • 135. Write tests for all job configurations An example on how to introduce Job DSL in a real life company def setupSpec() { jobManagement = new MemoryJobManagement() List<ScriptRequest> scriptRequests = [] ResourceHelper.getAllJobDslFiles().each { File script -> URL scriptURL = new File(script.getPath()).toURI().toURL() scriptRequests.add(new ScriptRequest(script.name, null, scriptURL)) } new DslScriptLoader(jobManagement).runScripts(scriptRequests) } @Unroll def 'Always activate log rotation for "#config.key"'(Map.Entry<String, String> config) { expect: with(new XmlParser().parse(new StringReader(config.value))) { !logRotator.text().isEmpty() } where: script << jobManagement.savedConfigs } ........................…........Intro Configuration as Code Test your codeThe next level
  • 136. Overall Testing: Enforce scripting standards @Unroll def 'Turn off debug output for shell steps in "#config.key"'(Map.Entry<String, String> config) { expect: with(new XmlParser().parse(new StringReader(config.value))) { } where: script << jobManagement.savedConfigs } An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level
  • 137. Overall Testing: Enforce scripting standards @Unroll def 'Turn off debug output for shell steps in "#config.key"'(Map.Entry<String, String> config) { expect: with(new XmlParser().parse(new StringReader(config.value))) { def scriptCommands = builders.get(0).children().findAll { buildStep -> buildStep.name().equals('hudson.tasks.Shell') }.collect { shellStep -> shellStep.get('command').text() } } where: script << jobManagement.savedConfigs } An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level
  • 138. Overall Testing: Enforce scripting standards @Unroll def 'Turn off debug output for shell steps in "#config.key"'(Map.Entry<String, String> config) { expect: with(new XmlParser().parse(new StringReader(config.value))) { def scriptCommands = builders.get(0).children().findAll { buildStep -> buildStep.name().equals('hudson.tasks.Shell') }.collect { shellStep -> shellStep.get('command').text() } // make sure every script has debug disabled by default scriptCommands.findAll { !it.startsWith('#!/bin/sh -en') }.findAll { !it.startsWith('@echo offn') }.isEmpty() } where: script << jobManagement.savedConfigs } An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level
  • 139. Functional tests def 'test functional stuff for your job builders'() { when: Job job = new JobBuilder(jobParent, 'foo').make { parameters { StringParam('IMPORTANT_PARAMETER', 'wrong!') } } then: thrown IllegalStateException('wrong parameter used!') } An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level
  • 140. Some examples for the impact in the actual teams An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level
  • 141. Some examples for the impact in the actual teams An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level • Web development: Huge release process with a bunch of manual branches -> Now it's a one-klick release
  • 142. Some examples for the impact in the actual teams An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level • Web development: Huge release process with a bunch of manual branches -> Now it's a one-klick release • Business Intelligence: Hardly any automated processes via Jenkins -> Now they automated everything
  • 143. Some examples for the impact in the actual teams An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level • Web development: Huge release process with a bunch of manual branches -> Now it's a one-klick release • Business Intelligence: Hardly any automated processes via Jenkins -> Now they automated everything • Core development: Huge deploy job blob that no one understood -> One-klick deploy jobs for every environment (350+ jobs)
  • 144. Some examples for the impact in the actual teams An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level • Web development: Huge release process with a bunch of manual branches -> Now it's a one-klick release • Business Intelligence: Hardly any automated processes via Jenkins -> Now they automated everything • Core development: Huge deploy job blob that no one understood -> One-klick deploy jobs for every environment (350+ jobs) Teams can work autonomously
  • 145. Benefits • Refactor jobs without fear due to regression testing and debug output • Reduced configuration mistakes due to functional testing • No conflicts between distributed teams • Easy change rollout • Minimal configuration • Maximal convention An example on how to introduce Job DSL in a real life company .........................….......Intro Configuration as Code Test your codeThe next level
  • 146. THANK YOU! PAYBACK GmbH Christian rasp Software Developer DevOps Theresienhöhe 12 80339 München Phone +49 (0) 89 997 41 – 1637 christian.rasp@PAYBACK.net PAYBACK.net | PAYBACK.de