Criando Novas Versões do Seu Pacote Python#

Principais Conclusões

  • Siga as diretrizes de versionamento semântico (SemVer) ao incrementar (aumentar) a versão do seu pacote Python; por exemplo, um incremento de versão major (versão 1.0 –> 2.0) equivale a mudanças que quebram a compatibilidade no código do seu pacote para um usuário.

  • Você pode querer considerar usar um plugin como o hatch_vsc para gerenciar as versões do seu pacote - se você quiser ter um fluxo de trabalho de release apenas no GitHub.

  • Caso contrário, a maioria das principais ferramentas de build de pacotes, como Hatch, Flit e PDM, tem um recurso de versão que ajudará você a atualizar a versão do seu pacote

  • Evite atualizar o número de versão do seu pacote manualmente, à mão, no seu código!

O pyOpenSci recomenda que você siga a PEP 440 do Python, que recomenda usar as diretrizes de versionamento semântico ao atribuir valores de release a novas versões do seu pacote Python.

O versionamento semântico é uma abordagem para atualizar as versões de um pacote que considera o tipo e a extensão de uma mudança que você está fazendo no código do pacote. Ser consistente com como e quando você atualiza as versões do seu pacote é importante porque:

  1. Ajuda os seus usuários (que podem incluir outros desenvolvedores que dependem do seu pacote) a entender a extensão das mudanças em um pacote.

  2. Ajuda a sua equipe de desenvolvimento a tomar decisões sobre quando incrementar a versão de um pacote com base em regras padrão.

  3. Aumentos de versão consistentes que seguem as regras do semver significam que os valores da versão do seu pacote explicam a extensão das mudanças feitas na base de código de uma versão para outra. Assim, os números de versão do seu pacote tornam-se «expressivos» da mesma forma que nomear bem as variáveis de código pode tornar o código expressivo.

Uma nota sobre versionamento

Em alguns casos, até mesmo pequenas mudanças de versão podem transformar uma atualização de pacote em uma mudança que quebra a compatibilidade para alguns usuários. O que também é importante é que você documente como versiona o seu código e, se possível, também documente a sua política de depreciação de código.

Regras do SemVer#

Seguindo o SemVer, você incrementa a versão do seu pacote para um:

  • patch (1.1.1 –> 1.1.2)

  • minor (1.1.1 –> 1.2.1)

  • major (1.1.1 –> 2.1.1)

a mudança do número de versão é baseada nas seguintes regras:

Dado um número de versão MAJOR.MINOR.PATCH, incremente o:

  • versão MAJOR quando você faz mudanças incompatíveis na API

  • versão MINOR quando você adiciona funcionalidade de forma retrocompatível

  • versão PATCH quando você faz correções de bugs retrocompatíveis. Rótulos adicionais para pré-release e metadados de build estão disponíveis como extensões ao formato MAJOR.MINOR.PATCH.

Nota

Algumas pessoas preferem usar o calver para o versionamento. Pode ser um sistema mais simples de usar, já que se baseia em valores de data associados às versões lançadas. No entanto, o calver não dá ao usuário uma noção de quando uma nova versão pode quebrar uma build existente. Por isso, ainda sugerimos o semver.

O pyOpenSci nunca exigirá o semver em uma revisão por pares, desde que um pacote tenha uma abordagem razoável para o versionamento!

Evite atualizar manualmente os números de versão do pacote Python, se possível#

Muitas vezes, você pode querer ter o valor da versão do seu pacote em vários locais. Um exemplo disso é que ele pode ser tanto um atributo na versão do seu pacote quanto também ser chamado na sua documentação.

Recomendamos que você evite atualizações manuais do número de versão do seu pacote para evitar erros humanos. É uma prática melhor manter o seu número de versão em um único local.

Se você não conseguir implementar uma versão em um único local, então considere usar uma ferramenta como hatch, PDM ou bump2version, que atualizará os valores de versão para você - em todo o seu pacote.

Abaixo, discutimos algumas ferramentas que você pode usar para gerenciar a atualização das versões de pacotes Python.

Ferramentas para gerenciar as versões do seu pacote Python#

Há um punhado de ferramentas que são amplamente usadas no ecossistema científico e que você pode usar para gerenciar as versões do seu pacote. Algumas dessas ferramentas são embutidas ou funcionam com as ferramentas de build de packaging que você escolher, discutidas neste capítulo.

Abaixo, fornecemos uma visão geral dessas ferramentas.

