Does it Build?
I’m passionate about being able to checkout a repository and run a command to execute the tests. Lets call this a “push button build” as you can checkout the code and press a button to build the software successfully. As silly as this may sound, the implications are important for non-trivial projects that start up services and utilize supporting tools in order to work. Even if your software doesn’t technically “build” there are still things that need to happen before you can run your app. Lets think about what this looks like in practice and see the impact it has on the code.
Lets assume I have a Python web application that uses a Redis data store. My goal is to checkout the repo and run
make test to run all the tests, including some integration tests that start up my app and execute some HTTP requests. That
make test needs to set up a few things.
- Create a virtualenv
- Install dependencies into the virtualenv
- Ensure the supporting applications are in installed (ie Redis)
- Add any test data and/or auth necessary to run the tests
- Start supporting processes safely (and shut them down!)
- Run the tests using the installed resources
This is a lot of work just to run the tests, but lets look at the bigger picture. When you deploy your app, you’ll likely need to do all of the same steps. The CI system will likely have to do those steps as well. So why not reuse that work and keep the configuration next to the code?
The biggest benefit in maintaining this automation is how it impacts operations and your ability to test those operations. By supporting a push button build, you open the door to take ownership of your configuration. If you’ve ever used a configuration management solution and had to debug why some data wasn’t the correct value in a config file, you probably have already felt this pain. As a developer that needs to deploy code, this sort of visibility to see what the resulting data and configuration looks like without having to push new Chef or Ansible code is a really powerful concept. If you can do it on your laptop, then you can create tests that can also be run in CI. While tools like Chef have this functionality, it can be complicated as you not only have to have expertise in the application and domain you’re configuring. You have to become an expert in config management tools and often include it within the scope of a larger system.
This idea of supporting push button builds shouldn’t sound new as it reflects the concepts of immutable infrastructure, containers and products such as Habitat. All these tools reflect this idea that you should be able to build an artifact that is atomic in its dependencies and configuration.
There are many ways to get to push button deploys. The most challenging aspects are finding ways to standardize development environments as this is where most of the variety lives. Teams need to consider what the baseline of development is going to be. For example, if the entire company standardizes on developers running OS X, then tooling like brew can be used to deploy local versions of supporting software. If the company allows any development environment, then using Docker might be used to ensure that services can be started reliably. These are not terribly difficult problems, but it requires communication and, eventually, tooling to make the baseline requirements easy to get started and used reliably.
The benefit of push button deploys is not going to show up as one big win. Rather, it will help prevent many small issues over time. Bugs often show up because development is different from production. By implementing push button builds, you can make production more like development and start testing your configuration and deployment the same way you test your own code.