Engenharia

Keep a Changelog, de fato implementado

6 min de leitura atualizado em

Keep a Changelog é uma convenção de uma página para um CHANGELOG.md: versão mais recente primeiro, uma seção por versão com um número e uma data ISO, entradas agrupadas sob seis tipos (Added, Changed, Deprecated, Removed, Fixed, Security), e uma seção Unreleased no topo para entradas entre releases. A maioria das equipes que a citam implementa cerca de dois terços dela, e o terço que deixam de lado é o terço que protege seus usuários.

Olivier Lacan publicou o Keep a Changelog em 2014 com uma frase que envelheceu melhor que a maioria da prosa de software: don’t let your friends dump git logs into changelogs. Dez anos depois, é a coisa mais próxima de um padrão que este canto do software tem. Vale a pena ler a fonte em vez de um resumo; este texto trata das partes que são deixadas de lado.

O que o Keep a Changelog pede?

Um CHANGELOG.md na raiz do repo, mais recente primeiro, com uma seção por versão. Cada versão carrega um número e uma data ISO, e agrupa suas entradas sob seis tipos:

TipoParaO que custa deixar de fora
AddedNovos recursosNada; ninguém deixa esse de fora
ChangedMudanças em comportamento existenteLeitores descobrem uma mudança de comportamento por um erro
DeprecatedRecursos prestes a serem removidosUma remoção vira um incidente em vez de um evento planejado
RemovedRecursos removidos nesta releaseNinguém distingue uma remoção de um bug
FixedCorreções de bugsNada; ninguém deixa esse de fora também
SecurityVulnerabilidadesA única leitora que procurava não encontra

Mais uma seção Unreleased no topo, para que haja um lugar para colocar uma entrada no momento em que ela é mergeada, e para que qualquer um possa ver o que está por vir.

Isso é quase tudo. O resto é a justificativa: entradas são para humanos, uma entrada por mudança, e o arquivo é um documento em vez de um log.

Quais partes do Keep a Changelog são deixadas de lado?

A seção Unreleased, depois quatro dos seis tipos, Security entre eles, nessa ordem.

Unreleased desaparece primeiro. É a seção sem prazo, então é a que para de ser mantida primeiro, e quando some as entradas passam a ser escritas no momento da release a partir do histórico de commits. Isso é precisamente o dump de git log contra o qual a especificação avisa logo no início, alcançado gradualmente. Automação de changelog trata majoritariamente de manter essa seção viva sem que ninguém precise se lembrar.

Os seis tipos colapsam em dois. A maioria dos changelogs reais acaba com Added e Fixed, porque Changed e Deprecated exigem um julgamento sobre no que alguém confiava. Esse julgamento é a parte valiosa. Deprecated em particular é o único tipo que é uma promessa sobre o futuro, e deixá-lo de fora é como uma remoção vira um incidente; a mecânica de manter essa promessa está em como depreciar uma API.

Security deixa de ser separado. Uma correção de segurança arquivada sob Fixed é invisível para a única leitora que estava procurando por ela. Mantenha-a distinta mesmo quando a correção for trivial, e especialmente quando você preferir não chamar atenção para ela.

O que a especificação não responde?

É um formato de arquivo. Não diz nada sobre as perguntas que você encontra imediatamente após adotá-la:

  • Como alguém descobre? Um arquivo em um repo alcança colaboradores. Não alcança uma cliente que nunca abriu o GitHub.
  • E produtos sem versões? Um serviço implantado continuamente não tem uma v4.2.0 para agrupar. A maioria das equipes substitui isso por datas, o que funciona, e a especificação nem abençoa nem proíbe.
  • Quem escreve a entrada? A especificação assume que um humano faz isso. Não diz quando.
  • E múltiplos públicos? Um arquivo serve desenvolvedores. Não serve o mesmo conteúdo para uma administradora não técnica, e reformatá-lo manualmente para ela é onde a duplicação começa. Changelog vs release notes é a divisão que a especificação deixa para vocês fazerem sozinhos.

Common Changelog, um fork mais rígido da ideia, aperta parte disso: proíbe certas formulações de entrada, exige um link para a mudança, e tem uma opinião clara sobre quem é o leitor. Vale a pena ler se as partes soltas do Keep a Changelog são o que sua equipe fica discutindo.

Dá para automatizar o Keep a Changelog sem despejar git logs?

Sim: derive o rascunho de commits estruturados, coloque-o em Unreleased com o tipo pré-preenchido, e exija que um humano edite a formulação antes que uma release seja cortada. O aviso da especificação é sobre a saída, não sobre a ferramenta. Derivar um rascunho de commits está bem. Publicar esse rascunho sem edição é a que ela se opõe.

A máquina cuida de coleta e formatação, no que ela é boa. O humano cuida de seleção e formulação, no que ela não é. Conventional commits cobre a divisão em duas camadas da qual isso depende, e quais tipos de commit mapeiam para quais das seis categorias acima. Nosso resumo ferramentas de changelog cobre o que existe para a metade de coleta.

Onde o Keep a Changelog para de ser suficiente?

Para na distribuição. Keep a Changelog é uma boa resposta para “como esse arquivo deveria parecer”. Não é uma resposta para “como nossos usuários descobrem o que mudou”, porque um arquivo Markdown em um repo é uma estratégia de distribuição que só funciona se seus usuários forem colaboradores.

Esse é o obstáculo que a maioria das equipes encontra em segundo lugar: o arquivo está bem, e ninguém fora da equipe o lê. Resolver isso significa que as entradas precisam virar dados que podem ser renderizados em outro lugar, o que é um problema diferente de formatar um arquivo, e o motivo pelo qual exemplos de changelog reúne páginas públicas de changelog em vez de arquivos de repositório. Como transformar essas entradas em algo que as pessoas voltam a acompanhar é coberto em como construir uma página de changelog.

Adote a especificação mesmo assim. Custa uma tarde, torna o segundo problema tratável, e ainda é a melhor página já escrita sobre o assunto.

FAQ

Keep a Changelog é um padrão? É uma convenção amplamente adotada, não a especificação de um órgão de padronização. Ferramentas (scripts de release, linters, parsers) assumem sua forma com frequência suficiente para que segui-la compre compatibilidade.

O que entra na seção Unreleased? Toda entrada para uma mudança que foi mergeada mas ainda não foi lançada em uma release numerada. Quando uma release é cortada, a seção é renomeada para a versão e data, e uma nova seção Unreleased vazia vai acima dela.

Um changelog deveria usar versionamento semântico? Keep a Changelog recomenda e não exige. Bibliotecas e APIs se beneficiam; um serviço implantado continuamente geralmente substitui por datas, o que o formato acomoda.

Correções de segurança deveriam estar no changelog antes de serem públicas? Adicione a entrada quando a correção for lançada, com detalhe suficiente para que uma operadora possa agir e não mais. Atrasar a entrada até uma data de divulgação coordenada é normal; omiti-la não é.


As afirmações técnicas deste artigo não foram revisadas de forma independente. Se algo estiver errado, avise a gente e vamos corrigir.

Relacionado na changeloop: Exemplos de changelog, Comparativo de ferramentas de changelog

changeloop
O time por trás de um changelog que fecha o loop. Os usuários pedem algo, sua equipe entrega, quem pediu fica sabendo.