State of the Jenkins Automation
-
Upload
julien-pivotto -
Category
Technology
-
view
769 -
download
4
Transcript of State of the Jenkins Automation
![Page 1: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/1.jpg)
State of the Jenkins Automation
Julien Pivotto (@roidelapluie)
Floss Spring 2017
Manchester - March 15, 2017
![Page 2: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/2.jpg)
whoamiJulien "roidelapluie" Pivotto
@roidelapluie
Sysadmin at Inuits
Automation, monitoring, HA
Jenkins user for 5+ years
![Page 3: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/3.jpg)
inuits
![Page 4: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/4.jpg)
JenkinsOpen Souce CI Server
Written in Java
First release in 2011
Fork of Hudson (2005)
![Page 5: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/5.jpg)
What can you do with Jenkins?Testing, building, deploying software
Testing, building, deploying services
Testing, building, deploying infra (IaC)
![Page 6: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/6.jpg)
Mission CriticalPublic Domain https://commons.wikimedia.org/wiki/File:Roaddamage59quake.JPG
![Page 7: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/7.jpg)
Automating JenkinsCreative Commons Attribution-ShareAlike 2.0 https://www.flickr.com/photos/machu/3131057286
![Page 8: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/8.jpg)
Why is it hard?For long, Jenkins has been UI-Driven
It is "easy" to deploy (.war file)
It has lots of plugins (and you need them)
![Page 9: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/9.jpg)
Why is it needed?Security (high value target)
Bugfixes
Plugins
![Page 10: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/10.jpg)
XML everywhere!Creative Commons Attribution 2.0 https://www.flickr.com/photos/generated/6035308729
![Page 11: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/11.jpg)
Lot of things to automateJenkins Service
Jenkins configuration: security, plugins
Jenkins "data": Jobs/Views
Inside the jobs
Jenkins nodes
![Page 12: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/12.jpg)
Automating the serviceCC0 Public Domain https://pixabay.com/en/butler-tray-beverages-wine-964007/
![Page 13: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/13.jpg)
Automating the Jenkins ServiceChef: Jenkins in the supermarket
Puppet: module rtyler/jenkins
Playbooks/etc for other tools as well
Docker
![Page 14: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/14.jpg)
Jenkins Master in DockerJenkins upstream images: alpine/ubuntu
Please no executors on master
How do you deploy the container?
Pipeline to build&upgrade it
![Page 15: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/15.jpg)
Jenkins PluginsFetched from https://updates.jenkins-ci.org
Can be installed from the UI :(
Can be installed from the CLI
![Page 16: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/16.jpg)
Packaging Jenkins PluginsPlugins have dependencies (against plugins &Jenkins core)
They have a fixed download path
They are listed in updates.jenkins.io/update-center.json
https://github.com/roidelapluie/Jenkins-Plugins-RPM
![Page 17: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/17.jpg)
Mirroring Jenkins PluginsMirror http://updates.jenkins-ci.org
By default, "latest" will be fetched
Don't cache too much
github.com/jenkinsci/docker install-plugins.sh
![Page 18: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/18.jpg)
Global configurationCC0 Public Domain https://commons.wikimedia.org/wiki/File:Waiting_room_bell.jpg
![Page 19: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/19.jpg)
Modifying XML files
DON'T
![Page 20: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/20.jpg)
system-config-dsl-pluginLike Job DSL, but for the system
https://github.com/jenkinsci/system-config-dsl-plugin
JENKINS-31094
Downside: it does not exist yet
![Page 21: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/21.jpg)
Creative Commons Attribution-Share Alike 3.0https://commons.wikimedia.org/wiki/File:Groovy-logo.svg
![Page 22: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/22.jpg)
GroovyYet another language to learn? yes.
Programming language for the Java platform
Scripting language
Fully integrated in Jenkins
Used by automation tools (chef cookbook,puppet module...)
![Page 23: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/23.jpg)
The Jenkins Script ConsoleA groovy console is available at /script
http://jenkins.example.com/script
also with curl
Requires "Overall/Run Scripts" permission
![Page 24: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/24.jpg)
Sample Groovy scriptsCreative Commons Attribution-Share Alike 2.0
https://www.flickr.com/photos/bjornb/88101376
![Page 25: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/25.jpg)
Set number of executorsimport jenkins.model.Jenkins;Jenkins.instance.setNumExecutors(0)
![Page 26: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/26.jpg)
Set HTML formatterimport jenkins.model.Jenkins;import hudson.markup.RawHtmlMarkupFormatter;
Jenkins.instance.setMarkupFormatter(new RawHtmlMarkupFormatter(false));
![Page 27: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/27.jpg)
Set system messageimport jenkins.model.Jenkins;Jenkins.instance.setSystemMessage("""Welcome to <em>Jenkins</em>.""");
![Page 28: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/28.jpg)
Configure simple-themeimport jenkins.model.Jenkins;
def simpleThemePlugin = \ Jenkins.instance.getDescriptor( "org.codefirst.SimpleThemeDecorator") simpleThemePlugin.cssUrl = \ "/userContent/example.css"simpleThemePlugin.save()
Everything in $JENKINS_HOME/userContentis served under /userContent
![Page 29: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/29.jpg)
Emailimport jenkins.model.Jenkinsdef desc = Jenkins.instance.getDescriptor( "hudson.tasks.Mailer")desc.setSmtpHost("172.17.0.1")desc.save()
![Page 30: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/30.jpg)
Disable usage statisticsimport hudson.model.UsageStatistics;hudson.model.UsageStatistics.DISABLED = true;
![Page 31: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/31.jpg)
But also...Setup Authorization/Authentication
Setup prefix url
Setup slaves, clouds
Setup global libraries
Setup credentials
Setup first jobs
![Page 32: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/32.jpg)
Bonusimport org.jenkinsci.plugins.pipeline.utility.steps.shaded.org.yaml.snakeyaml.YamlYaml reader = new Yaml()Map config = reader.load(text)
Thanks to pipeline utility step (readYaml()step), you can easily read yaml files
![Page 33: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/33.jpg)
Scripts sourceshttps://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console
https://github.com/jenkinsci/jenkins-scripts/tree/master/scriptler
https://github.com/infOpen/ansible-role-jenkins/tree/master/files/groovy_scripts
https://github.com/samrocketman/jenkins-bootstrap-jervis/tree/master/scripts
https://github.com/jenkinsci/puppet-
jenkins/blob/master/files/puppet_helper.groovy
http://pghalliday.com/jenkins/groovy/sonar/chef/configuration/management/2014
/09/21/some-useful-jenkins-groovy-scripts.html
![Page 34: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/34.jpg)
Jenkins Javadocshttps://jenkins.io/doc/developer/guides/
http://javadoc.jenkins.io/archive/jenkins-2.32/
http://javadoc.jenkins.io/
http://javadoc.jenkins.io/plugin/gerrit-trigger/
![Page 35: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/35.jpg)
Now what?Creative Commons Attribution 2.0 https://www.flickr.com/photos/51029297@N00/5275403364
![Page 36: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/36.jpg)
Jenkins init.groovy.dUpon startup, Jenkins will run $JENKINS_HOME/init.groovy.d/*.groovy
scripts
Meanwhile, "Jenkins is getting ready..."message is displayed
Drop files, restart Jenkins
Allows you to preconfigure everything --without the GUI
![Page 37: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/37.jpg)
init.groovy.d directorybehaviour
Scripts executed sequentally (alphanumorder)
Scripts that throws exceptions make startupfail
![Page 38: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/38.jpg)
Inside Jenkins
![Page 39: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/39.jpg)
The Multiple ApproachesGUI .. but this talk is about automation, right?
init.groovy.d: to create your seed job
Jenkins Job Builder: declarative, python, yaml
Jenkins Job DSL: imperative, groovy
![Page 40: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/40.jpg)
Jenkins Job BuilderAn Openstack Project
Python (not a Jenkins Plugin!)
Support templates
Extensible
Can do raw xml
Limited support for plugins and pipeline
Put Jobs config under SCM
![Page 41: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/41.jpg)
init.groovy.ddef jobManagement = new JenkinsJobManagement( System.out, [:], new File('.'))
new DslScriptLoader(jobManagement).runScript("""folder('jenkins') displayName('Jenkins')pipelineJob("jenkins/seed") definition cpsScm scm git remote credentials('jenkinsgitna') url('git.example.com/seed.git') branches('master') scriptPath('Jenkinsfile') """)
![Page 42: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/42.jpg)
Jenkins Job DSLA Jenkins Plugin
2012
Groovy DSL to create views & jobs
Put Jobs config under SCM
![Page 43: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/43.jpg)
Creative Commons Attribution-Share Alike 3.0https://commons.wikimedia.org/wiki/File:Groovy-logo.svg
![Page 44: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/44.jpg)
Job DSL supportLarge community of users
Lots of plugins supported
![Page 45: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/45.jpg)
Create a jobjob('test') scm git('git://example.com/foo.git' 'master') steps shell('make test')
![Page 46: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/46.jpg)
Create a Pipeline jobpipelineJob('test') definition cps script(buildScript)
![Page 47: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/47.jpg)
Set job propertiespipelineJob('test') description('Test Build') parameters booleanParam('verbose', false, 'Be Verbose') logRotator numToKeep(10)
![Page 48: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/48.jpg)
Read yamlimport org.jenkinsci.plugins.pipeline.utility.steps.shaded.org.yaml.snakeyaml.YamlYaml reader = new Yaml()Map config = reader.load( readFileFromWorkspace('cfg.yaml')
Just like in init.groovy.d scripts
readFileFromWorkspace()
![Page 49: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/49.jpg)
Loopsconfig.each() jobConfig > pipelineJob(jobConfig.name) triggers if (jobConfig.triggers?.scm) scm(jobConfig.triggers.scm)
![Page 50: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/50.jpg)
Create a viewlistView('Project A') recurse() jobs regex('myprj/[/]+') columns status() weather() name() lastSuccess() lastFailure() lastDuration() lastBuildConsole() buildButton() progressBar()
![Page 51: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/51.jpg)
Work with pluginsbuildMonitorView("OnScreen Status") jobs name('WatchA')
$JENKINS_URL/plugin/job-dsl/api-viewer/
![Page 52: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/52.jpg)
In PipelinejobDsl removedJobAction: 'DELETE', removedViewAction: 'DELETE', targets: 'seeds/*.groovy'
![Page 53: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/53.jpg)
Load extra librariesjobDsl additionalClasspath: 'src/*.jar', removedJobAction: 'DELETE', removedViewAction: 'DELETE', targets: 'seeds/*.groovy'
![Page 54: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/54.jpg)
Jenkins PipelineCreative Commons Attribution 2.0 https://www.flickr.com/photos/amerune/9294639633
![Page 55: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/55.jpg)
Jenkins PipelineJenkins Jobs as Code
"Jenkins file"
Imperative (aka scripted) Pipeline
Declarative Pipeline (2017)
![Page 56: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/56.jpg)
What is a Jenkinsfile (akaPipeline)
A file that contains the definition of a job
No need of Gui
Defines Steps, Reports, Environments,Nodes,...
Plugins can provide steps
Generic "step"
![Page 57: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/57.jpg)
How to write Pipelines?Visual Pipeline editor (WIP)
"Pipeline Syntax" link in jobs
![Page 58: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/58.jpg)
Scriped pipelinenode ("Ubuntu && amd64") stage('checkout') checkout scm stage('build') sh 'make' stage('test') sh 'make test'
![Page 59: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/59.jpg)
Real World Scripted Pipelinenode ("Ubuntu && amd64") checkout scm
stage('build') try sh 'make' catch(err) currentBuild.result = 'UNSTABLE' publishArtifacts('err.log') throw err stage('test') sh 'make test' step([$class: 'JavadocArchiver', javadocDir: "target/site", keepAll: true])
![Page 60: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/60.jpg)
Declarative Pipeline (1/2)pipeline agent label("Ubuntu && amd64") options timeout(time: 235, unit: 'MINUTES') timestamps() ansiColor('xterm') stages stage('build') steps sh('make')
![Page 61: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/61.jpg)
Declarative Pipeline (2/2)pipeline post always junit params.jUnitReports
![Page 62: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/62.jpg)
Declarative vs scriptedDeclarative checkout code by default
Declarative get a workspace "OOTB"
Declarative enforces everything in stages
Declarative allow Pipeline-wide wrappers (e.gansiColor, timestamps)
![Page 63: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/63.jpg)
Going further with PipelineGlobal Libraries Plugins
Job DSL Plugin
![Page 64: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/64.jpg)
Jenkins NodesCC0 Public Domain https://www.flickr.com/photos/133259498@N05/27077266322/
![Page 65: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/65.jpg)
Docker Docker DockerRun jobs inside containers
Clean, short lived containers
Easy to update
Docker Plugin
![Page 66: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/66.jpg)
Docker nodes patternBuild Container
Tag it with a tag "candidate"
Push it to your registry
Run normal testing
Run actual builds with that "candidate"
If success -> tag with "release" && push
![Page 67: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/67.jpg)
In practiceDocker Plugin config automated with groovy
Candidate and Release tags are setup asslaves
They get two labels: "image" "tag" (e.g. "build-centos-7" "candidate")
Jobs get a parameter "tag"
![Page 68: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/68.jpg)
In the build Jenkinsfilepipeline agent label("buildcentos7 && $params.tag")
![Page 69: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/69.jpg)
In the docker-build JenkinsfiledockerImage = docker.build("buildcentos7", "nocache")dockerImage.tag('candidate')docker.withRegistry(url, credentials) dockerImage.push('candidate')
node("buildcentos7 && candidate") sh('testscript')build job: 'myjob', parameters: [string(name:'tag', value:'candidate')] dockerImage.tag('release')docker.withRegistry(url, credentials) dockerImage.push('release')
![Page 70: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/70.jpg)
Pros/ConsUpdated containers won't block the builds (e.gon packages updates)
Containers stay up to date
Don't forget that builds release artifacts(sometime you don't want that in nodes tests)
![Page 71: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/71.jpg)
ConclusionPublic Domain https://commons.wikimedia.org/wiki/File:YellowOnions.jpg
![Page 72: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/72.jpg)
Jenkins can be FULLYautomated
My recommendations:
init.groovy.d
Jenkins Job DSL
Pipeline
![Page 73: State of the Jenkins Automation](https://reader033.fdocuments.us/reader033/viewer/2022051318/58d1bc9c1a28ab98278b61ff/html5/thumbnails/73.jpg)
You can go furtherI am happy to talk about:
Jenkins master in Docker container
BlueOcean
... I use that but did not fit in this timeslot