Game Tech Tutorial
Published in

Game Tech Tutorial

How to Setup CI/CD Pipeline with Jenkins and Unity Test Runner? (Complete Tutorial)

Continuous Integration and Deployment allow you to have fewer bugs in games to increase your productivity.

With CI/CD, you not only can ensure the game code’s stability in every deployment phase but also can release games on time and within budget. In other words, you won't waste too much time in testing, so you can focus on creating interesting features to attract players.

However, it’s hard to find a complete tutorial to build CI/CD pipelines with Jenkins and Unity Test Runner.

This tutorial will guide you to set up your own CI/CD pipelines on Jenkins with Unity Test Runner from the ground up to improve your work efficiency.

Outline

  • Install and Setup Jenkins
  • Create Test Runner cases in Unity
  • Setup Slack Message for Jenkins’s pipeline
  • Create a webhook in Github to notify Jenkins
  • Create a PR pipeline to build Android
  • Create a PR pipeline to build iOS
  • Summary

Getting Started

Environment:

  • Mac OS
  • Jenkins
  • Unity v2020.3.15f2

Install and Setup Jenkins

Run

brew install jenkins-lts

Note:

We are not going to use any plugins or 3-Party lib like fastlane to build ios and android because this is easy to debug and learn as a starting porint. And you can fully control to diagnose any error in conolse.

Of course, you can use fastlane in pipeline when needed.

Create Test Runner cases in Unity

  • Goto your game project’s folder
  • Create tests folder under Assets folder as /Assets/Tests/PlayMode
  • Create PlayMode.asmdef

Goto your folder → Right Click Mouse → Create → Assembly definition
→ Create PlayMode.asmdef and place it in /Assets/Tests/PlayMode

Setup PlayMode.asmdef as below

  • Check Override References
  • Add UnityEditor.TestRunner and UnityEngine.TestRunner to Assembly Definition References.
  • Add nunit.framework.dll to Assembly References
  • Then press Apply Button

Then we will create a Unity Test Runner case as TestGame.cs in /Assets/Tests/PlayMode

TestGame.cs

using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UI;
namespace TestGame
{
public class PlayModeTestGame
{
bool clicked = false;
[SetUp]
public void SetUp()
{
// Modify this with your first scene in the game UnityEngine.SceneManagement.SceneManager.LoadScene("<Your Game Scene>");
}
[UnityTest]
public IEnumerator TestMenu()
{
var gameObject = new GameObject();
string name = "start"; // Your Button Name
GameObject startButton = GameObject.Find(name);
Assert.NotNull(startButton);
var setupButton = startButton.GetComponent<Button>();
setupButton.onClick.AddListener(Clicked);
setupButton.onClick.Invoke();
Assert.IsTrue(clicked);
yield return new WaitForSeconds(2);
}private void Clicked()
{
clicked = true;
}
}
}

Note:

  • This test case shows how to load your first game scene and validate a start button.
  • This can detect some potential bugs and ensure your game can be properly built and played when adding 3-Party libs or new features.
  • Remember you need to create test cases under /Assets/Test/PlayMode folder

Test Your Unit Test

  • Open Unity → Windows → General → Test Runner → Click PlayMode → Click Run All
  • If it is fine, you will see below

Next, we expect Jenkins can run the test case when making any changes in a PR.

Let’s start to set up this pipeline.

Setup Slack Message for Jenkins’s pipeline

Since we will integrate Slack messages in the pipeline, we can always be notified by the latest status via the slack message.

  • Log in Jenkins Web Admin → Manage Jenkins → Click Plugin Manager → Click Available → Find and install Slack Notification
  • Go to Manage Jenkins → Configure System → Slack

Fill in the following

  • Workspace: <Your Slack Work Space >
  • Credential: <Add Your Slack Access Token>
  • Default channel: <Default Slack channel ID ex: #test>

Click Test Connection to check status

Next, we need to create a pipeline to check PR when someone pushes any changes to the source codes. At this moment, this actually will trigger a webhook to notify Jenkins’s pipeline.

Let’s set up the webhook for the PR pipeline.

Create a webhook in Github to notify Jenkins

  • Go to your Github → Settings → Create a webhook
  • Setup Payload URL

Payload URL:

http://<user name>:<API Token>@<Jenkins IP>:<Jenkins Port>/job/<Your PR Pipeline Name>/buildWith Parameters?token=<your_toke_name>

