I spent most of the day trying to get these three great tastes to go great together and thought others might find my experience useful. It seems like it should be easy, just follow a few quick steps:
- Install Unity and Jenkins.
- Create a new project in Jenkins that uses the Unity command line.
- Start a build.
After this, hopefully it will be that easy for you!
The first thing I did that was very, very wrong was not restart the machine after install Jenkins. After installation was complete, I just launched Jenkins and started updating it. Unfortunately, that started up a different version than the one that was registered to run when the computer booted up. So restarting will just ensure that you’re working with the correct instance of Jenkins. Now you can set up a project and add your build step to run the Unity command line. (You’ll want to set up your SCM bindings now, too, but that’s beyond the scope of this article.)
It’s possible at this point, everything will be working for you. If not, let’s keep going. So you’ve got your Jenkins project set up and you can run it, but when it executes the Unity command line, the process just hangs forever. It turns out that Unity needs access to some system resources that it can only get if it’s running as the logged in user; we’ll call the logged in user localuser. When you install Jenkins on OS X, it creates a jenkins user. Depending on how you’ve configured it, Jenkins may be running under your user account (localuser) or the jenkins user account. You can’t log in as the jenkins user, though, so that user just won’t work if you want to run Unity. There are two ways to solve this problem. First, you can modify Jenkins to run under localuser. The second is to create a slave on the same machine running under localuser. I investigated the first approach briefly, but the slave approach seemed easier.
Setting up a slave using SSH is surprisingly easy. First, generate keys for both the jenkins user and localuser. You can do this by running ssh-keygen for both users. I prefer RSA encryption, so I run “ssh-keygen -t rsa” once under each user’s account. For both of them, put their keys in the default location and use an empty passphrase. This is not the most secure set up, but Jenkins doesn’t work well with SSH keys that require a passphrase. Now that you’ve got both of your key pairs, you need to make sure both users know each others keys. Assuming you used RSA, each user will have two files in their ~/.ssh directory: id_rsa and id_rsa.pub. Now we need to add each user’s id_rsa.pub into the other user’s list of authorized keys. You can do this on the command line for localuser by running “sudo cat ~/.ssh/id_rsa.pub >> /Users/Shared/jenkins/.ssh/authorized_keys”. This will append the key to the authorized_keys file or create that file if it doesn’t exist. Now do the same thing with the users switched. Now your master and slave can talk to each other!
At this point you should be good to go, but here are a few more tips to help with issues I ran into.
You’ll almost certainly end up passing the path of the working directory to Unity’s command line. If so, that path will include the name of the Jenkins project. If you happened to put a space in your project name, then that path will have one, too. So make sure to keep spaces out of your project names or make sure to put quotes around them.
If you’re using Perforce, installing the P4 command line doesn’t put it anywhere in your path. The easiest thing to do is copy it to a location already in your path like /bin. Alternatively, you can create/modify your /etc/launchd.conf file to set your path to include the location of your P4 executable. Note that the launchd.conf approach will only work in Mountain Lion and later. Earlier versions of OS X use a plist to set environment variables and there are lots of good tutorials that can show you how to set that up.
Hopefully this will help you avoid some of the pitfalls I ran into while setting this up. If you have questions or if anything is unclear, feel free to ask in the comments.