Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
652 lines (493 sloc) 19.6 KB



Continuous Integration -> Continuous Delivery -> Continuous Deployment

Jenkins in Devtools Ecosystem


Ecosystem Big Picture


Jenkins in Devtools Ecosystem


Weekly version


for non-training use change /tmp to other persistent directory

mkdir -p /home/jenkins
docker run --rm --name jenkins -d -p 8000:8080 -v /home/jenkins:/var/jenkins_home jenkins/jenkins
cat /home/jenkins/secrets/initialAdminPassword

Install LTS


for non-training use change /tmp to other persistent directory

mkdir -p /home/jenkins
docker run --rm --name jenkins -d -p 8000:8080 -v /tmp/jenkins:/var/jenkins_home jenkins/jenkins:lts
cat /home/jenkins/secrets/initialAdminPassword

Docker Compose

  1. Create file docker-compose.yaml

    version: '3'
        driver: bridge
        image: jenkins/jenkins
        container_name: jenkins
        restart: "no"
          - "8080:8080"
          - devtools-ecosystem
          - /home/jenkins:/var/jenkins_home/
          - /var/run/docker.sock:/var/run/docker.sock
  2. Run Jenkins

    docker-compose up
  3. Run Jenkins in background (daemon)

    docker-compose up -d

More information


  • Local executors (default: 2)
  • Remote workers via SSH and labels
  • Docker build
  • New UI (Blue Ocean) currently accessible as a plugin, but soon to be default
  • Jenkins uses Groovy scripts in Jenkinsfile in repository main directory



Jenkins down... and up again.

