I’m a big fan of getting the basics of development right first when starting a new project or joining an existing one. One of those basic practices is one-step builds. However, I like to extend this idea to include not just building the project, but also bootstrapping a new development environment, migrating the database, running tests, and, if necessary, deploying.

Now, there are many build systems out there. Often there are multiple choices targeting the same language or platform: grunt or gulp; ant, maven, gradle; Rake; etc. All of these tools have their merits, and when I’m making a new project I usually choose the best one for the platform at hand. Often, if I’m working on a legacy project, I’ll reach for that steady Unix workhorse, make.

But, no matter what build system I use, I try to always make sure each project has these five basic commands:

bootstrap

This command warns about any dependencies missing from the project (i.e. wrong ruby version), sets up any virtual environments for the project, builds any virtual machines or docker images needed, installs all external dependencies for the project, downloads any necessary data files, and creates any databases required.

After this command is run, the project or machine should be completely configured for further project development.

One-step bootstrap allows you to very easily bring new people up to speed on your project and so helps collaboration. Additionally, if your own environment ever becomes corrupted, who cares? Just blow away the repo, clone it again, and bootstrap.

build

This one is the reason build systems were first created. There are many articles that talk about why one-step builds are important. One of my favorites is “The Joel Test”.

The two big reasons I cite for one-step builds are (1) increased development speed, and (2) simple continuous-integration setup.

In project that do not need to be compiled, as is the case for some Javascript, Ruby or Python projects, this step can instead be used to do basic code-quality and syntax checks with static analysis tools. pep8 anyone?

migrate

Most programs written today rely on a data store of some kind. Maybe it’s a Postgresql database, maybe it’s a MongoDB NoSQL database, maybe it’s just a series of csv files living in a directory.

Whatever it is, it’s database and it needs to be moved somewhere. The migrate command should set up any schemas necessary and install any seed or example data necessary for the application to operate.

test

A one-step testing process is just as important as a one-step build process, for exactly the same reasons. As a developer, being able to watch the tests pass whenever new behavior is added or changed is fantastic, and in a group setting with a CI server, your devop person will love the one-line task script: make build test.

Often, I will make additional commands to run only the unit tests, integration tests, functional tests, etc. Plus, depending on the build system, you can add additional functionality like auto-tests, watching directories, etc.

But no matter how fancy you make your tests, you still need to have one basic to answer the question, “Does this project work (at least as far as I know)?”

deploy (optional)

I’ve marked this command as optional because sometimes it’s not necessary. If the project is a data analysis project, for example, it doesn’t need to live on a server or be installed in a specific location on a box. It just needs to build an answer.

But many projects do need to be deployed, and being able to do a one-step deploy helps to close that ideal build-test-deploy continuous-deployment cycle we aspire to. Like the test command, it can be as simple or as complicated as you need, either pushing a static site to a single, specific url, or taking a parameter for a staging environment to deploy to for QA analysis.


When a project doesn’t have these basic commands, I find developer speed slows down. For instance, the bootstrap command is frequently neglected or omitted, and instead its knowledge is spread around the organization in the form of outdated wiki docs and passed-down “Oh, actually, you need to…” questions. Developers often spend hours setting up new development environments, instead of coding.

I consider these commands to be one of the basics of development. What build practices do you try to bring to your projects to speed them up?