Share
Embed
Transcript
53 slides
-
Eloy Coto Software craftsman Ex Quobis, IPGlobal, Foehn Cilium &
Kamailio contributor @eloycoto [email protected] -
Jenkins Blue Ocean - Like all the Jenkins features, it
is a plugin. - Can be used for job view, the admin part is not ready. - A lot of plugins do not have integration yet - Another themes around: - github.com/afonsof/jenkins-material-theme - github.com/djonsson/jenkins-atlassian-theme $ docker run -p 8080:8080 jenkins/blueocean -
Usual problems with Jenkins scripts - Jenkins has a lot
of disrepute - On early days all were scripts, too many bash&sh scripts - Groovy pipelines are nice, but the learning curve is hard. - Declarative pipelines - Easy to understand. - Still has the power of using Groovy scripts - You should use declarative pipelines -
Declarative Pipelines pipeline { agent any options { timeout(time: 300,
unit: 'MINUTES') } stages { stage("First"){ steps { sh "echo 'Hello World!'" } } } } Jenkinsfile -
Stages pipeline { agent any stages { stage("First"){ steps {
sh "echo 'Hello World!'"} } stage("Second"){ steps { sh "echo 'Hello World!'"} } stage("Third"){ steps { sh "echo 'Hello World!'"} } } } Jenkinsfile -
Agent pipeline { agent { label "fedora" } stages {
stage("OsX"){ agent { label "osX" } steps { sh "echo 'Hello World!'" } } } } Jenkinsfile -
Options pipeline { options { timeout(time: 500, unit: 'MINUTES') timestamps()
ansiColor('xterm') } stages { stage("OsX"){ options { timeout(time: 10, unit: 'MINUTES') } steps { sh "echo 'Hello World!'" } } } } Jenkinsfile -
Timeouts Job global timeout (20min) Stage 1 (10m) Stage 2(10m)
Stage 3 (20m) Waiting in the queue Job global timeout (2 hours) Stage 1 (10m) Stage 2(10m) Stage 3(20m) Waiting in the queue On autoscaling slaves or busy systems, use a large global timeout and adjust stages timeouts. Global Timeout -
Retry pipeline{ stages{ stage("deploy"){ steps{ retry(3){ sh './apply.sh' } sh
'./post.sh' } } } } Jenkinsfile -
Environment variables pipeline { environment { CFG="TEST" DISTRIBUTION="fedora" } stages
{ stage("OsX"){ environment { DISTRIBUTION="osx" } steps { sh 'echo "${DISTRIBUTION}"' } } } } Jenkinsfile -
Job parameters pipeline { parameters { string( defaultValue: 'master', name:
'FRONTEND_BRANCH') choice( choices: 'eu-central-1\neu-west-1', description: 'What AWS region?', name: 'region') } stages { stage("Unit Testing"){ steps {sh "echo '${FRONTEND_BRANCH}'"} } } } Jenkinsfile -
Post actions pipeline { stages { stage("Unit Testing"){ steps {sh
"go test"} post { always { junit '*.xml' } } } } post { always { cleanWs(); } } } Jenkinsfile -
Post actions pipeline { stages { ...} post { always
{ cleanWs(); } success { echo "It works!" } failure { echo "It fails!" } changed { echo "I'm different" } } } Jenkinsfile -
Parallel pipeline{ stages{ stage("Browser testing"){ parallel( "Firefox": { sh "echo
testing FFX" sh "echo more steps" }, "Chrome": { sh "echo testing Chrome" sh "echo more steps" } ) } } } Jenkinsfile -
When pipeline { agent any stages { stage('Deploy') { when
{ allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } } steps { sh 'docker push ..' } } } } Jenkinsfile -
Human interaction pipeline { agent any stages { stage('Deploy') {
steps { input ( id : "Deploy", message: "Do you want to deploy the application?" ) } } } } Jenkinsfile -
Credentials types - Username with password - Secret text -
Secret file - SSH Username with private key - Certificate -
Credentials pipeline { stages { stage("deploy"){ steps { withCredentials([string( credentialsId:
'mytoken', variable: 'TOKEN')]) { sh 'echo "Token->${TOKEN}"' } } } } } Jenkinsfile -
Credentials pipeline { stages { stage("deploy"){ environment { TOKEN=credentials('MY_TOKEN') }
steps { sh 'echo ${TOKEN}' } } } } Jenkinsfile -
Credentials pipeline { stages { stage("deploy"){ environment { AWS=credentials('AWS') }
steps { sh 'echo "${AWS_USR}-${AWS_PWD}"' } } } } Jenkinsfile -
Jenkins Shared libraries ./vars/wrappedNode.groovy ./vars/withVpn.groovy ./vars/withTool.groovy ./vars/withChownWorkspace.groovy ./vars/s3Fetch.groovy ./vars/s3Archive.groovy ./vars/nodeExists.groovy
./vars/golangTester.groovy ./vars/gitCommit.groovy ./vars/getOutput.groovy ./vars/documentationChecker.groovy ./vars/dockerImageTagToDigest.groovy ./vars/codecov.groovy ./src/com/docker/utilities/AWSSync.groovy ./src/com/docker/projects/EngineApi.groovy ./src/com/docker/projects/Docker.groovy github.com/docker/jenkins-pipeline-scripts -
Jenkins Shared Libraries String call() { if (env.GIT_COMMIT == null)
{ env.GIT_COMMIT = sh( script: "git rev-parse HEAD", returnStdout: true).trim() } env.GIT_COMMIT } vars/gitCommit.groovy -
Jenkins Shared libraries @Library('utils') _ pipeline { stages { stage("Checkout"){
steps { gitCommit() } } } } Jenkinsfile -
Job DSL example pipelineJob('DSL_Pipeline') { def repo = 'https://github.com/eloycoto/jenkins_test.git' description("Pipeline
for $repo") triggers { scm('H/5 * * * *') } definition { cpsScm { scm { git { remote { url(repo) } branches('master', '**/feature*') scriptPath('Jenkinsfile') extensions { } } } } } } Jenkinsfile -
Job DSL loops def jobsSpecs = [ "eloycoto/jenkins_test.git": "jenkinsfile" ]
jobsSpecs.each{ JobRepo, JobScriptName -> pipelineJob("${JobRepo}") { description("Pipeline for ${JobRepo}") ... ... scriptPath("${JobScriptName}") } } Jenkinsfile https://job-dsl.herokuapp.com/ -
Autoscaling slaves - Amazon EC2 plugin - Terraform Jenkins slaves
- github.com/dragoonis/terraform-jenkins - Kubernetes Plugin - github.com/jenkinsci/kubernetes-plugin -
JUnit Attachments post { always{ junit testDataPublishers: [ [$class: 'AttachmentPublisher']],
testResults: 'test/*.xml' } } Jenkinsfile -
Validating Jenkinsfiles $ export JENKINS=http://localhost:8080 $ curl -X POST \
-F "jenkinsfile=<jenkinsfile" \ $JENKINS/pipeline-model-converter/validate Terminal -
Clean Workspaces pipeline { ... ... post { always {
cleanWs() } } } Jenkinsfile -
API calls $ export URL='http://localhost:8080' # reference $ curl "$URL/api/json"
# Queue status $ curl "$URL/queue/api/json?pretty=true" # Run groovy scripts ❤ $ CRUMB=$(curl -s "${URL}/crumbIssuer/api/json" \ | jq -r '.crumbRequestField +": "+ .crumb') $ JEscript=$(cat script.groovy) $ curl -s -X POST -H "${CRUMB}" "${URL}/scriptText" \ -d "script=${JEscript}" Terminal -
Tricks for success - Implement CI workflow, it pays off!
- Skip any bash script, use declarative pipelines. - Keep Jenkinsfiles simple. Logic should be avoid. - Export data to Junit, it makes things easier. - Clean the workspace at the end.