Marcação automática de versão git para módulos NPM

Ao criar tags git para módulos NPM, quase sempre esqueço de atualizar a versão do módulo package.json. Por esse motivo, criei um gancho git post-commit que cria automaticamente uma tag sempre que a versão é atualizada em package.json:

File: .git/hooks/post-commit
#! /bin/bash
version
=`git diff HEAD^..HEAD -- "$(git rev-parse --show-toplevel)"/package.json | grep '^+.*version' | sed -s 's/[^0-9.]//g'`

if [ "$version" != "" ]; then
git tag
-a "v$version" -m "`git log -1 --format=%s`"
echo
"Created a new tag, v$version"
fi

Então, como isso funciona?

Primeiramente, obtemos o diff do commit que acabamos de fazer, para o package.jsonarquivo. Então, fazemos grepo diff para ver se a tag de versão mudou. Se tiver, nós canalizamos para sede removemos tudo que não é um número ou um ponto, deixando-nos com algo ao longo das linhas de 0.0.1.

A seguir, se tivermos uma nova versão, criamos a tag, usando a mensagem de commit como a mensagem da tag, e então imprimimos uma pequena declaração informativa.

Então agora, se mudarmos a versão em package.json:

{
...
"version": "0.1.0"
...
}

e comprometer:

[person@acomputer ~/project] $ git commit package.json -m 'Updated version'

Nós temos:

Created a new tag, v0.1.0
[master 13138dd] Updated version
1 file changed, 1 insertion(+), 1 deletion(-)

Podemos verificar se nossa tag foi criada executando:

[person@acomputer ~/project] $ git show v0.1.0
tag v0
.1.0
Tagger: A Person <aperson@example.com>
Date: Fri Jan 24 12:17:22 2014 +0800

Updated version

commit b0520a474bba259dd5e6b5542f3622b1eabebfad

Author: A Person <aperson@example.com>
Date: Fri Jan 24 12:17:22 2014 +0800

Updated version

diff
--git a/package.json b/package.json
index
5fd5e5b..17b7223 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
...
- "version": "0.0.9",
+ "version": "0.1.0",
...

Tudo o que resta fazer agora é:

git push && git push --tags

Isso também poderia ser facilmente adaptado para outros gerenciadores de pacotes – por exemplo, o Bower poderia ser suportado simplesmente mudando package.jsonno gancho para bower.json.