Hopefully we’re not beating a dead horse here, but as we’ve stated in several other articles, one of your goals with software development should be to minimize environmental dependencies. This goes for everything from the environment required to build your software from source code into deployable binaries, to the requirements of the computers that will run your application.
Many people think that this is just some pie in the sky idea that sounds good on paper, but isn’t worth pursuing in practice. “Just install the the Microsoft ReportViewer Redistributable on every machine that needs to run my app, it’s just one little installation prerequisite, what’s the problem?” That attitude is an incredibly slippery slope that will grant you a free one-way ticket to build & deployment hell if you let it happen.
To help further drive the point home about why you should always strive to minimize environmental dependencies for your applications, here’s a little horror story about some real world pain and suffering caused by not subscribing to this philosophy.
At one point in my career I worked for a firm that had to maintain several legacy versions of their software due to contractual obligations. Developers would occasionally have to make bug fixes to these legacy versions of the code base, and being on the “build team”, I had to produce the deployable artifacts of this legacy software. At the time, there was only one computer left in the whole company that was capable of compiling this legacy software… and it was literally under someone’s desk in the middle of the office. The fate of the legacy versions of this software relied on a little old PC on the floor.
Naturally, being the good build team that we were, my team and I decided to minimize this single-system-risk by cataloging all of the dependencies we could find on this computer that were necessary to build the software and try to reproduce this “build server” on a virtual machine. Try as we might, we could not reproduce “the little workstation that could”. Several of us tried for weeks, pawing through the installed programs, shoveling through mountains of registry keys… we just couldn’t figure out what was so special about this “build server”. We even reached out to one of the (then working remotely) employees that helped create this original build server, but he couldn’t remember what made it special either.
Then, as fate would have it, the build server started having hardware issues. It was reporting hardware errors in the Event Log left and right until one day it just refused to power on. Our sysadmins said it was a motherboard failure. Normally a motherboard failure on a workstation is just a minor inconvenience – just throw it out and swap in a new one. But given this one magical workstation was critical to creating the release versions of this legacy application, this motherboard failure became a Priority 1 Big Problem ™.
So to be able to keep releasing software, this is essentially what we did:
I literally had to plug in that “build server’s” hard drive into a spare workstation via some external harddrive adapter just to boot off of it just so I could compile the release version of this legacy application.
Obviously this is an extreme case, but hopefully it helps illustrate our point about why you should minimize external dependencies for building and running your software. By doing so, you ensure that your application, a.k.a. your organization’s intellectual property, will be able to be recreated from its source code almost indefinitely.