But… In one regard I have lied. I told Woody Zuill (friend and role model) that I could push to production with a single command. While that was true the command (git push heroku master) did just that. Push to Heroku. But I wanted it to test my code, version it, push to GitHub and then push to Heroku. You know - all the continuous delivery stuff.
I had to look into the “scary” domain of Makefiles. Untravelled territory for me. I thought it was scary but it was just a bit weird and I actually got something nice to work.
This post described what I did - and how I redeemed my statement to Woody so that deploying to production is in fact one command (about 25 seconds). The Makefile I created took inspiration from VisionMedia’s in co-monk and this article. And I read this to sort out some quirks, like .PHONY and one-liners (for the record… both of those are really strange - get to know them).
With the make utility</a>, found on LINUX and OS X systems you can very easily define tasks and then chain them together to form more advanced commands. For example this creates a task named test that runs mocha with a lot of flags that I couldn’t care less of typing.
Ok, you say. I can do that with package.json and npm too - picked it up from you blog actually.
Well, there are something that you wouldn’t want to, or just can’t do inside a simple package.json script. For example, here’s a task (that I’ve ripped right off from here) that increments the version number, updates the package.json file and then commits those changes to git.
It looks horrendous but it’s basically executing a string of node code to update the package.json and then just use ordinary git bash commands to tag with the version number. Oh, I ran into problems with this task since it’s actually using a NPM package called semver. Nothing strange with the package but it of course needs to be installed in your node_modules-folder. Preferably you do that with:
npm install semver –save-dev
This stores the semver dependency in your package.json as a development time dependency. Which is exactly as it should be.
I then created a couple of other small tasks with finally made me write the deployProd task. The task does the following:
- runs my tests
- use the release-function defined above to create a new minor (0.X.0) release
- commits and tag that in git
- push to github
- push to heroku
- launches the site in my browser for verification
(This could be preceded by a build task if you’re minimising, transforming your code from CoffeeScript or TypeScript, or doing some other mangling of the code.)
And thanks to make’s built in-features the command halts if anything didn’t worked as expected, the test failed for example.
The task code? Well it’s almost just reading the list above out loud.
deployProd: test createMinorRelease pushGithub pushHeroku launch
Here’s the entire makefile.
There! I’m not lying to Woody anymore. Feels great. For more than just that reason. Because now I truly have 1 single command to deploy my application properly.