Unity has been using Katana over the years for continuous integration (CI). Katana is used for building the releases and running all our internal test suites before we ship a release to you. It’s been working well for a number of years since most of Unity was in the same mercurial repository.
Whenever anyone at Unity wanted to run the editor, it was then possible to either:
All three available solutions were covering our internal needs very well until recently.
Then, we decided to evolve and start using packages. More and more of Unity features are being moved from the main Unity repository and stored into separate packages repositories. This has allowed us to speed up the delivery process and help take some Unity features and extensions to the next level. It was also a much-needed step on our roadmap to DOTS.
But like any transition, this new technical paradigm came with a set of challenges.
We, of course, wanted to be able to verify and publish these packages and make sure that each of them would play nicely with the different editor versions, and satisfy our internal quality requirements. Packages have their own repositories with a new CI system running on them.
For a package’s CI to be successful, the most important thing is its main dependency: the Unity Editor. We have had no seamless and unified way for the package CI to request a specific Editor build.
So last year we ended up with a lot of the package repos having their own custom way of grabbing the editor. Some of them ended up running CI on physical machines that would just have the editor permanently installed on them with hard-coded paths to each version needed.
Others created custom tools which would trigger Katana builds and download them to the CI machines.
All the solutions were quite hacky and not particularly generic.
So a couple of us sat down at the start of September 2018, using our 20% time that we get in R&D for freeform experimentation, which is also known as Fridays Are For Fun, and set about to try and create a generic way of getting editors for CI that would work for as many people as possible.
And thus, a couple of weeks later, the Unity Downloader was born.
The Unity Downloader is a command-line tool made in Python.
It allows our employees to download any editor (5.0+) for MacOS, Windows and Linux with any combination of components (WebGL, Android, etc).
The Unity Downloader supports this for any Unity version, branch and revision we have.
It’s obviously not just as simple as that, there is some heavy lifting going on in the background that you can’t see, like:
So basically the downloader is a combination of these things:
With all this in place, we could now suddenly run CI on ephemeral VMs which get destroyed and recreated in a clean state after a job ends.
It also easily lets our teams set up their package CI and run it against any supported Unity version they want to test against.
If they need to do a bug fix in the editor itself for their package and ensure it will work in their package CI when it lands, then they can easily tell CI to run using that branch by modifying the Unity Downloader command line to something like this:
The flow for the above request would be as follows, behind the scenes:
That’s a simplified version of what it is and does.
All internal package CI is now using the unity downloader in some way. Most of our package repo owners don’t know about this since it’s seamlessly handled by our CI tooling to invoke the downloader before it starts building and running tests. The repo owners only need to indicate what version or branch they want and they get it.
Some statistics for the month of May 2019 is:
In total 300,000 files downloaded since we started using metrics in November.
The graph shows the peaks and valleys of usage throughout a month. You can easily see the nightly jobs we have in CI (peaks) and the weekend lull (flat sections).
So for CI, the use case is pretty obvious. However, a significant chunk of the traffic is coming from actual humans. Some of us have augmented our workflows heavily around its usage.
One situation that the Unity Downloader has been useful for is when tracking down causes of bugs by means of bisection. Since we already tend to find out which published Unity version a bug was introduced in we can trivially get the range of revisions between when it was introduced and the release preceding it. With the Unity Downloader, you can then upfront trigger building as many intermediate revisions as your conscience will allow with something like this.
Setting the --skip-download flag and omitting the -- wait flag is the quickest way of just making sure that things are cached and builds are triggered. So a quick succession of those calls will ensure anything that hasn’t been built will be triggered. That ensures that as the bisection progresses after the first couple of revisions tested, the remaining ones are most likely built and ready for download. Doing this in a more traditional sense and building each revision locally would be a very time-consuming task.
Another scenario is to quickly test a Unity project locally. To download the Editor for the project and launch it, I can just do the following:
Which will get the exact editor revision the project was made for and won’t end up triggering the script updater and so on.
So, given that it is now widely used in our automation and has helped our own workflows, I would say it has been a success so far.
However, as with all solutions concocted in a couple of weeks, there are some issues with the design of the system which causes problems.
These problems are mainly:
Now that the Unity Downloader has reached enough maturity to be widely used internally (especially in CI), we would like to investigate options for making it available for Unity users. It improved our workflows a lot, and we’re confident that it could play a role in helping solve other problems, both internally and externally.
The plan is, over the next weeks and months, to do a complete refactoring of the Unity Downloader.
So with that in mind, and with all the lessons learned along the way, we would like to take a step back and take a moment to involve our users, in order to make the new version of the tool more fit for external needs in case we find a way to expand its usage.
To make sure that the new Unity Downloader fits the needs of our users, especially regarding CI, we would love to get some feedback from you all.
Do you feel like you would have a need for being able to download any or all published editor versions from a terminal of your choice?
Do you have your own CI solution where this might come in handy, and if so then what technical requirements might you have to make it viable for you?
Even if you don’t see yourself using it we would like to know why you think you wouldn’t.
Is this article helpful for you?
Thank you for your feedback!