Building with the Unity Jenkins Pipeline
The Unity Jenkins Pipeline (UJP) is a collection of tools and services built to enhance the your development experience. With proper configuration, your development team can leverage the offerings of UJP to:
- Improve build time
- Automate testing
- Simplify quality assurance (QA) processes
- Quickly deliver builds to the Google Play Store and/or Apple App Store
If you are interested in using the UJP, please contact your Big Fish producer to start the UPJ onboarding process. Big Fish Games will meet with you to discuss your needs, begin the internal backend setup, and grant your team access to the appropriate shared, managed resources.
Phases of the UJP
The UJP is broken down into four phases:
- The Build phase kicks off new builds of your game in response to specified triggers
- In the Planning phase, the game project and build settings are cloned
- In the Execution phase, your project is built, signed, and tested
- In the Reporting phase, you will receive a summary of the build and relevant test results
Build Phase
During the Build phase, the UJP is initialized through triggers from any of the following sources:
- Webhooks: Sends an HTTP request to one of the BFG endpoints. A build is triggered when an HTTP request is received. Contact your Big Fish producer to obtain an API key for this trigger.
- Scheduled Jobs: Triggers a build of the game on a fixed schedule, from once a day or a few times a week depending on the team's needs.
- Source Control Management (SCM) Events: Triggers a build when changes are made to the game's GitHub repository. Changes can be tracked through webhook integrations on pull requests or through SCM polling that scans the repository for changes on specific branches.
Planning Phase
In the Planning phase, the UJP begins by cloning the game project from the repository. When it detects a build trigger, it will collect the build settings from three different sources:
- Basic information of the game, such as the name, commit to build, type of build, etc.
- The internal game systems and data owned and maintained by Big Fish
- The configuration file maintained by the game team that contains information on how the game is built
With the above sources, the UJP can determine what CLI invocation is necessary to build your Unity projects along with the build steps needed, such as an Xcode or Gradle build. UJP can also determine if the game should be built using your production or testing backend, instrumented for test automation and sent to BitBar, and if the game should be published to a test utility such as AppCenter, or a first-party system such as TestFlight.
Execution Phase
The Execution phase builds, signs, tests and releases your game files. In this process, the UJP performs the following steps:
- Builds and signs the iOS distribution
- Builds and signs the Android distribution
- Archives the build artifacts in a S3-backed repository
- Releases to a specified user group in AppCenter
- Performs static code analysis with SonarQube
- Tests metadata for production builds
- Does a secondary build for test automation with AltTester and BitBar
- Uploads assets to Content Delivery Network (CDN). Only Google Cloud Platform (GCP) is supported
Reporting Phase
The Reporting phase creates a summary of the entire UJP process to the game's dedicated Slack channel in the Big Fish Games workspace. This summary is also added to the pull requests within the game's repository, and uploaded to Big Fish's archive which is kept for troubleshooting and triage purposes.
Getting Started with the UJP
To use the UJP, ensure you have the following game details available:
- App ID or Bundle Identifier for the game, for each platform supported
- Display name of the game, which is the name that shows up on devices after installation
- The Unity project, stored in a Git repository, the C# methods used to build the project, and the directory where artifacts and exported projects are stored
- Information on the CDN distribution of Unity-built assets, including their location within the project and the directory structure of the uploaded asset bundle
- Note: Currently, the only CDN supported by Big Fish is GCP. Contact your Big Fish producer if you require the use of any other CDN.
- Unique Device Identifier (UDID) for any physical iOS devices owned by developers or testers to to test the game
Source Control Access
The UJP requires access to the game project's repository. To provide access, create an SSH
key that can be used to clone the game's project in the UJP.
If the game uses GitHub, Big Fish Games recommends using Deploy Keys ↗️.
Game Project Setup
The UJP supports four build configurations: Dev, Test, Stage, and Prod. Benefits of using multiple build configurations include:
- Game versioning to test against different backend environments
- Enabling cheats for testing game features
- Embedding debugging tools for live test results
To use the build features of the UJP, the game must expose a public method to accept parameters from command line or environment variables. This allows the UJP to compile and sign the builds. Use Unity's batchmode directive to accomplish this.
The UJP requires different build parameters for Android and iOS platforms. When Unity builds the game for iOS, it exports an Xcode project that must be built and signed in Xcode. You will need to know the relative path to that project when creating the configuration file.
For Android, you can produce an app for game in one of two ways: either via a fully built .aab
file, or through an exported Gradle or Android Studio project that is built separately.
The following table lists the available build parameters:
Type | KEY | Description | Required? | Dependencies |
---|---|---|---|---|
string | REPO | The Git repository containing the Unity project | Required | |
string | BRANCH | The branch of the above Git repository to checkout | Required | |
bool | DEV | Build using DEV configuration | One of these is required | |
bool | QA | Build using QA configuration | ||
bool | STAGE | Build using STAGE configuration | ||
bool | PROD | Build using PROD configuration | ||
bool | APPLE | Build for Apple App Store | One of these is required | |
bool | GOOGLE | Build for Google Play Store | ||
bool | ENTERPRISE | (Apple only) Sign Using the Enterprise Certificate | Optional | APPLE = true |
bool | APPLESTORE | (PROD + APPLE only) Upload to Apple App Store | Optional | APPLE = true |
bool | GOOGLESTORE | (PROD + GOOGLE only) Upload to Google Play Store | Optional | APPLE = true |
bool | ALTTESTER | Instrument the binary for use with AltTester | Optional | |
bool | runAndroidTests | (ALTTESTER only) Run BitBar tests against AltTester binary - Android | Optional | GOOGLE = true |
bool | runIOSTests | (ALTTESTER only) Run BitBar tests against AltTester binary - iOS | Optional | APPLE = true |
bool | SFVT | (PROD only) Check app metadata with Settings File Verification Tool | Optional (Required for PROD) | PROD = true |
bool | SONARQUBE | Run SonarQube scan before building | Optional | |
bool | CNDUPLOAD | Upload content to the GCP Bucket | Optional |
Configuration File Setup
The UJP requires a configuration file that contains information on how the game is built. This file must be named jenkins.json
.
To setup the jenkins.json
configuration file:
- Navigate to the base directory of the game's repository.
- Create a folder named
ci
, then open the newly created folder. - Create a
.json
file namedjenkins.json
. - Copy the following code into the file:
{
"about": "This is the configuration file for BFG Cloud Jenkins",
"appDisplayName" : "",
"buildOutputDirAmazon" : "",
"buildOutputDirApple" : "",
"buildOutputDirGoogle" : "",
"bundleIdAmazon" : "",
"bundleIdApple" : "",
"bundleIdGoogle" : "",
"customAppManifests" : [
{
"filePath": "",
"contents": {}
}
],
"customArtifacts": [
],
"customEnv": {},
"gcpFrom": {
"dev" : "",
"qa" : "",
"stage" : "",
"prod" : ""
},
"unityProjectCustomPath": "",
"unityAmazonExecuteMethod" : [""],
"unityAppleExecuteMethod" : [""],
"unityGoogleExecuteMethod" : [""],
"unityCustomParams" : "",
"unityParamSets" : {
"dev" : "",
"qa": "",
"stage": "",
"prod" : ""
},
"unityBuildUsingGradle" : ""
}
The following table describes each of the values in the jenkins.json
configuration file. Note that all paths are relative to the root of the git repository.
Key | Type | Description | Required |
---|---|---|---|
about | String | A basic description of the configuration file | Optional |
appDisplayName | String | The name of the App, displayed in the OS after installation | Required |
buildOutputDirAmazon | String | Path to the Unity output when building Amazon FireOS apps | Required if building for FireOS |
buildOutputDirApple | String | Relative path to the exported Xcode project produced by the Unity build | Required |
buildOutputDirGoogle | String | Path to the Unity output when building Google Android apps | Required |
bundleIdAmazon | String | Bundle Identifier / App Identifier for FireOS builds of the game | Required if building for FireOS |
bundleIdApple | String | Bundle Identifier / App Identifier for iOS builds of the game | Required |
bundleIdGoogle | String | Bundle Identifier / App Identifier for Android builds of the game | Required |
customAppManifests | Array | An array of JSON objects, containing filePath and contents, which directs the Jenkins pipeline to create JSON files in the Unity project | Optional |
customArtifacts | Array | A string array of paths (and/or blobs) to be archived alongside the binaries. A trailing / indicates a dir to be zipped before the archive (any/all that match the pattern). | Optional |
customEnv | List | JSON object | Optional |
gcpFrom | Array | The folder to upload to GCS | Optional |
gradleOutDir | Array | The build output directories of Gradle | Required if using Gradle |
unityAmazonExecuteMethod | Array | Array of methods to be executed by Unity during Amazon FireOS builds | Required if building for FireOS |
unityAppleExecuteMethod | Array | Array of methods to be executed by Unity during Apple iOS builds | Required |
unityGoogleExecuteMethod | Array | Array of methods to be executed by Unity during Google Android builds | Required |
unityBuildUsingGradle | Boolean | Set to "true" if a separate Gradle process must be run after the Unity build completes (you are exporting a project to build) | Required |
unityCustomParams | Boolean | Set to "true" if the Unity batchmode commands require custom parameters | Required |
unityParamSets | List | List of custom parameters to be used in Unity batchmode commands, sorted by build configuration | Optional |
unityProjectCustomPath | String | If the Unity project is embedded in a subdirectory of the Git repository, the relative path should be listed here | Optional |
Test Automation
Big Fish Games offers test automation with AltTester and BitBar. For more information on the setup of AltTester with UJP, see Onboarding Test Automation.
Distribution
When you are ready to distribute your game to the app store(s), reach out to your Big Fish producer to kick off the process. From there, the Big Fish release management team will configure the app store listings for both Android and iOS, as well as any iOS provisioning profiles and authorized iOS devices.
When the appropriate parameters are passed through the job trigger, the UJP will automatically upload the game to the Google Play Store Internal Test Track (Android) and/or App Store Connect's TestFlight (iOS).
Big Fish Games does not support automated distribution to Amazon's app store.
Custom Build Settings
Games often use custom build settings to control build tooling that includes:
- String Parsing and Pseudo-Markup
- Custom App Manifests
- Custom Environments
- Parameter Sets
The UJP can incorporate these custom build settings into your game build(s).
String Parsing and Pseudo-Markup
The UJP is capable of reading values and replacing strings with build-time data. This is particularly helpful during testing and triage. When the strings are found in the game configuration file, the UJP will replace them as shown in the table below:
String | Output |
---|---|
!target! | Android or iOS, depending on which is being built at the time. |
!git_sha! | A 6-digit hash (short-form) representing the Git commit being cloned and built. |
!build_number! | The current Jenkins build number. This increases every time Unity Jenkins Pipeline is run. |
If your team requires additional information that is only available at the time of build of the game, contact the Big Fish build automation team.
Custom App Manifests
A Unity project often requires that certain .json
files exist before the game can be built due to version information or dependency manifests. If a file cannot be checked into version control alongside the project, or if it contains data that must be updated at the time of build, the UJP can create the file before building.
For the UJP to create the file, the customAppManifests
block must be populated in the ci/jenkins.json
configuration file. Below is an example that tells the pipeline to write the current Git SHA
and Jenkins build number to the manifest.json
.
"customAppManifests" : [
{
"filePath": "manifest.json",
"contents": { "commit" : "!git_sha!", "build_number" : "!build_number!", "baz" : "value" }
}
]
Custom Environments
Sometimes the Unity build tools for your game are affected by environment variables. If your game requires specific environment variables to produce correct results, you can provide the UJP with the necessary variables required.
To provide Unity Jenkins Pipeline with the proper environment variables:
- Navigate to the
ci
folder and open thejenkins.json
file. - Expand the
customEnv
object. - Populate the object with arrays associated with the available build configurations.
In the example below, all environments have RELEASE_BUILD
explicitly set to false
, except when building against the PROD
configuration.
"customEnv" : {
"DEV": {
"RELEASE_BUILD": false
},
"QA": {
"RELEASE_BUILD": false
},
"STAGE": {
"RELEASE_BUILD": false
},
"PROD": {
"RELEASE_BUILD": true
}
}
Parameter Sets
When the game's build parameters are controlled by CLI options, custom sets of parameters can be set. To set up a custom set of parameters:
- Navigate to the
ci
folder and open thejenkins.json
file. - Set the
unityCustomParams
to"true"
. - Create a new object that associates build configurations (Dev, QA, Stage, or Prod) with the set of custom parameters required.
In the example below, the same build method is supplemented with -target
, -buildType
, and -shorthash
arguments that are different for each environment.
"unityCustomParams" : "true",
"unityParamSets" : {
"dev" : "-target !target! -buildType development -shorthash !git_sha! -devOnlyOption true",
"prod" : "-target !target! -buildType prodution -shorthash !git_sha! -prodOnlyOption true"
},