Many developers have experienced the “It Works on My Machine” problem when developing software. This is when you learn that some software you’ve been developing doesn’t work in a particular environment, but it works fine on your machine. For example, you may have tested the software on your machine, yet when the “same” software was tested on, say, the testing machine, it fails. There are many reasons this may occur. One reason may be that you forgot to commit a file to the version control repository. Another reason may be that the testing configuration is different - for instance, the application server’s pooling mechansim may be set for fewer connections. There can be many reasons, but in all cases, it means that something is different between your machine and the other machine(s). This is when you exclaim “But it works on my machine!” - as your last line of defense.

Introduce a similar, yet different, antipattern: “It only builds on this machine” or as I like to call it: The Magic Machine. The Magic Machine is the only machine capable of building your software. It’s the “Don’t touch that machine or we’ll go out of business” machine. It turns out this is much more common then we may realize.

This occurs for one reason: tightly-coupled build dependencies!

Typical Causes:

  1. Build script is tightly coupled with the IDE
  2. No build script. Every build is a custom hack job.
  3. The build script only exists on the Magic Machine
  4. A customization of the build script only exists on the Magic Machine
  5. Dependencies on Database/Application Server or other servers that must be recreated for each machine
  6. Custom configurations (username/password, scripts) on Magic Machine

The AntiPattern
As you see in the image below, there is a tight coupling with the various dependencies. This is all well and good unless you try build on a different machine with these same dependencies (which were hard-wired on the magic machine)
Magic Machine

Symptoms and Consequences

The symptoms are very straightforward: you try to build on a different machine than the magic machine and it won’t build. The bottom line is that if this Magic Machine ceases to work, you are effectively out of business for the product you are producing. The risk of relying on only one machine that can build your software occurs more frequently than you may imagine. You must immediately work to ensure that you can build your software on any machine. Depending on your particular circumstances, this may be a significant undertaking.

I highly encourage development groups to build on a separate machine; just make sure it’s not the only machine that is capable of building your software. The worst-case scenario, and all too common, is if your development machine acts as your build machine (and magic machine).

Refactored Solution

  1. Create one set of build scripts that everyone uses
  2. Build dependencies into the build script (e.g. using relative references)
  3. Make it simple to download servers and other software for which the build has dependencies
  4. Scorch the environment on each machine to ensure build is working and not relying on files from previous builds

Some will say, “Why don’t you create a backup or Ghost image?” and replicate the builds this way. While creating backups or images is a good practice in general, it is not a good way to solve this particular problem. It may be effective as a way of reducing some of the risk associated with a magic machine, but backups or images will not solve the underlined problem because of the constant changes in software development.

Benefits
The primary benefit is that you have working software at any point in time. What’s more is you will learn of integration problems before you deliver to the users. By building on a separate machine, and any machine, you enforce a single source code line obtained through your version control repository.