Skip to main content
Version: v2

Builder

Building the project as part of a workflow may help to create mind-space and focus on the project itself.

Use Unity - Builder to automatically build Unity projects for different platforms.

Basic setup

Credentials

Make sure you have set up these variables in the activation step:

  • UNITY_EMAIL (the email address for your Unity account)
  • UNITY_PASSWORD (the password that you use to login to Unity)

NOTE: Issues have been observed when using a UNITY_PASSWORD with special characters. It is recommended to use a password without any special characters (mixed-case alphanumeric characters only).

GameCI does not acquire nor store your Unity email or password. They are required for reactivating the license during build and test steps.

Workflow file setup

Create or edit the file called .github/workflows/main.yml and add a job to it.

Personal license

Personal licenses require a one-time manual activation step.

Make sure you acquire and activate your license file and add it as a secret.

Then, define the build step as follows:

- uses: game-ci/unity-builder@v2
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
targetPlatform: WebGL

Professional license

Make sure you have set up these variables in the activation step:

  • UNITY_EMAIL (should contain the email address for your Unity account)
  • UNITY_PASSWORD (the password that you use to login to Unity)
  • UNITY_SERIAL (the serial provided by Unity)

Then, define the build step as follows:

- uses: game-ci/unity-builder@v2
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
with:
targetPlatform: WebGL

License Server

If you host your own Unity license server internally you can provide its url using unityLicensingServer. A floating license will be acquired before the build, and returned after.

Example of use:

- uses: game-ci/unity-builder@v2
with:
targetPlatform: WebGL
unityLicensingServer: [url to your license server]

That is all you need to build your project.

By default, the enabled scenes from the project's settings will be built.

Storing the build

To be able to access your built files, they need to be uploaded as artifacts. To do this it is recommended to use Github Actions official upload artifact action after any build action.

By default, Builder outputs it's builds to a folder named build.

Example:

- uses: actions/upload-artifact@v2
with:
name: Build
path: build

Builds can now be downloaded as Artifacts in the Actions tab.

Caching

In order to make builds run faster, you can cache Library files from previous builds. To do so simply add Github Actions official cache action before any unity steps.

Example:

- uses: actions/cache@v2
with:
path: path/to/your/project/Library
key: Library-MyProjectName-TargetPlatform
restore-keys: |
Library-MyProjectName-
Library-

This simple addition could speed up your build by more than 50%.

Configuration options

Below options can be specified under with: for the unity-builder action.

targetPlatform

Platform that the build should target.

Must be one of the allowed values listed in the Unity scripting manual.

required: true

unityVersion

Version of Unity to use for building the project. Use "auto" to get from your ProjectSettings/ProjectVersion.txt

required: false default: auto

customImage

Specific docker image that should be used for building the project.

- uses: game-ci/unity-builder@v2
with:
customImage: 'unityci/editor:2020.1.14f1-base-0'

required: false default: ""

projectPath

Specify the path to your Unity project to be built. The path should be relative to the root of your project.

required: false default: <your project root>

buildName

Name of the build. Also the folder in which the build will be stored within buildsPath.

required: false default: <build_target>

buildsPath

Path where the builds should be stored.

In this folder a folder will be created for every targetPlatform.

required: false default: build

buildMethod

Custom command to run your build.

There are two conditions for a custom buildMethod:

  • Must reference a valid path to a static method.
  • The class must reside in the Assets/Editor directory (or in an Editor Assembly).

Example:

- uses: game-ci/unity-builder@v2
with:
buildMethod: EditorNamespace.BuilderClassName.StaticBuildMethod

To get started with a modified version of the default Unity Builder build script, you can copy BuildScript.cs to your Assets/Editor/UnityBuilderAction directory and reference it:

- uses: game-ci/unity-builder@v2
with:
buildMethod: UnityBuilderAction.BuildScript.Build

If you need to pass custom parameters to this build method, see customParameters below.

required: false default: Built-in script that will run a build out of the box.

customParameters

Custom parameters to configure the build.

Parameters must start with a hyphen (-) and may be followed by a value (without hyphen).

Parameters without a value will be considered booleans (with a value of true).

- uses: game-ci/unity-builder@v2
with:
customParameters: -profile SomeProfile -someBoolean -someValue exampleValue

There are 2 main use cases:

  • To pass your own custom parameters to be used with buildMethod above
  • To pass Unity Build Options (for example, customParameters: -standaloneBuildSubtarget Server will do server builds)

required: false default: ""

versioning

Configure a specific versioning strategy

- uses: game-ci/unity-builder@v2
with:
versioning: Semantic

Find the available strategies below:

Semantic

Versioning out of the box! (recommended)

Compatible with all platforms. Does not modify your repository. Requires zero configuration.

How it works:

Generates a version based on semantic versioning. Follows <major>.<minor>.<patch> for example 0.17.2. The latest tag dictates <major>.<minor> (defaults to 0.0 for no tag). The number of commits (since the last tag, if any) is used for <patch>. To increment major or minor version, manually add a tag to a commit that follows the <major>.<minor> versioning convention. Optionally, the version number can have a v prefix, for example v0.17.

No configuration required.

Tag

Generates the version based on the git tag of the latest commit (HEAD). For example 0.17.2 will generate the version 0.17.2. A leading "v" is stripped, so a version of v1.3.3 will generate a version of 1.3.3. (advanced users)

Compatible with all platforms. Does not modify your repository.

Custom

Allows specifying a custom version in the version field. (advanced users)

This strategy is useful when your project or pipeline has some kind of orchestration that determines the versions.

None

No version will be set by Builder. (not recommended)

Not recommended unless you generate a new version in a pre-commit hook. Manually setting versions is error-prone.

androidVersionCode

Configure the android versionCode.

When not specified, the version code is generated from the version using the major * 1000000 + minor * 1000 + patch scheme;

androidAppBundle

Set this flag to true to build '.aab' instead of '.apk'.

- uses: game-ci/unity-builder@v2
with:
androidAppBundle: true
androidKeystoreName: user.keystore
androidKeystoreBase64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
androidKeystorePass: ${{ secrets.ANDROID_KEYSTORE_PASS }}
androidKeyaliasName: ${{ secrets.ANDROID_KEYALIAS_NAME }}
androidKeyaliasPass: ${{ secrets.ANDROID_KEYALIAS_PASS }}

You should also set all the Android Keystore options (see below). Refer to this section for keystore setup.

required: false default: false

androidKeystoreName

Configure the android keystoreName. Must be provided if configuring the below keystore options.

For this to take effect, you must enable Custom Keystore in your Android Player settings. The default build script overrides the other keystore settings with these keystore options.

required: false default: ""

androidKeystoreBase64

Configure the base64 contents of the android keystore file. You should get this with base64 $androidKeystoreName

The contents will be decoded from base64 using echo $androidKeystoreBase64 | base64 --decode > $projectPath/$androidKeystoreName

It is recommended to use GitHub Secrets.

required: false default: ""

androidKeystorePass

Configure the android keystorePass. Recommended to use GitHub Secrets.

required: false default: ""

androidKeyaliasName

Configure the android keyaliasName. Recommended to use GitHub Secrets.

required: false default: ""

androidKeyaliasPass

Configure the android keyaliasPass. Recommended to use GitHub Secrets.

required: false default: ""

androidTargetSdkVersion

Configure the android target API level. If used, must be one of Unity's AndroidSdkVersions.

required: false default: ""

sshAgent

SSH Agent path to forward to the container.

This is useful if your manifest has a dependency on a private GitHub repo.

required: false default: ""

gitPrivateToken

Github private token to pull from github.

This is useful if your manifest has a dependency on a private GitHub repo.

required: false default: ""

chownFilesTo

User and optionally group (user or user:group or uid:gid) to give ownership of the resulting build artifacts.

required: false default: ""

allowDirtyBuild

Allows the branch of the build to be dirty, and still generate the build.

- uses: game-ci/unity-builder@v2
with:
allowDirtyBuild: true

Note that it is generally bad practice to modify your branch in a CI Pipeline. However there are exceptions where this might be needed. (use with care).

required: false default: false

Outputs

Below are outputs that can be accessed by using ${{ steps.myBuildStep.outputs.outputName }}, where myBuildStep is the id of the Builder step, and outputName is the name of the output.

buildVersion

Returns the version that was generated by Builder, following the strategy configured for versioning.

- uses: game-ci/unity-builder@v2
id: myBuildStep
- run: echo 'Project Version: ${{ steps.myBuildStep.outputs.buildVersion }}'

Private Github repositories

If you use private git repository in your packages/manifest.json, you need to create SSH pub/private keys for your project and then add to the webfactory/ssh-agent

name: 'Add GitHub to the SSH known hosts file'
run: |
mkdir -p -m 0700 /home/runner/.ssh
curl --silent https://api.github.com/meta | jq --raw-output '"github.com "+.ssh_keys[]' >> /home/runner/.ssh/known_hosts
chmod 600 /home/runner/.ssh/known_hosts
  • Finally, add webfactory/ssh-agent to your Github action :
name: Accessing private repos
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: webfactory/ssh-[email protected]
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: game-ci/unity-builder@v2
with:
sshAgent: ${{ env.SSH_AUTH_SOCK }}

UPM authentication using .upmconfig.toml

Unity requires an .upmconfig.toml to exist in the home directory to authenticate and download packages from private UPM registries. To create this file, first create the /home/runner/work/_temp/_github_home directory, and then create the .upmconfig.toml file inside that directory. This action must be done before running the game-ci/unity-builder@v2 action.

- name: Create .upmconfig.toml UPM authentication file
run: |
mkdir /home/runner/work/_temp/_github_home
cd /home/runner/work/_temp/_github_home
echo "[npmAuth.\"https://upm.example.com\"]" >> .upmconfig.toml
echo "alwaysAuth = true" >> .upmconfig.toml
echo "token = \"${{ secrets.NPM_TOKEN }}\"" >> .upmconfig.toml

Complete example

A complete workflow that builds every available platform could look like this:

name: Build project

on: [push, pull_request]

jobs:
buildForAllSupportedPlatforms:
name: Build for ${{ matrix.targetPlatform }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
targetPlatform:
- StandaloneOSX # Build a macOS standalone (Intel 64-bit).
- StandaloneWindows # Build a Windows standalone.
- StandaloneWindows64 # Build a Windows 64-bit standalone.
- StandaloneLinux64 # Build a Linux 64-bit standalone.
- iOS # Build an iOS player.
- Android # Build an Android .apk standalone app.
- WebGL # WebGL.
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
lfs: true
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ matrix.targetPlatform }}
restore-keys: Library-
- if: matrix.targetPlatform == 'Android'
uses: jlumbroso/free-disk-[email protected]
- uses: game-ci/unity-builder@v2
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
targetPlatform: ${{ matrix.targetPlatform }}
- uses: actions/upload-artifact@v3
with:
name: Build-${{ matrix.targetPlatform }}
path: build/${{ matrix.targetPlatform }}

Next steps

You can find more workflow examples in Getting Started.