Example:

http://test-user:1143acc4dd35ceeb678d213162565fb123@192.168.1.1:9001/job/my-pr/buildWithParameters? token=mytoken
  • Select application/x-www-form-urlencoded
  • Then Check Let me Select individual events → Select PR → Click Active

Note:

  • Your Jenkins Server should set up IP while list to only allow accesses from Github’s IPs.
  • By this setting, whenever someone makes a PR to your source codes, Github will notify your Jenkins via a webhook.
  • Your PR pipeline needs to parse this webhook and execute CI/CD flows.

Note:

Our pipelines need customized functions to build Android or iOS in Unity.

Remember that you need to download BuilderUtility.cs and place it in your project’s Editor folder for setting up pipelines.

Create a PR pipeline to build Android

This pipeline will run test cases and build games for Android when making any changes in PR.

  • Log in to Jenkins Web Admin → Select Pipeline
  • Check Do not allow current builds and
    The project is parameterized (Multi-line String Parameter)

Fill in the following

  • Name: payload
    Default Value: Copy the following
{
"pull_request": {
"number": 1,
"state": "closed",
"head": {
"ref": "feature/test-pr"
}
}
}

Let’s start to create a PR pipeline.

Modify Pipeline name, Machine’s user Name, Github URL, and Unity Version.

// Pipeline name
def jobName="your-game-pr"
// Machine's user Name
def machine_user_name="your_user_name"
// Your Github URL
def build_repo="git@github.com:gcoolmaneric/jenkins-game-ci.git"
// Your Unity Version
// Ex: "2020.1.15f2"
def unity_version="<Your unity verison>"
// Distributed URL via https://distribution.com
def DEPLOY_URL=""
// deploy_gate_token
def deploy_gate_token="<deploy_gate_token>"
// deploy_gate_upload url
def deploy_gate_upload_url="https://deploygate.com/api/users/<deploy_group_name>/apps"

Note:

  • We use deploygate.com to distribute apk or ipa files as an example.
  • You can comment out deploy_gate_token and deploy_gate_upload and use other services like AWS S3 instead.

First, we need to understand the following functions in the pipeline.

Function: parseJSON is used to parse request payload from Github’s webhook when making any change in PR.

Function: sendSlackMessage can send messages to Slack Channel for reporting any changes.

Then we start to write the pipeline.

1. Initial environment parameters

  • app_mode: build Android in mono or IL2CPP

Note

  • building Android in IL2CPP will take nearly 10 mins while mono is much faster.
  • You can set up mono mode for development while IL2CPP for QA.

2. Clean up workspace and clone branch

Note:

  • Clone Branch: — depth 1 means we only clone the latest commit.
  • This can improve the performance without downloading all the Github history.

3. Run Test cases in Unity Test Runner

  • This command will run test cases in PlayMode.

Note

  • -testPlatform PlayMode: run test case in PlayMode
  • -nographics: not open Unity Editor

4. Build Android in mono or IL2CPP

Note:

  • -batchmode: run in barchmode
  • -projectPath: set up project path
  • -buildTarget: build platform as Android or iOS
  • -executeMethod: execute customized function (ex:BuilderUtility.BuildMonoAndroid )
  • You can find the function BuildMonoAndroid in BuilderUtility.cs.

5. Upload App to the Cloud

Note:

  • This stage can upload the Android’s apk file to the cloud for distributing games.
  • If successful, get the uploaded URL from the console and send it to slack channel.
  • This stage is optional and you can upload to other clouds like Amazon S3.

Lastly, Uncheck Use Groovy Sandbox.

Create a PR pipeline to build iOS

This pipeline is as same as the previous one, so you can copy the previous pipeline and update the following.

Summary

Congratulations! You have learned how to create Test cases in Unity Test Runner and set up CI/CD pipelines to build games for Android or iOS.

You can download the PR pipeline here for reference.

I hope this tutorial will be helpful for you to save time building CI/CD pipeline to speed up your workflow.

Thanks for reading.

Next, you can refer below to set up Jenkins with high availability and scalability when needed.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Eric Wei

Eric Wei

Senior Full Stack Engineer & Solution architecture | AWS, GCP, Azure | Cloud, Unity Game Development, SDK, DevOps, and more.