SlideShare a Scribd company logo
1 of 146
Download to read offline
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

What's hot

Puppetcamp r10kyaml
Puppetcamp r10kyamlPuppetcamp r10kyaml
Puppetcamp r10kyamlPuppet
 
Writing less code with Serverless on AWS at FrOSCon 2021
Writing less code with Serverless on AWS at FrOSCon 2021Writing less code with Serverless on AWS at FrOSCon 2021
Writing less code with Serverless on AWS at FrOSCon 2021Vadym Kazulkin
 
How adding a further tool can be a good thing
How adding a further tool can be a good thingHow adding a further tool can be a good thing
How adding a further tool can be a good thingBelsoft
 
Pietro Di Bello, Paolo D'Incau - Continuous Delivery su progetti Java: cosa a...
Pietro Di Bello, Paolo D'Incau - Continuous Delivery su progetti Java: cosa a...Pietro Di Bello, Paolo D'Incau - Continuous Delivery su progetti Java: cosa a...
Pietro Di Bello, Paolo D'Incau - Continuous Delivery su progetti Java: cosa a...Codemotion
 
Drupal Deployment
Drupal DeploymentDrupal Deployment
Drupal DeploymentJeff Eaton
 
2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)Puppet
 
vBrownBag DevOps Series: Puppetinabox
vBrownBag DevOps Series: PuppetinaboxvBrownBag DevOps Series: Puppetinabox
vBrownBag DevOps Series: PuppetinaboxRobert Nelson
 
Infrastructure Automation at Scale
Infrastructure Automation at ScaleInfrastructure Automation at Scale
Infrastructure Automation at ScaleDataCentred
 
Jenkins Workflow Webinar - Dec 10, 2014
Jenkins Workflow Webinar - Dec 10, 2014Jenkins Workflow Webinar - Dec 10, 2014
Jenkins Workflow Webinar - Dec 10, 2014CloudBees
 
Jenkins talk at Silicon valley DevOps meetup
Jenkins talk at Silicon valley DevOps meetupJenkins talk at Silicon valley DevOps meetup
Jenkins talk at Silicon valley DevOps meetupCloudBees
 
Build your application in seconds and optimize workflow as much as you can us...
Build your application in seconds and optimize workflow as much as you can us...Build your application in seconds and optimize workflow as much as you can us...
Build your application in seconds and optimize workflow as much as you can us...Alex S
 
Docs as Part of the Product - Open Source Summit North America 2018
Docs as Part of the Product - Open Source Summit North America 2018Docs as Part of the Product - Open Source Summit North America 2018
Docs as Part of the Product - Open Source Summit North America 2018Den Delimarsky
 
Learn How Selenium And Jenkins Fit In DevOps | Edureka Live
Learn How Selenium And Jenkins Fit In DevOps | Edureka LiveLearn How Selenium And Jenkins Fit In DevOps | Edureka Live
Learn How Selenium And Jenkins Fit In DevOps | Edureka LiveEdureka!
 
Big datatraining.in devops-part1
Big datatraining.in devops-part1Big datatraining.in devops-part1
Big datatraining.in devops-part1MvkZ
 

What's hot (18)

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

Viewers also liked

Build automation best practices
Build automation best practicesBuild automation best practices
Build automation best practicesCode Mastery
 
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...Daniel Gallego Vico
 
XPages build automation and testing
XPages build automation and testingXPages build automation and testing
XPages build automation and testingmpradny
 
Continuous Integration & Package Management 101
Continuous Integration & Package Management 101Continuous Integration & Package Management 101
Continuous Integration & Package Management 101Maor Hayun
 
Abdominal wall closure
Abdominal wall closureAbdominal wall closure
Abdominal wall closureNuwan Gunapala
 
Management of the burst abdomen.ppt
Management of the burst abdomen.pptManagement of the burst abdomen.ppt
Management of the burst abdomen.pptDr./ Ihab Samy
 

Viewers also liked (7)

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

Similar to Rule jenkins with configuration as code

Oh the compilers you'll build
Oh the compilers you'll buildOh the compilers you'll build
Oh the compilers you'll buildMark Stoodley
 
How Custom is your Org? CEER at Dreamforce 2019
How Custom is your Org?  CEER at Dreamforce 2019How Custom is your Org?  CEER at Dreamforce 2019
How Custom is your Org? CEER at Dreamforce 2019Steven Herod
 
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...Chocolatey Software
 
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...Michel Buczynski
 
Modern Release Engineering in a Nutshell - Why Researchers should Care!
Modern Release Engineering in a Nutshell - Why Researchers should Care!Modern Release Engineering in a Nutshell - Why Researchers should Care!
Modern Release Engineering in a Nutshell - Why Researchers should Care!Bram Adams
 
Continuous delivery @wcap 5-09-2013
Continuous delivery   @wcap 5-09-2013Continuous delivery   @wcap 5-09-2013
Continuous delivery @wcap 5-09-2013David Funaro
 
Pipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as CodePipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as CodeKris Buytaert
 
Going open source with small teams
Going open source with small teamsGoing open source with small teams
Going open source with small teamsJamie Thomas
 
