Automatize a liberação de JS com Grunt

Então, digamos que você esteja desenvolvendo uma nova biblioteca JS e esteja no ponto de lançar sua versão atual, que geralmente inclui as seguintes etapas:

  1. bata a versão em seu package.json
  2. crie uma nova tag git para o lançamento
  3. empurrar para o github
  4. publique sua nova versão para npm

Por que não fazer tudo isso em uma única etapa?
Supondo que você esteja usando o Grunt para automatizar seu desenvolvimento, existem alguns plug-ins interessantes que podem ajudá-lo com isso:

https://github.com/geddski/grunt-release

https://github.com/vojtajina/grunt-bump

Eu tentei os dois e são bons, mas optei pelo segundo. Deixe-me compartilhar com você o porquê:

Adoro coffeescript e é claro que o uso em meus projetos. É muito divertido e rápido desenvolver com ele. Usar coffeescript também significa que você precisaria compilar os fontes, mas isso é facilmente alcançável com Grunt e está fora do escopo deste artigo.

A questão é que, antes de enviar suas alterações ou lançar uma nova versão, você precisa ter certeza de que suas fontes foram geradas corretamente. As coisas ficam mais complicadas do que se você incluir meta banners em seus arquivos porque você precisa que a versão correta seja exibida (carregada de 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"

Então, teoricamente, você precisaria deste tipo de processo:

  1. bata a versão em seu package.json
  2. construir seu projeto (compilação, etc)
  3. crie uma nova tag git para o lançamento
  4. empurrar para o github
  5. publique sua nova versão para npm

E é aí que o plugin entra em ação. Ele suporta uma tarefa de 2 etapas para que você possa executar algumas outras tarefas entre elas.grunt-bump

$ grunt bump-only:minor
$ grunt build

$ grunt bump
-commit

Perfeito, mas ainda preciso executar 3 tarefas. Por que não juntar tudo? E uma vez que você pode passar para a tarefa um alvo especificando o “tipo de versão colisão” ( patch, minor, major) devemos permitir que quando registrar a nossa nova tarefa:

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"

Agora definimos uma nova tarefa chamada releaseque faz tudo o que queríamos.
A parte é uma tarefa que executa um comando via plug in, no meu caso a publicação no npm (já que o plug in não oferece suporte para isso).shell:publishgrunt-shellgrunt-bump

shell:
publish
:
command
: "npm publish"

Finalmente, aqui está a saída de 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.