4. Continuous Integration

4.1. Jenkins

  • jenkins/jenkins:alpine - jenkins latest

  • jenkinsci/blueocean - jenkins:lts + blue ocean

docker network create ecosystem
# sudo chmod o+rw /run/user/1000/docker.sock
sudo ln -s /home/ubuntu/.local/share/docker/volumes/jenkins/_data /var/jenkins_home

docker run \
    --name jenkins \
    --detach \
    --rm \
    --network ecosystem \
    --publish 8080:8080 \
    --volume jenkins:/var/jenkins_home \
    --volume /run/user/1000/docker.sock:/var/run/docker.sock \
    jenkinsci/blueocean

4.2. Configuration for Java

pipeline {
  agent any
  stages {
    stage('Environment') {
      steps {
        sh 'hostname'
        sh 'whoami'
        sh 'id'
        sh 'ifconfig'
        sh '# ping -c1 dev.astrotech.io'
        sh 'cat /etc/os-release'
        sh 'uname -a'
        sh 'env |sort'
        sh 'pwd'
        sh 'echo $JAVA_HOME'
        sh 'echo $PATH'
        sh 'java -version'
        sh 'mvn --version'
        sh 'git --version'
      }
    }

    stage('Build') {
      steps {
        sh 'mvn compile'
      }
    }

    stage('Test') {
      parallel {
        stage('Unit Test') {
          steps {
            sh 'mvn test'
          }
        }

        stage('Integration Test') {
          steps {
            sh 'mvn verify'
          }
        }

      }
    }

    stage('Static Code Analysis') {
      steps {
        sh 'mvn compile'
        sh 'mvn test'
        sh 'mvn verify'
        sh 'mvn org.pitest:pitest-maven:mutationCoverage'
        sh 'docker run --rm --network ecosystem -v $(pwd):/usr/src sonarsource/sonar-scanner-cli'
      }
    }

    stage('Upload Artifact') {
      steps {
        sh 'cp -a ~/.m2 .m2'
        sh 'docker build . -f Dockerfile.runtime -t localhost:5000/myapp:$(git log -1 --format="%h")'
        sh 'docker tag localhost:5000/myapp:$(git log -1 --format="%h") localhost:5000/myapp:latest'
        sh 'docker push localhost:5000/myapp:$(git log -1 --format="%h")'
        sh 'docker push localhost:5000/myapp:latest'
        sh 'docker rmi localhost:5000/myapp:latest'
        sh 'docker rmi localhost:5000/myapp:$(git log -1 --format="%h")'
      }
    }

  }
  environment {
    JAVA_HOME = '/usr/lib/jvm/java-1.8-openjdk/'
  }

4.3. Configuration for Python

pipeline {
  agent {
    docker {
      image 'testenv:python'
    }

  }
  stages {
    stage('Unit Test') {
      parallel {
        stage('Unit Test') {
          steps {
            sh '/usr/bin/python3 -m unittest discover example-py-unittest'
          }
        }

        stage('Pytest') {
          steps {
            sh 'cd example-py-pytest && /usr/bin/python3 -m pytest'
          }
        }

        stage('Doctest') {
          steps {
            sh '/usr/bin/python3 -m doctest example-py-doctest/com/automationpanda/example/*.py'
          }
        }

      }
    }

    stage('Static Code Analysis') {
      parallel {
        stage('Static Code Analysis') {
          steps {
            sh '/usr/bin/python3 -m pycodestyle .'
          }
        }

        stage('Pylint') {
          steps {
            sh '/usr/bin/python3 -m pylint .'
          }
        }

      }
    }

    stage('Built') {
      steps {
        sh 'python setup.py build'
      }
    }

    stage('Push to Pip') {
      steps {
        sh 'python3 setup.py upload'
      }
    }

  }
}

4.4. Slides

../_images/ecosystem-big-picture4.png
../_images/cicd-strategy1.png
../_images/cicd-success1.png
../_images/cicd-failing1.png

4.5. Alternatives

Server:

Cloud: