Skip to content

Continuous Integration

HLXEasy edited this page Mar 22, 2021 · 4 revisions

Alias Continuous Integration

This document describes the whole Continuous Integration setup of Alias.

General system setup

The whole CI system is running on Amazon AWS and is mostly based on Docker respectively Docker images. As build orchestrator we use Jenkins.

Build hosts setup

At the moment there are two different types of EC2 instances used:

  • A c5d.large instance for the Jenkins master.
  • Multiple t2.2xlarge instances for the build slaves.

Jenkins master

The Jenkins master is running on an c5d.large instance, which is using a Debian Stretch AMI as operating system with Docker and Docker-Compose installed.

To bring up everything smoothly and easy to update, we forked the GitHub project docker-jenkins-nginx-letsencrypt into aliascash/docker-jenkins-nginx-letsencrypt and customized it slightly to our needs:

  • Updated hostname entries
  • Using named volume for Jenkins home directory
  • Expose port 50000 for build slaves
  • Use dedicated path to store nginx content

Jenkins build slaves

The Jenkins build slaves where initially setup using a t2.2xlarge instance, which was running also a Debian Stretch AMI. On this instance the following installations and modifications took place:

  • Activation of Stretch backports repository
  • Installation of
    • ca-certificates
    • curl
    • gnupg2
    • software-properties-common
    • git
    • git-lfs
    • docker-ce
    • xfsprogs
    • openjdk-8-jdk
    • qemu-user-static
  • Put admin account into docker group
  • Create folder /jenkins and set admin:admin as owner and group

Afterwards an own Alias-Wallet-Builder AMI was created from this instance.

To spawn build slave instances on demand we use the Amazon EC2 Plugin on Jenkins and configured slave instances using the above mentioned AMI, instance type t2.2xlarge and label docker. So with this setup Jenkins starts new build slave instances if a buildjob requires build slaves with label docker and shut them down after a certain idle timeout.

Updating the CI

Updating the CI master is now a quite easy task. The repository docker-jenkins-nginx-letsencrypt is cloned on the Master host and all the following could be done as admin user:

  • Shutdown Docker containers:
    ~$ cd docker-jenkins-nginx-letsencrypt/
    ~/docker-jenkins-nginx-letsencrypt$ docker-compose down
    
  • Update Docker images:
    ~/docker-jenkins-nginx-letsencrypt$ docker-compose pull
    
  • Start new Docker containers:
    ~/docker-jenkins-nginx-letsencrypt$ docker-compose up -d
    

It took some minutes afterwards until everything is up&running again (start of four containers, get letsencrypt certificates, start Jenkins master etc).

General build setup

The Alias Linux build is mostly based on Docker. This enables the possibility, to test the build itself easily on different base systems respectively different Linux distributions. As default distribution Debian Stretch is used.

Also, each Repository on Alias GitHub organization, which contains a so called Jenkinsfile will be automatically build. Details see below.

Docker images

To take advantage of the Docker concept and to improve build speed, the build itself and also the corresponding Docker images are split into a base-part and a builder-part and a consolidating final Alias build.

Alias-Wallet-Builder

One thing to speedup the build is to split these build steps into an own build job, which build or setup the build system itself. This job will only run, if there are changes on the build requirements or dependencies. So these steps where separated into the creation of dedicated builder images for various Linux distributions, which contain all buildtime dependencies.

Alias-Wallet-Base

With the same reason as the builder images from before, base images where created. These images contain all runtime dependencies of Alias and they are not required for the plain build of Alias. So this job runs only in case of changed runtime dependencies and provides the basement for individual experiments with different Linux distributions.

The final Alias Docker image

The main Alias repository contains also Dockerfiles, which use the builder-images to create the final deliveries. So the Docker build creates an instance of the builder-image and performs the real compilation of Alias in there.

GitHub-Uploader

With the GitHub-Uploader repository a helper Docker image is created, which contains the very useful tool github-release. This tool respectively the GitHub-Uploader Docker image can be used, to upload all kind of artifacts to a release tag on a GitHub repository. Exactly this will happen during the Docker build of with the Dockerfiles from the Alias main repository: The build itself is a multi stage build and so at first a builder instance is created and the Alias binaries will be built there. After that an instance of the GitHub uploader is created and the binaries where copied over from the previously created builder instance. After that these binaries will be uploaded to the corresponding release tag on the Alias release section on GitHub.

Jenkins Buildjobs

The major part of the build job configuration on Jenkins is based on a so called GitHub Organization Scanner. The scanner is configured with the URL to the GitHub organization and scans all existing repositories.

On each repository each branch is checked for the existence of a Jenkinsfile and if found, a dedicated buildjob for this branch is created. So there is no administration necessary to setup buildjobs in case a new branch is created on one of the Git repositories as Jenkins handles them himself. The jobs will of course be removed, if the corrsponding branch is removed like after a merge of the branch into another one.

GitHub-Jenkins-Interaction

For the interaction between GitHub and Jenkins the GitHub-Plugin is used. This enables two way communication between GitHub and Jenkins with the following major advantages:

  • To trigger a buildjob it is not necessary to let Jenkins poll GitHub for changes. The GitHub plugin installs a webhook on each Repository on GitHub, so GitHub itself triggers the buildjob after i. e. something was pushed to a repository. This increases build speed and reduces feedback time to the developers, as there is no wait time until the next poll because the build job is instantly triggered by GitHub.
  • If a buildjob was finished, the corresponding hash will be marked with the build status failed or successful. So it is directly on the GitHub repository webpage visible, if the build is green or not.
  • If a pull request is opened, the result of this pull request is also build right before it could be approved. Git makes this possible by applying the desired merge of the pull request and performing the build to check if the build itself is working. So if the build fails, the pull request cannot be approved respectively merged.
Clone this wiki locally