User Management

  • Always use LDAP (OpenLDAP or Active Directory)
  • Each tool has separate LDAP read only account
  • Connection only with LDAPS (secure)
  • Internal and external users in one LDAP server
  • Name groups as jenkins-users or jenkins-administrators
  • Local administrator jenkins-administrator only for fixing bugs with LDAP
  • Use (for easy email filtering)
  • Use as domain name with firewall blocking external access
  • Wildcard SSL certificate (*
  • Only HTTPS access to tool!
  • /etc/resolv.conf search -> set by DHCP
  • No nested groups
  • All tool access groups in OU=ecosystem
  • Use LDAP groups for project roles from OU=projects
  • Do not use user accounts in project roles (only LDAP groups)
  • Confluence page with all *-administrators + mailto: links
  • Confluence page with Jira project leaders
  • Confluence page with Jenkins job administrators
  • Do not use technical accounts (use SSH keys)
  • Use SSH keys with proper comment:

Plugin installation

  • Dependencies hell
  • Plugin support (especially those free ones)
  • Open Source plugins
  • Plugin and upgrades
  • Once given out, cannot be easily taken away

Build Triggers

.. literalinclude:: code/
    :language: console
    :caption: build trigger via Jenkins API


  • Email
  • Slack / HipChat
  • IRC

Installing MVN

docker container exec -u 0 -it jenkins bash
mkdir -p /opt
cd /opt
tar -zxvf apache-maven-3.5.4-bin.tar.gz
mv apache-maven-3.5.4 /opt/maven
ln -s /opt/maven/bin/mvn /usr/local/bin/mvn
echo 'export M2_HOME=/opt/maven' > /etc/profile.d/

Now load the environment variables in the current shell using the following command.

source /etc/profile.d/


If your code is in other version:

.. literalinclude:: code/
    :language: properties
    :caption: Minimal Sonar Project Properties

.. literalinclude:: code/
    :language: properties
    :caption: Extra Sonar Project Properties


Development Driven Tests

version: '3'

    driver: bridge


    image: jenkins/jenkins
    restart: always
      - "18080:8080"
      - prodnetwork
      - /tmp/jenkins:/var/lib/jenkins/
      - sonar
      - SONAR_PORT=9000
    image: sonarqube
    restart: always
     - "19000:9000"
     - "19092:9092"
      - prodnetwork

Large repos

  • is a sign of git missuse, and should be tackled with GIT LFS
  • Use command line git rather than jGit
  • command line git handles memory better
  • Use reference repository (bare)
  • Shallow clone (GIT from 1.9+ can push from shallow clones)
  • Don't fetch tags
  • Narrow refspec - only clone specific branches (honor refspec on initial clone)
  • Pipeline stash / unstash (sparse checkout on master node, and then stash checkout, and unstash on remotes)
  • Sparse checkout (Subset of working tree - single directory [exclude or include on per file basis])

Blue Ocean

  • Multibranch projects are the first class citizens
  • New UI
  • Interoperable with old UI
  • Accessible at /blue/ in the URL after "Blue Ocean" plugin installation.
  • Pipeline editor

Blue Ocean pipeline


Blue Ocean pipeline Success


Blue Ocean pipeline Failing

Environment Variables

Groovy syntax

.. literalinclude:: code/groovy-variable.groovy
    :language: groovy
    :caption: Variable

.. literalinclude:: code/groovy-contitional.groovy
    :language: groovy
    :caption: Conditional

.. literalinclude:: code/groovy-control-structure.groovy
    :language: groovy
    :caption: Control structure

.. literalinclude:: code/groovy-function.groovy
    :language: groovy
    :caption: Function

.. literalinclude:: code/groovy-class.groovy
    :language: groovy
    :caption: Class

.. literalinclude:: code/groovy-loop.groovy
    :language: groovy
    :caption: Loop

.. literalinclude:: code/groovy-import.groovy
    :language: groovy
    :caption: Import

.. literalinclude:: code/groovy-exception.groovy
    :language: groovy
    :caption: Exception

.. literalinclude:: code/groovy-http.groovy
    :language: groovy
    :caption: Rest API HTTP queries

Jenkinsfile - Pipeline model definition


Pipeline model definition plugin

Sample Jenkinsfile:

.. literalinclude:: code/jenkinsfile-simple.groovy
    :language: groovy
    :caption: Simple

.. literalinclude:: code/jenkinsfile-example.groovy
    :language: groovy
    :caption: Example

.. literalinclude:: code/jenkinsfile-test.groovy
    :language: groovy
    :caption: Test

.. literalinclude:: code/jenkinsfile-build.groovy
    :language: groovy
    :caption: Build

.. literalinclude:: code/jenkinsfile-deploy.groovy
    :language: groovy
    :caption: Deploy

.. literalinclude:: code/jenkinsfile-environment.groovy
    :language: groovy
    :caption: Environment

.. literalinclude:: code/jenkinsfile-parameter.groovy
    :language: groovy
    :caption: Parameters

.. literalinclude:: code/jenkinsfile-agent.groovy
    :language: groovy
    :caption: Agent

.. literalinclude:: code/jenkinsfile-parallel.groovy
    :language: groovy
    :caption: Parallel

.. literalinclude:: code/jenkinsfile-option.groovy
    :language: groovy
    :caption: Option

.. literalinclude:: code/jenkinsfile-tool.groovy
    :language: groovy
    :caption: Tool

.. literalinclude:: code/jenkinsfile-timeout.groovy
    :language: groovy
    :caption: Timeout

.. literalinclude:: code/jenkinsfile-input.groovy
    :language: groovy
    :caption: Input

.. literalinclude:: code/jenkinsfile-artifact.groovy
    :language: groovy
    :caption: Artifact

Post Actions

At the end of pipeline directive:

always:Run the steps in the post section regardless of the completion status of the Pipeline’s or stage’s run.
changed:Only run the steps in post if the current Pipeline’s or stage’s run has a different completion status from its previous run.
failure:Only run the steps in post if the current Pipeline’s or stage’s run has a "failed" status, typically denoted by red in the web UI.
success:Only run the steps in post if the current Pipeline’s or stage’s run has a "success" status, typically denoted by blue or green in the web UI.
unstable:Only run the steps in post if the current Pipeline’s or stage’s run has an "unstable" status, usually caused by test failures, code violations, etc. This is typically denoted by yellow in the web UI.
aborted:Only run the steps in post if the current Pipeline’s or stage’s run has an "aborted" status, usually due to the Pipeline being manually aborted. This is typically denoted by gray in the web UI
.. literalinclude:: code/jenkinsfile-post.groovy
    :language: groovy
    :caption: Post


cron:Accepts a cron-style string to define a regular interval at which the Pipeline should be re-triggered, for example: triggers { cron('H */4 * * 1-5') }
pollSCM:Accepts a cron-style string to define a regular interval at which Jenkins should check for new source changes. If new changes exist, the Pipeline will be re-triggered. For example: triggers { pollSCM('H */4 * * 1-5') } Available since Jenkins 2.22
upstream:Accepts a comma separated string of jobs and a threshold. When any job in the string finishes with the minimum threshold, the Pipeline will be re-triggered. For example: triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }
.. literalinclude:: code/jenkinsfile-trigger.groovy
    :language: groovy
    :caption: Trigger


branch:Execute the stage when the branch being built matches the branch pattern given, for example: when { branch 'master' }. Note that this only works on a multibranch Pipeline.
environment:Execute the stage when the specified environment variable is set to the given value, for example: when { environment name: 'DEPLOY_TO', value: 'production' }
expression:Execute the stage when the specified Groovy expression evaluates to true, for example: when { expression { return params.DEBUG_BUILD } }
not:Execute the stage when the nested condition is false. Must contain one condition. For example: when { not { branch 'master' } }
allOf:Execute the stage when all of the nested conditions are true. Must contain at least one condition. For example: when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
anyOf:Execute the stage when at least one of the nested conditions is true. Must contain at least one condition. For example: when { anyOf { branch 'master'; branch 'staging' } }
.. literalinclude:: code/jenkinsfile-when.groovy
    :language: groovy
    :caption: When



  • Install Docker on Jenkins container

    docker exec -itu 0 jenkins bash
    curl -fsSL | apt-key add -
    echo "deb [arch=amd64] stretch stable" > /etc/apt/sources.list.d/docker.list
    apt install -y apt-transport-https
    apt update
    apt install -y docker-ce
  • Spawning sibling containers instead of container inside the container

    $ docker run -v /var/run/docker.sock:/var/run/docker.sock ...
  • Using docker

    $ docker pull openjdk:8-jdk
    $ docker pull maven:3-jdk-7
    $ docker pull maven:3-jdk-8
    $ docker pull golang:1.7
    $ docker pull ruby:2.3
    $ docker pull python:2
    $ docker pull python:3