Features, Exportables & You
Features, Exportables & YouFeatures, Exportables & You
Features, Exportables & Youjskulski
 
From prototype to production - The journey of re-designing SmartUp.io
From prototype to production - The journey of re-designing SmartUp.ioFrom prototype to production - The journey of re-designing SmartUp.io
From prototype to production - The journey of re-designing SmartUp.ioMáté Lang
 
Dat 210 academic adviser ....tutorialrank.com
Dat 210 academic adviser ....tutorialrank.comDat 210 academic adviser ....tutorialrank.com
Dat 210 academic adviser ....tutorialrank.comladworkspaces
 
DAT 210 Education Specialist |tutorialrank.com
DAT 210 Education Specialist |tutorialrank.comDAT 210 Education Specialist |tutorialrank.com
DAT 210 Education Specialist |tutorialrank.comladworkspaces
 
Continuous Integration for Citizens
Continuous Integration for CitizensContinuous Integration for Citizens
Continuous Integration for CitizensMikhail Zyatin
 
Interview with Issam Lahlali, one of the CppDepend tool creators
Interview with Issam Lahlali, one of the CppDepend tool creatorsInterview with Issam Lahlali, one of the CppDepend tool creators
Interview with Issam Lahlali, one of the CppDepend tool creatorsPVS-Studio
 
TDD - Seriously, try it! (updated '22)
TDD - Seriously, try it! (updated '22)TDD - Seriously, try it! (updated '22)
TDD - Seriously, try it! (updated '22)Nacho Cougil
 
TDD - Seriously, try it! - Bucarest Tech Week
TDD - Seriously, try it! - Bucarest Tech WeekTDD - Seriously, try it! - Bucarest Tech Week
TDD - Seriously, try it! - Bucarest Tech WeekNacho Cougil
 
PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...
PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...
PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...Andrey Karpov
 

Similar to Rule jenkins with configuration as code (20)

Raising the Bar
Raising the BarRaising the Bar
Raising the Bar
 
DevOps and Cloud
DevOps and CloudDevOps and Cloud
DevOps and Cloud
 
BDD Primer
BDD PrimerBDD Primer
BDD Primer
 
Oh the compilers you'll build
Oh the compilers you'll buildOh the compilers you'll build
Oh the compilers you'll build
 
How Custom is your Org? CEER at Dreamforce 2019
How Custom is your Org?  CEER at Dreamforce 2019How Custom is your Org?  CEER at Dreamforce 2019
How Custom is your Org? CEER at Dreamforce 2019
 
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
 
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
Facilitating continuous delivery in a FinTech world with Salt, Jenkins, Nexus...
 
Modern Release Engineering in a Nutshell - Why Researchers should Care!
Modern Release Engineering in a Nutshell - Why Researchers should Care!Modern Release Engineering in a Nutshell - Why Researchers should Care!
Modern Release Engineering in a Nutshell - Why Researchers should Care!
 
Continuous delivery @wcap 5-09-2013
Continuous delivery   @wcap 5-09-2013Continuous delivery   @wcap 5-09-2013
Continuous delivery @wcap 5-09-2013
 
Pipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as CodePipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as Code
 
Going open source with small teams
Going open source with small teamsGoing open source with small teams
Going open source with small teams
 
Features, Exportables & You
Features, Exportables & YouFeatures, Exportables & You
Features, Exportables & You
 
From prototype to production - The journey of re-designing SmartUp.io
From prototype to production - The journey of re-designing SmartUp.ioFrom prototype to production - The journey of re-designing SmartUp.io
From prototype to production - The journey of re-designing SmartUp.io
 
Dat 210 academic adviser ....tutorialrank.com
Dat 210 academic adviser ....tutorialrank.comDat 210 academic adviser ....tutorialrank.com
Dat 210 academic adviser ....tutorialrank.com
 
DAT 210 Education Specialist |tutorialrank.com
DAT 210 Education Specialist |tutorialrank.comDAT 210 Education Specialist |tutorialrank.com
DAT 210 Education Specialist |tutorialrank.com
 
Continuous Integration for Citizens
Continuous Integration for CitizensContinuous Integration for Citizens
Continuous Integration for Citizens
 
Interview with Issam Lahlali, one of the CppDepend tool creators
Interview with Issam Lahlali, one of the CppDepend tool creatorsInterview with Issam Lahlali, one of the CppDepend tool creators
Interview with Issam Lahlali, one of the CppDepend tool creators
 
TDD - Seriously, try it! (updated '22)
TDD - Seriously, try it! (updated '22)TDD - Seriously, try it! (updated '22)
TDD - Seriously, try it! (updated '22)
 
TDD - Seriously, try it! - Bucarest Tech Week
TDD - Seriously, try it! - Bucarest Tech WeekTDD - Seriously, try it! - Bucarest Tech Week
TDD - Seriously, try it! - Bucarest Tech Week
 
PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...
PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...
PVS-Studio and CppCat: An Interview with Andrey Karpov, the Project CTO and D...
 

Recently uploaded

Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxnada99848
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 

Recently uploaded (20)

Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptx
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 

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