Padrões de Commits e Estratégias de Branches
Como desenvolvedor de sistemas e graduando em um curso de Tecnologia, uma das questões que encontro entre os estudantes e entre alguns colegas de trabalho é sobre como manter o controle de suas contribuições em projetos de software de forma organizada e eficaz. Essas dúvidas geralmente giram em torno dos padrões de commit
e do gerenciamento de branches
. Esses são conceitos-chave que, quando bem implementados, facilitam muito a vida de quem está desenvolvendo, além de melhorar significativamente a colaboração nas equipes.
Depois de muitos tropeços, erros e estudos aprofundados, compilei algumas informações cruciais que podem ajudá-lo a evitar as dificuldades que enfrentei. Desbravemos juntos como estruturar commits
de maneira clara e explorar estratégias eficientes para o gerenciamento de branches
. Vale ressaltar que esta é apenas a superfície da discussão, recomendo que não pare por aqui!!
Padrões de Commit
Se você está aqui, sabe o quanto é crucial manter um histórico de projeto organizado. Isso não só facilita a compreensão das mudanças realizadas, mas também potencializa a colaboração entre nós, desenvolvedores. Entre os padrões que adotei e recomendo está o Conventional Commits, uma estrutura simples que eleva a clareza e a utilidade dos nossos registros de alterações.
Exemplo de Commit Usando Conventional Commits:
feat(login): adiciona captcha à tela de login
Neste exemplo, adicionamos uma nova funcionalidade ao sistema: um captcha na tela de login. O uso do prefixo feat
indica que se trata de uma nova funcionalidade, tornando este commit imediatamente compreensível para qualquer pessoa que o examine.
Tipos de Commits no Conventional Commits
Aqui estão os tipos mais comuns de commits utilizados no dia a dia de desenvolvimento:
feat
: Indica a adição de uma nova funcionalidade ao projeto. É talvez o tipo mais empolgante de commit, pois sinaliza crescimento e novas possibilidades.
fix
: Usado para correções de bugs. Esses commits são essenciais para a manutenção da saúde do software, garantindo que problemas identificados sejam resolvidos de forma ágil.
docs
: Refere-se exclusivamente a mudanças na documentação.
style
: Aplica-se a alterações que não afetam o significado do código (formato, ponto e vírgula ausente, etc.) e que não estão relacionadas com correção de bugs ou adição de funcionalidades.
refactor
: Utilizado quando fazemos uma alteração no código que nem corrige um bug, nem adiciona uma funcionalidade. Pense como uma refatoração, de fato. Quando refatoramos, tentamos fazer uma mesma coisa com uma qualidade superior, sem adicionar funcionalidades nem corrigir bugs (isso entra em outro tipo e escopo).
test
: Inclui tudo que é relacionado a testes no projeto. Adicionar novos testes ou corrigir alguns já existentes são exemplos comuns.
chore
: Para mudanças que não modificam o código-fonte ou os testes. Frequentemente relacionados à manutenção de tarefas que devem ser realizadas para o projeto funcionar adequadamente, mas que não alteram funcionalidades diretamente.
build
: Este tipo de commit é utilizado para alterações que afetam o sistema de build do projeto ou dependências externas. Inclui modificações em scripts de build, configurações ou ferramentas que auxiliam na construção do software.
Explicação do Escopo em um Commit
No exemplo anterior, o escopo foi claramente identificado:
feat(login): adiciona captcha à tela de login
Aqui, login
é o escopo do commit. Ele indica especificamente que a adição da funcionalidade (captcha) ocorreu na tela de login. Isso nos ajuda a entender rapidamente qual parte do sistema foi modificada sem a necessidade de examinar o código diretamente. Utilizar o escopo corretamente permite que nossa equipe rastreie melhor as modificações em diferentes áreas do projeto, facilitando revisões e depurações futuras.
Opcional, mas útil
Embora o escopo não seja obrigatório segundo o padrão Conventional Commits, recomendamos seu uso para maximizar a comunicação entre os membros da equipe.
Estratégias de Branches
Exploremos as branches mais comuns em projetos que utilizam o GitHub Flow:
Main
Contém a versão atual do software, a qual está em produção
Dev / Develop
Nela estão concentrados todos os desenvolvimentos que ainda não foram implantados em produção
Hotfix
Usada para correções críticas que não podem esperar uma próxima versão
Exemplo:
hotfix/<versão>-correção-do-bug-xyz
Bugfix
Usada para correções de bugs pouco urgentes / críticos
Exemplo:
bugfix/correção-do-bug-xyz
Feature
Usada para o desenvolvimento de uma funcionalidade específica, a qual possui base na branch develop
Exemplo:
feature/funcionalidade-y
Fluxo Contínuo de Pull Requests e Vínculo com Issues
O fluxo de trabalho que implementamos inclui uma constante interação entre essas branches através de pull requests. Este é um exemplo típico do fluxo:
- Desenvolvimento de funcionalidades: Inicia na branch feature, onde uma nova funcionalidade é desenvolvida.
- Integração: Após completar o desenvolvimento na feature, fazemos um pull request para a develop, onde todas as novas funcionalidades se juntam e são testadas juntas.
- Pré-produção: Quando estamos prontos para lançar, a develop é "mergeada" para a main, que então passa por uma última fase de testes antes de ser lançada em produção.
Além disso, utilizamos issues do GitHub para manter um vínculo claro entre as tarefas e os commits/pull requests. Cada issue corresponde normalmente a uma feature ou bugfix, facilitando o rastreamento do trabalho e a revisão do progresso.
Conclusão: Adaptabilidade é Chave
Embora os padrões e estratégias que discuti aqui sejam amplamente adotados e recomendados, é crucial entender que eles não devem ser vistos como regras imutáveis. Cada equipe deve adaptar essas práticas às suas necessidades específicas. Por exemplo, em equipes menores (menos de quatro pessoas), ou em projetos com escopos mais limitados, um fluxo mais simplificado pode ser mais apropriado.
No final, o objetivo é encontrar um equilíbrio que maximize a eficiência, facilite a colaboração e atenda às demandas do projeto, enquanto mantém o código organizado e gerenciável. Encorajo você a experimentar e ajustar essas estratégias para descobrir o que funciona melhor no seu contexto específico.