Skip to content

Cloud Builds (Jenkins)

Michalis Kamburelis edited this page Dec 31, 2018 · 20 revisions

We maintain an official Cloud Builds (Jenkins) server.

Table of Contents:

Features Overview

On the server, you can build Castle Game Engine projects in an automated fashion.

The service is completely free for public open-source projects. For closed-source projects, it is available as a reward for supporting CGE on Patreon at a higher tier. We also use it internally, to test CGE itself after every commit.

If you are interested in this, just send an email to Michalis Kamburelis. We will set everything up.

What it does:

  • We automatically rebuild and package your game when you make a commit to SVN or GIT repository. You also get a web access to trigger the build now.

  • We have a ready FPC/Lazarus build environment for Windows 32-bit, Windows 64-bit, Linux 64-bit (x86_64) and Android. The FPC versions can be chosen for each build, any version supported by CGE (like 3.0.2, 3.0.4, fresh 3.3.1) is supported. So you can check whether your software compiles with all FPC versions that matter to you.

  • The builds can use Castle Game Engine latest stable release, or Castle Game Engine bleeding-edge version from GitHub. In the latter case, each commit to CGE will also cause a rebuild of your project, so you always stay current.

  • The builds can be done using CGE build tool. You can also use custom shell scripts, if you know your way around Unix shell scripting. In any case, I will help you set everything up, so don't fear!:)

  • You can browse the build history of your projects, see which commits failed/succeeded to compile, download the packages from each build (latest build, or a historic one), see compilation logs and more. You can also get automatic email notification when a build fails.

  • We can also automatically run tests of your game (e.g. you can use FpcUnit testing framework, built in FPC).

  • We can also automatically generate API docs of your code (using FpDoc or PasDoc), and upload them somewhere.

  • You can run auto-generate-textures command of the build tool. All command-line utilities (used internally by the build tool, e.g. NVidia Texture Tools) are already installed for you.

Using it

Configure and view the job in Jenkins (web view)

Login to https://jenkins.castle-engine.io/ with your username/password.

Notes:

  • For now, there is no automatic registration. Instead just send an email to Michalis Kamburelis with your desired Jenkins username, and I will create it for you. You will receive an automatically generated password (which you can later change from Jenkins yourself).
  • It is best to configure your account such that your username matches the SVN username (if you use SVN) and/or your email matches your GIT email (if you use GIT). This way your commits will be automatically matched to you in Jenkins.

TODO: For now, I will also create a project for you.

In Jenkins, you can configure the project's repository (GIT, SVN) and how often it is checked for modifications, repository credentials (if the project is not publicly accessible) and some more.

TODO screenshot

Note: If your repository is private (not publicly accessible), you will need to input your credentials (username/password to login to SVN/GIT). I advice creating a read-only account for your repository (e.g. called jenkins) for this purpose. For best security, do not use your regular read-write account to get the repository contents inside Jenkins. I do my best to keep this Jenkins installation secure (and we are using this server for various private projects at Cat-astrophe Games, so we really trust it with content that must be secure), but you should follow the rule "reveal as little as possible" anyway.

On the Jenkins page, you can see the statistics about recent builds (how long they took, whether they succeeded) and you can download artifacts of your project. The "artifacts" are just files that you consider the "output" from the build process. In case of CGE games, it is usually a couple of archives like my_game-0.1.0-linux-x86_64.tar.gz, my_game-0.1.0-win32-i386.zip, my_game-0.1.0-win64-x86_64.zip, produced by the build tool package command.

You can also see the logs for each build. If a build compilation failed, these logs will contain the information "why". The logs are the first thing to consult if you want to know what happened (and what failed) during the build.

Configure what commands are executed to do the job (Jenkinsfile)

Specify how to build your project

Place a file named Jenkinsfile (no extension, and case matters!) in the top-level of your repository. Inside, place this content:

pipeline {
  agent { docker { image 'kambi/castle-engine-cloud-builds-tools:cge-stable' } }
  stages {
    stage('Build') {
      steps {
        sh 'castle-engine package --os=linux --cpu=x86_64'
        sh 'castle-engine package --os=win32 --cpu=i386'
        sh 'castle-engine package --os=win64 --cpu=x86_64'
        sh 'castle-engine package --os=android --cpu=arm'
      }
    }
  }
}

Of course, remove the lines for platforms you don't use. E.g. if your game doesn't compile on Android, remove it.

You can also comment out the lines. C-like "star comments" are supported, like /* This is a comment. */.

It is nice split long-running stages into multiple stages. It is also useful to run everything with --verbose inside Jenkins. So a better version of the above example looks like this:

pipeline {
  agent {
    docker {
      image 'kambi/castle-engine-cloud-builds-tools:cge-unstable'
    }
  }
  stages {
    stage('Build Desktop') {
      steps {
        sh 'castle-engine package --os=win64 --cpu=x86_64 --verbose'
        sh 'castle-engine package --os=win32 --cpu=i386 --verbose'
        sh 'castle-engine package --os=linux --cpu=x86_64 --verbose'
      }
    }
    stage('Build Mobile') {
      steps {
        sh 'castle-engine package --os=android --cpu=arm --verbose'
      }
    }
  }
}

Choose Castle Game Engine version (by choosing Docker image)