Há três grupos gerais de ferramentas que você pode usar para gerenciar as versões de um pacote:

  1. ferramentas de semantic release: Essas ferramentas determinam automagicamente qual tipo de incremento de versão usar com base no texto das suas mensagens de commit. Abaixo, discutimos o Python Semantic Release como uma ferramenta Python que implementa uma abordagem de versionamento semântico.

  2. Ferramentas de incremento manual: Ferramentas como o Hatch oferecem o incremento de versão dentro do seu pacote. Normalmente, isso é implementado na linha de comando; por exemplo, hatch version major incrementaria o seu projeto de 0.x para 1.0.

  3. Ferramentas de Sistema de Controle de Versão: Por fim, há ferramentas que se baseiam no seu sistema de controle de versão para rastrear as versões. Essas ferramentas costumam ser plugins para a sua ferramenta de build de pacotes (ex: setuptools build ou hatchling). Discutimos essa opção abaixo, presumindo que você está usando .git tags e o GitHub para gerenciar o repositório do seu pacote.

Semantic release vs. baseado em controle de versão vs. incremento manual de versão#

Em geral, as ferramentas de semantic release e de sistema de controle de versão podem ser configuradas para rodar automaticamente no GitHub usando o GitHub Actions. Isso significa que você pode criar um fluxo de trabalho em que um release do GitHub e a nova tag de versão associada são usados para disparar uma build automatizada que:

  1. Constrói o seu pacote e atualiza a versão de acordo com a nova tag

  2. Testa a build e publica no test PyPI

  3. Publica o pacote no PyPI

Nota

Incrementar a versão de um pacote refere-se à etapa de aumentar a versão do pacote depois que um certo número de mudanças foi feito nele. Por exemplo, você pode incrementar da versão 0.8 para a 0.9 de um pacote ou da 0.9 para a 1.0.

Usando o versionamento semântico, há três «níveis» principais de versões que você pode considerar:

Major, minor e patch. Eles são descritos em mais detalhes abaixo.

Ferramentas para incrementar as versões de pacotes Python#

Nesta seção, discutimos as seguintes ferramentas para gerenciar a versão do seu pacote Python:

  • hatch &

  • plugin hatch_vcs para o hatchling

  • setuptools-scm

  • python-semantic-version

Ferramenta 1: Hatch e outras ferramentas de build que oferecem versionamento incremental#

Muitas das ferramentas de front-end de build modernas oferecem suporte a versões que seguem as regras de versionamento semântico. Essas ferramentas são diferentes do Python Semantic Version porque não requerem mensagens de commit específicas para implementar a versão. Em vez disso, elas permitem que você atualize a versão na linha de comando usando comandos como:

  • tool-name version update major

  • tool-name version update minor

O Hatch, por exemplo, oferece hatch version minor, que modificará a versão do seu pacote de forma incremental. Com o Hatch, o valor da versão será encontrado no seu arquivo pyproject.toml.

Prós do Hatch (ou de outras ferramentas como o PDM)#

  • Atualizações de versão fáceis de usar localmente com uma única ferramenta!

Contras do Hatch (ou de outras ferramentas como o PDM)#

  • Haverá alguma configuração envolvida para garantir que a versão do pacote seja atualizada em todo o seu pacote

Ferramenta 2: Hatch_vcs & o back-end de build hatchling#

O hatch_vcs é uma ferramenta de versionamento que permite gerenciar as versões de um pacote usando git tags. O Hatch_vcs cria um arquivo _version.py no ecossistema do seu pacote que mantém o controle da versão atual do pacote.

O Hatch mantém o controle da versão do seu pacote em um arquivo _version.py. Armazenar a versão em um único arquivo gerenciado pelo Hatch fornece ao seu pacote um valor de «fonte única da verdade» para o número de versão. Isso, por sua vez, elimina o potencial erro associado à atualização manual da versão do seu pacote.

Quando você (ou o seu sistema de CI) constrói o seu pacote, o hatch verifica o número da tag atual do seu pacote. Se ela tiver aumentado, ele atualizará o arquivo _version.py com o novo valor.

Assim, quando você cria uma nova tag ou um novo release com uma tag e constrói o seu pacote, o Hatch acessará o valor da nova tag e o usará para atualizar a versão do seu pacote.

Para usar o hatch_vcs, você precisará usar o back-end de build hatchling.

Dica

Hatchling can also be used with any of the modern build tools including Flit and PDM if you prefer those for your day to day workflow.

Exemplo de configuração do Hatch no seu pyproject.toml#

# pyproject.toml example build setup to use hatchling and hatch_vcs
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

O Hatch_vcs dá suporte a um fluxo de trabalho totalmente automatizado de release e build do pacote, e push para o PyPI no GitHub.

# Example hatch vcs setup in the pyproject.toml file
[tool.hatch.build.hooks.vcs]
version-file = "_version.py"

Dica

Se você usa o setuptools_scm, então você pode achar que o hatch_vcs e o hatchling são o equivalente moderno do seu fluxo de trabalho atual de setuptools / build.

