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:
| Tipo | Para | O que custa deixar de fora |
|---|---|---|
| Added | Novos recursos | Nada; ninguém deixa esse de fora |
| Changed | Mudanças em comportamento existente | Leitores descobrem uma mudança de comportamento por um erro |
| Deprecated | Recursos prestes a serem removidos | Uma remoção vira um incidente em vez de um evento planejado |
| Removed | Recursos removidos nesta release | Ninguém distingue uma remoção de um bug |
| Fixed | Correções de bugs | Nada; ninguém deixa esse de fora também |
| Security | Vulnerabilidades | A ú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.