Using CircleCI to build/test/make unitypackage on Unity

Yoshifumi Kawai
4 min readApr 9, 2019

I develop libraries such as UniRx, MessagePack-CSharp, and MagicOnion, and create a .unitypackage whenever I release one, but I really want to automate the process using CI.

However, Unity Cloud Build is (probably?) restricted from creating .unitypackage, so for now I will use CircleCI. CircleCI is a CI service that I really like, and since all of the CI that I do on .NET Core is done in CircleCI, I think it is better if I use the same service for Unity too. The goals of this procedure are:

  • To create .unitypackage from some of the sources in the repository
  • To perform a UnitTest with Editor
  • To build in IL2CPP/Windows (execute UnitTest IL2CPP ver.)

The Windows build is because we are working in a Windows environment, and since the purpose is to develop libraries, the binary build itself is for testing purposes (we only want to confirm behavior in IL2CPP).

Obtain authentication and operate Unity in CircleCI

CircleCI is operated via container, but the overall flow includes carrying Unity images
and activating them in batchmode to extract results. You should be able to execute appropriate commands while viewing Unity command line arguments.

Fortunately, gableroux has published the container images to be used as the base to gableroux/unity3d/tags, and added helpful tags.

The Unity execution file is in ‘/opt/Unity/Editor/Unity’, so simply input that to ‘-batchmode’ to complete it. However, the greatest barrier is license certification. This is explained in the details of gableroux’s GabLeRoux/unity3d-ci-example, in which the images are published, so you basically only have to follow along with that explanation.

However, the procedures can be made slightly simpler with the current Unity, so examples of simplification are listed here.

First, you must create a license file on the local drive. This is done in the docker image. The image used here must be the same version as the one actually used in CI. If the version is different, the license will have to be remade. You might want to automate this process too, but for now let’s do it manually.

Next, download the image and input Unity to ‘-quit -batchmode -nographics -logFile –createManualActivationFile’, which will result in the creation of content named ‘Unity_v***.alf’ by the base of the XMK license file (without the userid or password, it appears in template form). Then, take this to the host side. It is a simple single file XML, so cat output can be copied & pasted for storage.

Next, open https://license.unity3d.com/manual and upload the alf file above to retrieve the ‘Unity_v2018.x.ulf’ file. This is the essence. You should be logged in to a Unity website during the creation procedure, and the essence of the license file has been created based on the userid/password of your log-in. The contents are XML.

This is important information, so the environment variables in CircleCI should be concealed. However, this is a lengthy XML with multiple lines, so if you copy & paste the contents as they are, the file will be broken at some point, and you will not receive certification. Of course, you shouldn’t upload the file itself to the repository. Encrypt it and add the encrypted file to the repository, and the add the key to the environment variables.

Have ${CIPHER_KEY} replaced with some character string, and also set this to the environment variables of CircleCI. I placed the file in ‘.circleci/Unity_v2018.x.ulf-cipher’ since it is only used in CI.

or use base64 for multiline-key is recommended by CircleCI docs. Encoding Multi-Line Environment Variables, maybe this is better than cipher key.

After this, all that remains is to write the ‘.circleci/config.yml’, and the minimum composition is as follows.

If you use ‘-nographics’ and input it as is, all that’s left is to transfer the license file with ‘-manualLicenseFile’. The specifications use ‘|| exit 0’ as the point for certification, and with the current Unity, exit code 1 is returned even following the regular certification. Therefore, this step can be operated by treating it as being regularly completed compulsively.

Make .unitypackage

In batch mode, a specified static method can be input via ‘-executeMethod’, so the code for making .unitypackage should be prepared with this. Here, use a file like the following one in ‘Editor/PackageExport.cs’.

Next, after receiving license certification with CI, you should just have to enter the command to input this file and the command for storing artifacts.

Perfect!

You should first test the Windows Unity.exe, and then attempt the command. However, there is some difficulty with Windows. The log cannot be output in a standard method; it can only output to %USERPROFILE%\AppData\Local\Unity\Editor\Editor.log. Open Editor.log and reference it closely when making the command.

Execute a UnitTest with the editor

Basically speaking, all that’s required is to add ‘-runEditorTests’, but don’t forget to remove ‘-quit’. If ‘-quit’ is not removed, it won’t run normally.

Specify using ‘editorTestsResultFile’ and store to store_test_results to see the test results in CircleCI.

Or at least that’s what I did, but the overall test surroundings didn’t operate well, so I intend to research more later and fix it…

Build in IL2CPP/Windows

Build with ‘-buildWindows64Player’, and then save it to a .zip for storage.

With this, we have completed everything we wanted to complete for the moment.

The final result will be something like the above.

CircleCI is a very good CI with a lot of flexibility. For Unity builds, machine performance is often an issue, so it’s unclear if this can be used with large-scale
products (on-premises environments via CircleCI Enterprise might be fine). It should function more than well enough for small-scale products. You should try it out for mobile builds, like Android and iOS too!

--

--

Yoshifumi Kawai

a.k.a. neuecc. Creator of UniRx, UniTask, MessagePack for C#, MagicOnion etc. Microsoft MVP for C#. CEO/CTO of Cysharp Inc. Live and work in Tokyo, Japan.