Prós do hatch_vcs#

  • O Hatch dá suporte aos padrões modernos de packaging Python

  • Ele cria um arquivo de fonte única que contém a versão do seu pacote.

  • Você nunca atualiza a versão do pacote manualmente

  • Você pode automatizar a escrita da versão em qualquer lugar do seu pacote, incluindo a sua documentação!

  • Ele dá suporte a um fluxo de trabalho de release puramente baseado no GitHub. Isso simplifica os fluxos de trabalho de manutenção.

  • O número de versão é atualizado no seu pacote por meio de um arquivo oculto _version.py. Não é necessária nenhuma atualização manual de configuração.

  • Embora gostemos de mensagens de commit detalhadas (Veja o Python Semantic Version abaixo), sabemos que, às vezes, ao manter um pacote, diretrizes específicas em torno das mensagens de commit podem ser difíceis de aplicar e gerenciar.

Contras do hatch_vcs#

  • Em um fluxo de trabalho de CI, você acabará inserindo ou criando manualmente o número de versão por meio de uma tag no GitHub. Mas você poderia desenvolver localmente uma build para «incrementar» as versões das tags

Ferramenta 3: versionamento do setuptools-scm usando git tags#

O Setuptools_scm é uma extensão que você pode usar com o setuptools para gerenciar as versões de um pacote. O Setuptools_scm opera da mesma forma que o hatch_vcs (discutido acima). Ele armazena uma versão em um arquivo _version.py e se baseia em tags (git) para determinar a versão atual do pacote.

Se você está usando o setuptools como a sua ferramenta de build principal, então o *setuptools-scm é uma boa escolha porque:

Prós do setuptools_scm

  • Ele cria um arquivo de fonte única que contém a versão do seu pacote.

  • Você nunca atualiza a versão do pacote manualmente

  • Você pode automatizar a escrita da versão em qualquer lugar do seu pacote, incluindo a sua documentação!

  • Ele dá suporte a um fluxo de trabalho de release puramente baseado no GitHub. Isso simplifica os fluxos de trabalho de manutenção.

  • O número de versão é atualizado no seu pacote por meio de um arquivo oculto _version.py. Não é necessária nenhuma atualização manual de configuração.

  • Embora gostemos de mensagens de commit detalhadas (Veja o Python Semantic Version abaixo), sabemos que, às vezes, ao manter um pacote, diretrizes específicas em torno das mensagens de commit podem ser difíceis de aplicar e gerenciar.

  • O setuptools ainda é a ferramenta de build de packaging Python mais comumente usada

Contras do setuptools_scm#

  • Em um fluxo de trabalho de CI, você acabará inserindo ou criando manualmente o número de versão por meio de uma tag no GitHub.

  • Não é bem documentado

  • Como o setuptools sempre terá que dar suporte à compatibilidade retroativa, ele sempre será mais lento em adotar as convenções modernas de packaging Python.

Por isso, você pode considerar usar uma ferramenta mais moderna, como o hatch_vcs e o hatchling, para construir o seu pacote e gerenciar as versões do pacote.

Ferramenta 4: Python semantic release#

O Python semantic release usa um fluxo de trabalho de mensagens de commit que atualiza a versão do seu pacote com base em palavras-chave encontradas nas suas mensagens de commit. Como o nome indica, o Python Semantic Release segue as regras de release do semver.

Com o Python Semantic Release, as versões são disparadas usando uma linguagem específica encontrada em uma mensagem de commit do git.

Por exemplo, as palavras fix(attribute_warning): fazem o Python Semantic Release implementar um incremento de versão patch. Por exemplo, se o seu pacote estivesse na versão 1.1.0 e você fizesse o commit abaixo com as palavras fix(text-here), o Python Semantic Release incrementaria o seu pacote para a versão 1.1.1.

git commit -m "fix(mod_plotting): fix warnings returned athlete attributes"

De forma semelhante, uma funcionalidade (feat()) dispara um incremento de versão minor. Por exemplo, da versão 1.1 para a versão 1.2

git commit -m "feature(add_conversions): add value conversions to activity date"

Dica

Você pode encontrar uma discussão criteriosa sobre o python semantic version neste guia de pacotes Python. Note que o guia não é atualizado desde 2020 e, potencialmente, será atualizado no futuro! Mas, por enquanto, alguns dos comandos estão desatualizados, embora o conteúdo ainda seja excelente.

Prós do Python Semantic Release#

  • Segue de perto o versionamento semver

  • Obriga os mantenedores a usar mensagens de commit descritivas, o que pode simplificar a resolução de problemas e garantir um histórico do git mais limpo e autoexplicativo.

Contras do Python Semantic Release#

  • Requer uma linguagem de commit muito específica para funcionar. Na prática, alguns mantenedores e contribuidores podem não conseguir manter esse nível de especificidade nas mensagens de commit (NOTA: há bots que verificam as mensagens de commit do git em um repositório)

  • O release acontece na linha de comando. Isso torna mais difícil implementar um fluxo de trabalho de release baseado no GitHub, pois a mensagem de commit errada poderia disparar um release.

  • O número de versão é atualizado manualmente em um arquivo de configuração como o pyproject.toml, em vez de em um arquivo _version.py do pacote.