Automate JS releasing with Grunt
So let's say you are developing a new JS library and you are at the point to release your current version, which it usually includes following steps:
- bump the version in your
package.json
- create a new git tag for the release
- push it to github
- publish your new version to npm
Why not do all of this in one step?
Assuming you are using Grunt to automate your development, there are some cool plugins that could help you with that:
https://github.com/geddski/grunt-release
https://github.com/vojtajina/grunt-bump
I've tried both and they are both good but I've opted for the second one. Let me share with you why:
I love coffeescript and I use it of course in my projects. It's really fun and fast to develop with it. Using coffeescript means also that you would need to compile the sources, but that's easily achievable with Grunt and it's out of the scope of this article.
The point is that before you push your changes or release a new version you need to make sure that your sources are correctly generated. Things get more complicated then if you include meta banners in your files because you need the correct version to be displayed (loaded from the package.json
).
meta:
banner: "/* =================================================\n" +
"# <%= pkg.name %> - v<%= pkg.version %>\n" +
"# ====================================================\n" +
"# Copyright (c) 2013 <%= pkg.author.name %>\n" +
"# Licensed under the MIT license.\n" +
"*/\n"
So theoretically you would need this kind of process:
- bump the version in your
package.json
- build your project (compilation, etc)
- create a new git tag for the release
- push it to github
- publish your new version to npm
And that's where the grunt-bump
plugin comes in hand. It supports a 2-steps task so that you can run some other tasks in between.
$ grunt bump-only:minor
$ grunt build
$ grunt bump-commit
Perfect, but I still need to run 3 tasks. Why not put it all together? And since you can pass to the task a target specifying the "type of version bump" (patch
, minor
, major
) we should allow that when registering our new task:
grunt.registerTask "release", "Release a new version, push it and publish it", (target)->
target = "patch" unless target
grunt.task.run "bump-only:#{target}", "build", "bump-commit", "shell:publish"
Now we have defined a new task called release
which does all what we wanted.
The shell:publish
part is a task that runs a command via the grunt-shell
plugin, in my case the publishing to npm (since the grunt-bump
plugin doesn't support that).
shell:
publish:
command: "npm publish"
Finally here is the output of grunt release
Running "release" task
Running "bump-only:patch" (bump-only) task
Running "bump:patch:bump-only" (bump) task
>> Version bumped to 0.0.8
>> pkg's version updated
Running "clean:default" (clean) task
Cleaning lib...OK
Running "clean:test" (clean) task
Cleaning test...OK
Running "coffeelint:default" (coffeelint) task
>> 6 files lint free.
Running "coffee:default" (coffee) task
File lib/oauth2.js created.
File lib/rest.js created.
Running "coffee:test" (coffee) task
File test/integration.spec.js created.
File test/oauth2.spec.js created.
File test/rest.spec.js created.
Running "concat:default" (concat) task
File "lib/oauth2.js" created.
File "lib/rest.js" created.
Running "bump::commit-only" (bump) task
>> Committed as "Bump version to 0.0.8"
>> Tagged as "v0.0.8"
>> Pushed to origin
Running "shell:publish" (shell) task
npm http PUT https://registry.npmjs.org/sphere-node-connect
npm http 409 https://registry.npmjs.org/sphere-node-connect
npm http GET https://registry.npmjs.org/sphere-node-connect
npm http 200 https://registry.npmjs.org/sphere-node-connect
npm http PUT https://registry.npmjs.org/sphere-node-connect/-/sphere-node-connect-0.0.8.tgz/-rev/7-e48da04c54941c0a7d9b90c6ec85651d
npm http 201 https://registry.npmjs.org/sphere-node-connect/-/sphere-node-connect-0.0.8.tgz/-rev/7-e48da04c54941c0a7d9b90c6ec85651d
npm http PUT https://registry.npmjs.org/sphere-node-connect/0.0.8/-tag/latest
npm http 201 https://registry.npmjs.org/sphere-node-connect/0.0.8/-tag/latest
+ sphere-node-connect@0.0.8
Done, without errors.