CI/CD deliverables pipeline

Happy Coincidence

Building the Build Images

In the first step, the admin builds the images that the deliverables build requires. It makes sense to use a fully automated process with Jenkins for this, too. To do so, you need to version the Dockerfiles in your own Git repositories. Additionally, each of the repositories is assigned a Jenkinsfile in the root directory that defines the build image. The Git repository for the uploader [8], repository for the builders [9], and corresponding Docker repositories [10]-[12] can be found online.

Thanks to the organization scanner set up in the previous step, the system automatically finds these repositories and sets up corresponding build jobs. The scanner also creates the hooks on GitHub so that the builds are triggered by a push. This eliminates the need to update repositories periodically to reflect changes. The account you use must, of course, have suitable repository permissions, and the Jenkins instance must be accessible from GitHub.

Once the jobs have run successfully, the images required for the build of the deliverables are now available on Docker Hub.

Building the Project Deliverables

Now the setup has progressed to the extent at which the CI system is ready for its tasks: recurring automatic building of the project deliverables, with all required details, and uploading them to GitHub. The main repository of the project has a Jenkinsfile in the root directory that defines the build. The build process from Jenkins' point of view is therefore identical to the build of the auxiliary repositories for the Builder images and the GitHub Uploader that have already been described. The Linux binaries are built-in Docker instances that are based on the prepared Builder and Uploader images. The multistage build of the Debian variant can be seen in Listing 4.

Listing 4

Multistage Dockerfile of App Build

01 ### At first perform source build ###
02 FROM starwarsfan/cmake-builder-debian:1.0 as build
03 MAINTAINER Yves Schumann <yves@eisfair.org>
04
05 COPY /demo-app
06
07 RUN mkdir /demo-app/build \
08  && cd /demo-app/build \
09  && cmake .. \
10  && cmake --build .
11
12 RUN echo "Build is finished now, just execute result right here to show something on the log:" \
13  && /demo-app/build/hello-world
14
15 ### Now upload binaries to GitHub ###
16 FROM starwarsfan/github-release-uploader:1.0
17 MAINTAINER Yves Schumann <yves@eisfair.org>
18
19 ARG GITHUB_TOKEN=1234567
20 ARG RELEASE=latest
21 ARG REPOSITORY=cmake build test
22 ARG GIT_COMMIT=unknown
23 ARG REPLACE_EXISTING_ARCHIVE=''
24 ENV ARCHIVE=cmake-buildtest-${RELEASE}-${GIT_COMMIT}-Debian.tgz
25
26 RUN mkdir -p /filesToUpload/usr/local/bin
27
28 # Maybe copy more from the builder...
29 COPY --from=build /demo-app/build/hello-world /filesToUpload/usr/local/bin/hello-world
30
31 RUN cd /filesToUpload \
32  && tar czf ${ARCHIVE} . \
33  && github-release upload \
34         --user starwarsfan \
35         --security-token "${GITHUB_TOKEN}" \
36         --repo "${REPOSITORY}" \
37         --tag "${RELEASE}" \
38         --name "${ARCHIVE}" \
39         --file "/filesToUpload/${ARCHIVE}" \
40         ${REPLACE_EXISTING_ARCHIVE} \
41  && export GITHUB_TOKEN=---

The exciting part is now to build the project Jenkinsfile as efficiently as possible. In practice, you will notice features that you would need to redefine in almost every Jenkinsfile. It is much more efficient to outsource these to separate pipeline functions and make them available globally in Jenkins. This means you only need to maintain the code in one place, and all pipelines benefit.

Help Functions for Release Handling

The github-release tool as a Docker image provides valuable services for handling releases on GitHub that simplify many tasks, but the functions can be further encapsulated. As an example, I'll look at the approach in the jenkins-pipeline-helper [13] repository. The github-release functions are encapsulated as pipeline functions and can be called directly by name within the pipeline. The Jenkinsfile for creating a GitHub release is shown in Listing 5. As a gimmick, the release functions can process two different variants of the release description.

Listing 5

Jenkinsfile Snippet to Create a GitHub Release

01 script {
02         createRelease(
03           user: "${GITHUB_ACCOUNT}",
04           repository: "${GITHUB_REPOSITORY}",
05           tag: "${GIT_TAG_TO_USE}",
06           name: "${RELEASE_NAME}",
07           description: "${RELEASE_DESCRIPTION}",
08           preRelease: "${PRERELEASE}"
09         )
10 }

If you populate the description parameter with some text, your Jenkins will use this text as the release description. The Develop builds are only given a build number:

RELEASE_DESCRIPTION = "Build ${BUILD_NUMBER}"

However, if you pass in a file name, its content will be used. This is the case in the example with the builds from the Master branch:

RELEASE_DESCRIPTION = "${WORKSPACE}/Releasenotes.md"

Specifically, it causes the tool chain to publish the release notes automatically on GitHub with every release build.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus