Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Spectrecoin Continuous Integration
This document describes the whole Continuous Integration setup of Spectrecoin.
General system setup
Build hosts setup
At the moment there are two different types of EC2 instances used:
To bring up everything smoothly and easy to update, we forked the GitHub project docker-jenkins-nginx-letsencrypt into spectrecoin/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
- Put admin account into docker group
- Create folder /jenkins and set admin:admin as owner and group
Afterwards an own Spectrecoin-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 Spectrecoin 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.
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- and a builder-part and a consolidating final Spectrecoin build.
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.
With the same reason as the builder images from before, base images where created. These images contain all runtime dependencies of Spectrecoin and they are not required for the plain build of Spectrecoin. So this job runs only in case of changed runtime dependencies and provides the basement for our ready to run Docker images.
The final Spectrecoin Docker image
The main Spectrecoin repository contains also Dockerfiles, which use the builder- and base-images to create the final deliveries. So the Docker build creates an instance of the builder-image and performs the real compilation of Spectrecoin. Afterwards an instance of the base-image is created and the previously built binaries are installed there. The final step is to push these Docker images to DockerHub, so they could directly pulled from these users, which would let the wallet run as a Docker container.
Spectre-Distribution & GitHub-Uploader
The Spectre-Distribution and GitHub-Uploader repositories contains Dockerfiles, which will not have real Docker images as their result. In this case Docker is used as the tool to create the release artifacts for the supported Distributions.
In fact the following happens:
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 the Spectre-Distribution repository: A temporary Docker image for each supported Linux distribution is created, which extracts the Spectrecoin binaries from the formerly build Spectrecoin Docker images. After that these binaries will be archived together and uploaded to the corresponding release tag on the Spectrecoin release section.
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 handels them by himself. The jobs will of course be removed, if the corrsponding branch is removed like after a merge of the branch into another one.
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.