Python: Controlando versionamento com bumpversion


O que é o bumpversion?

Uma pequena ferramenta de linha de comando que simplifica o controle de versionamento para liberação de software, atualizando todas as seqüências de versão em seu código-fonte pelo incremento correto.
Também cria commits e tags, os formatos de versão são altamente configuráveis, funciona sem a necessidade de VCS, mas trabalha perfeitamente com informações oriundas do Git ou Mercurial, permitindo gerar commits e tags de forma automatizada. Esta ferramenta lida com arquivos de texto, por isso não é específico para linguagens de programação.
A página oficial do bumpversion se encontra no pypi (https://pypi.org/project/bumpversion/), onde também pode-se encontrar a sua documentação oficial e detalhes de instalação e uso.

Vantagens

O bumpversion segue as recomendações regidas pela "semântica de versionamento tratada na PEP440".

Utilização

Há duas formas de excutar esta ferramenta, uma perene e outra volátil. A perene é indicada para projetos e registra as alterações, e volátil deve-se passar as informações necessárias toda a execução.

Ambiente de teste

Utilizemos um ambiente virtual, com arquivo de versionamento segundo a PEP440 [major.minor.patch]. Considerado Python configurado e plenamente funcional em um sistema operacional Linux.
$ pip install pipenv
$ file=/tmp/$(date +%s); mkdir $file && cd $file
$ pipenv shell
$ pip install bumpversion
$ echo $(date +%Y.%-m.0) > version.txt

Execução volátil

Conteúdo inicial
$ cat version.txt
2019.2.0
Atualizar patch
$ bumpversion --allow-dirty --current-version $(cat version.txt) patch version.txt
$ cat version.txt
2019.2.1
Atualizar revisão
$ bumpversion --allow-dirty --current-version $(cat version.txt) minor version.txt
$ cat version.txt
2019.3.0
Atualizar versão
$ bumpversion --allow-dirty --current-version $(cat version.txt) major version.txt
$ cat version.txt
2020.0.0

Execução perene

Na execução perene faz-se necessário definir alguns parametro no arquivo de configuração.
Para carregamento das diretivas de configuração, o bumpversion faz uso do arquivo .bumpversion.cfg em sua inexistência poderá utilizar o setup.cfg, respectivamente nesta precedência.

Arquivo de configuração


$ cat > .bumpversion.cfg << eof
# .bumpversion.cfg 
[bumpversion]
current_version = 1.0.0
commit = True
message = Update version: {current_version} → {new_version}
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+)(?P<build>\d+))?
serialize = 
 {major}.{minor}.{patch}-{release}{build}
 {major}.{minor}.{patch}

[bumpversion:part:release]
optional_value = prod
first_value = dev
values = 
 dev
 prod

[bumpversion:part:build]

[bumpversion:file:version.txt]
eof

ou com setup.cfg. Na utilização do setup.cfg tome cuidado para não substituir a configuração existente.
$ cat >> setup.cfg << eof
# setup.cfg 
[bumpversion]
current_version = 1.0.0
commit = True
message = Update version: {current_version} → {new_version}
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+)(?P<build>\d+))?
serialize = 
 {major}.{minor}.{patch}-{release}{build}
 {major}.{minor}.{patch}

[bumpversion:part:release]
optional_value = prod
first_value = dev
values = 
 dev
 prod

[bumpversion:part:build]

[bumpversion:file:version.txt]
eof

Arquivo completo para download aqui

Diretivas de configuração



  • current_version: Esta diretiva precisa corresponder ao conteúdo dos arquivos gerenciados;
  • commit: se "True" Grava a release no git/mercurial;
  • tag: se "True" gera nova tag do VCS;
  • parse: Define os componentes do número da versão que será gerenciado, também está vinculado à formatação do parametro serialize. O bumpversion basicamente encontra a string, definida no parametro current_version, divide-a em componentes de acordo com o parse regex e recria-a usando a primeira serialização correspondente que possui todas as partes relevantes.
  • Diretiva [bumpversion:part:release]: Controla como a parte da liberação do número da versão é gerenciada. Basicamente, executa-se entre dev e prod. Como prod é opcional, ele não é mostrado no número da versão, apenas uma destas dicas são necessárias, embora esteja registrado na documentação do bump2version. Estes valores de [alfa, beta, gama, delta com delta opcional e progrediria de .dev, a, b, rc, [sem sufixo], .post, conforme descrito na PEP440.
  • Diretiva [bumpversion:part:build]: Permite o uso para incrementar o número de compilação;
  • Diretiva [bumpversion:file:version.txt]: Indica o arquivo que será atualizado. Se houver multiplos arquivos deverá ser indicado um por diretiva;
Atualizar patch
$ bumpversion patch
$ cat version.txt
2020.0.1-dev0

Atualizar build
$ bumpversion build
$ cat version.txt
2020.0.1-dev1

Atualizar build
$ bumpversion build
$ cat version.txt
2020.0.1-dev2

Atualizar tag release patch
$ bumpversion --tag release
$ cat version.txt
2020.0.1

Atualizar revisão
$ bumpversion minor
$ cat version.txt
2020.1.0-dev0

Atualizar tag release revisão
$ bumpversion --tag release
$ cat version.txt
2020.1.0

Atualizar versão
$ bumpversion major
$ cat version.txt
2021.0.0-dev0

Atualizar tag release versão
$ bumpversion --tag release
$ cat version.txt
2021.0.0

Desfazer commit automático no repositório

git reset --hard HEAD~1                        # rollback the commit
git tag -d `git describe --tags --abbrev=0`    # delete the tag

Referências

https://www.python.org/dev/peps/pep-0440/
https://medium.com/@williamhayes/versioning-using-bumpversion-4d13c914e9b8

Comentários