.. literalinclude:: code/jenkinsfile-docker.groovy
    :language: groovy
    :caption: Docker


.. literalinclude:: code/jenkinsfile-maven.groovy
    :language: groovy
    :caption: Maven

Dobre praktyki

  • Skrypt releasowy trzymany w konfiguracji narzędzia
  • Instalacja nadmiarowych pluginów
  • Korzystanie z pluginów zamiast z linii poleceń
  • Przygotowanie środowiska + provisioning
  • Spawnowanie agentów w cloud i czas setupu nowego środowiska
  • Długość buildów
  • Ignorowanie testów ?!
  • Skipowanie testów (verbose)
  • Budowanie Pull Requestów
  • Jak długo trzymać branche?
  • Jak automatycznie czyścić branche?
  • Budowanie na różnych środowiskach
  • Colorful deployments (version names from colors of the first six hexes in GIT ref)
  • Technology radar:
  • Spockframework:
.. literalinclude:: code/spockframework.groovy
    :language: groovy
    :caption: Spock Framework


.. literalinclude:: code/jenkinsfile-color.groovy
    :language: groovy
    :caption: Color

.. literalinclude:: code/jenkinsfile-artifactory.groovy
    :language: groovy
    :caption: Artifactory

.. literalinclude:: code/jenkinsfile-commit-message.groovy
    :language: groovy
    :caption: Commit Hash from git shell

  • Jenkins odpalający git bisect i testy dla każdego commita z próby, tak długo aż nie znajdzie problemu

Build Strategy


Almost green... just some broken tests


Build Strategy


GIT Flow


Instalacja Jenkinsa i konfiguracją buildów

  1. Zainstaluj Jenkins za pomocą Docker
  2. Zaciągnij repozytorium
  3. Ustaw Job aby budował aplikację za pomocą mvn clean install

Building c/c++ projects inside docker

  1. Zainstaluj Jenkins za pomocą Docker

  2. Zaciągnij repozytorium

  3. Budowanie ma odbywać się w kontenerze docker uruchamianym jako sibling

  4. Dodaj job za pomocą Blue Ocean

    • apt update && apt install -y gcc libpcap-dev make
    • ./configure
    • make
    • make check
    • make install

Budowanie Pull Requestów

  • Skonfiguruj ręcznie plan by budował gałęzie wg. schematu GIT Flow

    • Pull Requests
    • feature
    • bugfix
    • master

Pull Requests

Trigger przez API

  • Napisz skrypt sh wykorzystujący curl
  • Skrypt po odpaleniu ma triggerować build
  • Dodaj skrypt do crontab
  • Skrypt ma się uruchamiać @daily
  • Zwróć uwagę, że cron ma mniejszą ilość zmiennych środowiskowych (skrypt, który u Ciebie działa, może nie być odpalany przez cron)

Statyczna analiza kodu za pomocą SonarScanner i SonarQube

  • Dla repozytorium sonar-training-examples (
  • Zacznij budować za pomocą mvn clean install
  • Wyniki upublicznij w SonarQube
  • Build uzależnij od wyniku Quality Gates (plugin Sonar Quality Gates)
  • Uruchom SonarQube za pomocą docker run -d --name sonarqube -p 9000:9000 sonarqube

Budowanie PITest

Jenkinsfile i Pipeline DSL

  • Przepisz całą konfigurację wykorzystując Pipeline DSL zapisany w Jenkinsfile

Jenkins Docker Plugin

  • Skonfiguruj zadanie aby uruchamiało kontener
  • Zadanie ma provisionować konfigurację wewnątrz kontenera
  • Zadanie ma uruchamiać build wewnątrz kontenera
  • Zadanie ma niszczyć kontener po buildze

Jenkins i testy wydajnościowe JMeter

  • Przeprowadź test wydajnościowy głównej strony aplikacji uruchomionej na Twoim komputerze (np. SonarQube jeżeli wykonałeś poprzednie ćwiczenie)
  • Test wydajnościowy powinien zapisany w xml oraz uruchamiany bez wykorzystania GUI


  1. Nagraj test w selenium
  2. Uruchom test przy każdym commicie do brancha feature i bugfix
You can’t perform that action at this time.