The image declaration kambi/castle-engine-cloud-builds-tools:cge-stable refers to our Docker image with Castle Game Engine and various tools (FPC, Lazarus, Android SDK and NDK, ...). It defines an environment in which your build will run. You really don't need to be concerned with the details like "what is Docker and how does it work", these are being handled by Jenkins, you only choose a Docker image from 3 possibilities:

  • kambi/castle-engine-cloud-builds-tools:cge-stable - stable CGE version.

  • kambi/castle-engine-cloud-builds-tools:cge-unstable - unstable CGE version (latest code from GitHub).

  • kambi/castle-engine-cloud-builds-tools:cge-none - no CGE inside the container (this is useful for jobs that don't need CGE, or that test CGE itself).

Note: If you use the castle-engine-cloud-builds-tools:cge-unstable image, I can additionally configure the build to run always after Castle Game Engine changed. (Internally, the build of castle_game_engine_update_image will cause a rebuild of your game.) This way after every commit to Castle Game Engine, your game will be also rebuild to use the latest engine.

Choose FPC and Lazarus version

By default, building uses the latest stable FPC version (currently 3.0.4), as advised by CGE. To switch to another FPC/Lazarus version, add a command like source /usr/local/fpclazarus/bin/setup.sh 3.0.2 && ... or source /usr/local/fpclazarus/bin/setup.sh trunk && ... at the beginning of the shell command. Like this:

pipeline {
  agent { docker { image 'castle-engine-cloud-builds-tools:cge-stable' } }
  stages {
    stage('Build') {
      steps {
        sh 'source /usr/local/fpclazarus/bin/setup.sh trunk && castle-engine package --os=linux --cpu=x86_64'
        sh 'source /usr/local/fpclazarus/bin/setup.sh trunk && castle-engine package --os=win32 --cpu=i386'
        sh 'source /usr/local/fpclazarus/bin/setup.sh trunk && castle-engine package --os=win64 --cpu=x86_64'
        sh 'source /usr/local/fpclazarus/bin/setup.sh trunk && castle-engine package --os=android --cpu=arm'
      }
    }
  }
}

As you can see, each build can use a different FPC version, if you want to.

Note that some FPC versions do not support some targets. Right now: FPC 3.0.2 doesn't support Android/ARM.

Email notifications

You can be notified via email when the build fails (e.g. compilation failed) or when it becomes stable again. To do this, add to the Jenkinsfile a section post with this content:

pipeline {
  agent { ... }
  stages { ... }
  post {
    regression {
      mail to: 'michalis.kambi@gmail.com',
        subject: "[jenkins] Build started failing: ${currentBuild.fullDisplayName}",
        body: "See the build details on ${env.BUILD_URL}"
    }
    failure {
      mail to: 'michalis.kambi@gmail.com',
        subject: "[jenkins] Build failed: ${currentBuild.fullDisplayName}",
        body: "See the build details on ${env.BUILD_URL}"
    }
    fixed {
      mail to: 'michalis.kambi@gmail.com',
        subject: "[jenkins] Build is again successfull: ${currentBuild.fullDisplayName}",
        body: "See the build details on ${env.BUILD_URL}"
    }
  }
}

Save the resulting files (archive artifacts)

You usually want to save the build files (artifacts) after a successful build. This allows to download them later using Jenkins web interface. To do this, add to the Jenkinsfile a section post with this content:

pipeline {
  agent { ... }
  stages { ... }
  post {
    success {
      archiveArtifacts artifacts: 'my_game-*.tar.gz,my_game-*zip,my_game-*.apk'
    }
  }
}

As you see, you just trivially list files (using wildcards like *) to consider "artifacts". Remember to replace my_game with the name of your game project.

If you want to archive artifacts, and have email notifications (see the previous section), just combine them both in a single post clause. So post clause will contain subclauses like success, failure and so on. As you can guess, many more possibilities are possible, you can do a lot of things depending on whether a build fails, succeeds and so on.

More ideas for things that can be done

Many, many more possibilities are possible. Jenkins is incredible, IMHO.

  • You can execute any Unix shell script (before, after, or instead of the presented commands). Like this:
pipeline {
  agent { docker { image 'kambi/castle-engine-cloud-builds-tools:cge-stable' } }
  stages {
    stage('Build') {
      steps {
        sh './my_script.sh'
      }
    }
  }
}

And the script inside my_script.sh should be committed in your repository, and could look like this:

#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
# See http://redsymbol.net/articles/unofficial-bash-strict-mode/ for the explanation of 2 lines above.

# Remove previous artifacts
rm -f *.tar.gz *.zip *.apk

# Additional command-line options for the build tool
BUILD_TOOL_DEFINE=--compiler-option=-dJENKINS_COMPILATION

# Build for Windows 64-bit, and Linux 64-bit
castle-engine --os=win64 --cpu=x86_64 $BUILD_TOOL_DEFINE package
castle-engine --os=linux --cpu=x86_64 $BUILD_TOOL_DEFINE package
  • You can build and run your test suite using FPCUnit.

  • You can build API documentation using fpdoc or pasdoc. They are both preinstalled in the image. (TODO: Add pasdoc.)

  • You can run castle-engine auto-generate-textures. The tools to make it work are preinstalled in the image.

The Docker image contains a basic Debian stable installation. It's all executed in a secure Docker container, and will not affect other builds. After each job execution, the environment is cleared, except the files changed/added inside your project directory.

Jenkinsfile examples

We use this approach with all the Castle Game Engine applications. So you can find many Jenkinsfile examples in our repositories. See e.g.

Jenkinsfile documentation

For more information about Jenkinsfile, and Jenkins with Pipeline plugin (which is what is happening here), see

Clone this wiki locally
You can’t perform that action at this time.