Modern programming projects -- commercial ones, anyway -- should use build automation (aka CI/CD). Otherwise there is potential for nasty surprises come QA/release time:
- The person who normally builds a given piece of the final package is away that day and their workstation is locked
- Licenses for certain tools have to be given to everybody in the company who might need to build some artifact, just to avoid the previous problem
- Licenses for certain tools have expired, because nobody's run it in a while and you didn't notice the date had passed
- Which file is the right build? Is it qa-test-build.apk, or release-candidate-June.apk, or 2021-06-20.apk, or one of the myriad copies of each of those in the folder "recent builds", "test builds", "rc builds"? Oh, or did Frank do it this this week?
The right automation software alleviates all those problems and more. It doesn't need a person present in order to complete the correct task, it doesn't forget and it doesn't make mistakes because it's bored or distracted or pressed for time.
If you can only afford one license for a particular build tool, put that license on a single "agent" machine, and everybody can get the finished product from there.
If builds run regularly (you run them regularly, don't you?) then an expired license will make itself known the day it happens, hopefully before the eleventh hour when you're trying to submit a build to the platform.
Build artifacts are organized in a systematic way, so as long as everybody's communicating (Hey Aaron, build #314159 is the release candidate, please test that one), then everybody knows which build is the right build.
Before we get to what I chose, let's talk about how I chose it. I don't have very many deal breakers, other than the ones I've mentioned in the past. Actually, I guess I have two.
First, complicated and/or delicate installation. If the system needs <specific OS version x.y.z.123.b-2>, or <equally specific language runtime>, or has to be installed on a Tuesday evening during a waxing gibbous moon with a chicken in your left hand and a knife in your right, I'm going to pass.
Second, hard to use interface, and especially, hard to find build results/artifacts. If it's hard to set up a job, or hard to find the result of that job and get the build to QA, I may as well build the thing at my desk and email it around to people like an executive would. HARD pass.
Now the must haves. Has to interface with my desired source control systems. Absolutely must understand Subversion and Perforce, and if it doesn't understand Git I probably won't look at it either. "But Ian, I thought you didn't like Git". I don't, but I have friends who provide libraries and some of them keep their source in a Git repo, so I'm better served by a system that understands it.
Has to have a master-worker arrangement. As a mobile guy, I need at least 2 platforms -- OSX for iOS, and Windows or Linux for Android -- just for the application binaries themselves. There might be realtime pvp servers (Linux) or GUI tools (probably Windows) and any number of other things. So I need workers on all of those systems controlled by a master.
Gotta have a web interface. Welcome to the 21st Century.
I've gotten used to being able to "mark a build"; while builds normally get culled after some number of days, or bumped out by the most recent, I should be able to lock one in as a Release Candidate. I should also be able to attach some description to it, so we'll know what that was 2 years from now (rather than just being able to rebuild from a tagged changelist).
I had 3 candiates:
Buildbot - I liked this one because everything is on PyPI so it's pretty much create a virtualenv and pip install to freedom. I had some minor issues at the beginning getting the TLS libraries installed, but I think that's more a function of my inexperience with Python than anything to do with the code.
The master and worker setup are pretty much the same, so once your master is running, you can then install workers wherever you like and point them at the master. It is nearly as easy to do as it is for me to say.
Since it's all Python, I have to assume any place you have a Python install you can have a Buildbot worker. And since it's all self-contained, you can run it manually from your home directory if that's the cut of your jib.
GoCD - a little more professional looking, a little more complicated and a little more fiddly. You can install it via your operating system's package manager, if such a thing exists. Windows has an installer .exe, it's all good.
It's Java, which is mildly upsetting to me, but the installers come with the correct version of it, so I can overlook that just so long as I don't have to upgrade it myself.
My winner was Jenkins, and I'm not gonna lie, it was mostly because I have experience with it. Buildbot seems cool, and if you have to teach yourself one of these systems, it looks like the simplest, i.e. the shortest path. GoCD seems a lot more feature-rich, though the UI seems a little less intuitive, and I find myself having to drill down through the various parts of a job in order to get to the artifacts.
Jenkins is also Java-based, but once again the installation is easy and low-maintenance. I was able to apt install the entire system, including Java, and it wasn't some weird alternate, it was the stock Java that comes with Ubuntu. Sorted.
I've been using Jenkins at work full time for maybe 3 years, and it's pretty hard to find fault with it. It does all the things I've mentioned and a lot more. The UI is pretty good: if you have a bazillion jobs on a single master, and you weren't aware of folders you caveman, you can set up views to organize it all nicely, and that's what we do at work. Some of our leads have created pretty elaborate "landing pages".
Equally as important is that it's very easy to point QA to a specific view if they're testing for you that week. I go as far as Slacking them links to an install page that our build script creates, which is crazy handy. Then they can navigate to said page on their device and click the install link and start breaking my build (and my heart 💔).
I haven't created any of the more complicated job types yet, but I've seen them in action, so I'll be learning how to set them up once the applicable use cases present themselves.