Há pouco tempo, em um dos projetos de nossa empresa, foi decidido finalmente abandonar o uso do Subversion para armazenar e versionar códigos em favor do Git.
Os principais objetivos da transição foram os seguintes:
- Melhorar a transparência do processo de desenvolvimento.
- Implementação do procedimento obrigatório de revisão de código antes de atualizar as atualizações nos ambientes de teste.
- Implemente a integração contínua para criar atualizações após a revisão do código e instalá-las nos ambientes de teste.
Um pré-requisito para atingir esses objetivos era o uso do GitLab (esse servidor Git já era usado pelo cliente e já havia um código lá que pertencia à frente da solução) e Jira (também já usado pelo cliente).
Foi proposto o uso do Git Flow como modelo de desenvolvimento de destino, adicionando um código de revisão a ele. Esse modelo de desenvolvimento de fato se tornou o padrão no desenvolvimento de software de código aberto e é usado pela maioria dos gigantes do setor. É por isso que seu suporte é incorporado a muitas ferramentas populares para trabalhar com o Git. Um grande número de materiais foi escrito sobre o tema de seu uso; citarei os mais bem-sucedidos para a familiarização inicial: um e dois .
Por si só, esse modelo oferece apenas princípios gerais de manutenção de código, deixando de fora os processos que acompanham sua escrita. Portanto, a implementação de tudo o mais, incluindo o código de revisão, depende do servidor Git específico. Nesse sentido, o GitHub é mais conveniente: ele foi originalmente construído como uma plataforma para colaboração de um grande número de desenvolvedores independentes e permite limitar os direitos de envio de commits (Push) no repositório, com a capacidade de criar solicitações para o envio de código. Além disso, o GitLab oferece seu próprio fluxo de trabalho para manter o código chamado GitLab Flow, adaptado para usar o GitLab CI. Portanto, no GitLab, a funcionalidade para criar solicitações para o envio de código não é implementada e é proposto o uso de solicitações de mesclagem de ramificações para revisar o código de alteração. Para criar e instalar artefatos no projeto, o Jenkins já foi usado, o que permite criar e configurar com flexibilidade tarefas de montagem e implantação, e foi decidido não mudar para o GitLab CI, rejeitando simultaneamente a ideia de usar o GitLab Flow.
Também observo que o projeto foi configurado integrações no Jira e Git. No Jira, no plug-in Git, um repositório criado para armazenar código-fonte foi adicionado para rastreamento, e no GitLab esse repositório foi configurado para integrar-se ao Jira na seção "Integrações" do repositório.
Para resolver esse problema, foi desenvolvido um fluxo de trabalho para trabalhar com código com estrutura semelhante ao Git Flow, mas permite revisar o código toda vez que você faz alterações nos principais ramos do processo (desenvolvimento, liberação-n e mestre) usando o GitLab. A seguir, o processo resultante será descrito, bem como os estágios de integração contínua e entrega de software para as strings adjacentes a ele. Entre parênteses estão os comandos correspondentes a serem executados.
O repositório criado para armazenar o código-fonte é carregado no repositório local (git clone) e o Git Flow (git flow init) é inicializado nele - além do ramo mestre (para criar tags para armazenar liberações estáveis), o ramo de desenvolvimento é criado (o ramo principal de desenvolvimento, em que integra ramificações de função, liberações e correções), máscaras para ramificações de função, liberações e correções são definidas e também é feita uma transição para a ramificação de desenvolvimento.
A seguir, a ramificação atual do código-fonte do Subversion é transferida para a cópia de trabalho, o código é confirmado (git add -A + git commit -m “Commit message”) para a ramificação de desenvolvimento do repositório local e seu upload para o repositório remoto (git push origin develop). Depois disso, você pode começar a desenvolver novas funcionalidades usando o Git para fazer a versão do código.
Durante o desenvolvimento, a versão atual da ramificação de desenvolvimento é baixada e ramificações são criadas a partir dela para o desenvolvimento de novas funções (o recurso de fluxo git inicia MYFEATURE) de acordo com os códigos de tarefa Jira nos quais o desenvolvimento está sendo realizado.
Uma transição para a ramificação criada (git checkout MYFEATURE) é executada automaticamente, a funcionalidade planejada é desenvolvida e as alterações são confirmadas na ramificação local MYFEATURE (git commit -m “Commit message”). Observe que, para a integração correta do Git e do Jira, o código de confirmação no Jira ao qual essa correção se aplica deve ser indicado nas mensagens de confirmação. Em seguida, esses commits serão exibidos nas tarefas correspondentes a eles, assim como na seção "Git commits" do projeto, com a ajuda da qual você pode estabelecer de maneira inequívoca o que está incluído em um release específico.
Quando a funcionalidade da tarefa selecionada é desenvolvida e pronta para ser submetida ao ambiente de teste, as confirmações criadas são carregadas na ramificação remota com o mesmo nome (git push -u origin MYFEATURE) e uma solicitação para mesclar a ramificação baixada com a ramificação de desenvolvimento é feita para o líder da equipe ou suas funções de atuação.

Para solicitar uma mesclagem, o desenvolvedor resolve conflitos de mesclagem (se houver) e o líder da equipe de desenvolvimento (ou atua) produz uma revisão de código, durante a qual é possível criar confirmações adicionais (git commit -m “Confirmar mensagem”) com correções nos comentários recebidos durante a revisão de código, em uma ramificação com novas funcionalidades e enviando-as para o repositório central (origem do git push -u MYFEATURE). Após a conclusão bem-sucedida da revisão, o líder da equipe (ou em ação) confirma a fusão das filiais. Aqui, não é supérfluo definir o sinalizador para excluir a ramificação após a fusão - caso contrário, o número de ramificações poderá aumentar rapidamente para escalas indecentes.
Para garantir a integração contínua no repositório GitLab, um Web Hook é configurado na seção "Integrações", que chama as tarefas de Jenkins para criar e instalar novas funcionalidades no ambiente de teste. Jenkins, usando um plug-in para trabalhar com o Git, baixa o código-fonte, obtém o nome da tarefa e usa a API do Jira para solicitar uma lista de componentes que foram alterados e precisam ser montados, iniciar o processo de construção, executar os testes de Unidade e carregar os artefatos criados se eles forem aprovados com êxito. no Sonatype Nexus e instala-os em um ambiente de teste. Se em um dos estágios ocorrer uma falha ou os testes da Unidade falharem, com a ajuda do plug-in Telegram, a equipe de desenvolvimento será notificada sobre o resultado da compilação. Se a instalação foi bem-sucedida, a equipe de controle de qualidade é notificada de que a tarefa está pronta para teste.
Se os defeitos aparecerem, a versão atual do ramo de desenvolvimento é baixada e, a partir do commit de mesclagem do ramo MYFEATURE com o ramo de desenvolvimento, o ramo hotfix-MYFEATURE é criado (git checkout [BASECOMMIT] -b hotfix-MYFEATURE).
Ao criar, um check-out é feito automaticamente na ramificação criada, as correções são feitas e as alterações são confirmadas no hotfix-MYFEATURE da ramificação local (git commit hotfix-MYFEATURE -m “Confirmar Mensagem”). Quando a correção é concluída e pronta para ser enviada ao ambiente de teste, elas são enviadas para uma ramificação remota com o mesmo nome (git push -u hotfix de origem-MYFEATURE) e uma solicitação de mesclagem é criada com a ramificação de desenvolvimento.

Para solicitar uma mesclagem, o desenvolvedor resolve conflitos de mesclagem (se houver) e executa uma revisão de código, durante a qual é possível criar confirmações adicionais com correções nos comentários recebidos. Após a conclusão da revisão, as ramificações são mescladas. Imediatamente após a transferência do patch para a ramificação de desenvolvimento, o Web Hook também trabalha para chamar a tarefa no Jenkins para criar, executar testes de unidade, carregar os artefatos criados no Sonatype Nexus e instalar o patch no ambiente de teste. Um mecanismo de notificação semelhante funciona para correções.
Se todos os defeitos forem corrigidos, a versão atual da ramificação de desenvolvimento será baixada e, a partir da consolidação de mesclagem da ramificação hotfix-MYFEATURE com a ramificação de desenvolvimento, a ramificação release-mn será criada (o lançamento do fluxo de git inicia RELEASENAME [BASECOMMIT]).

Criar uma ramificação de lançamento também inicializa o lançamento de um Web Hook para chamar uma tarefa no Jenkins, que baixa o código-fonte do Git, obtém o nome da ramificação de lançamento e, usando a API Jira, consulta a lista de componentes que foram alterados como parte das tarefas de lançamento, baixa as versões atuais do Sonatype Nexus e os define para um ambiente de teste de regressão. Após a instalação do release no ambiente de teste de regressão, os scripts são executados para preparar o ambiente para o teste (reinicialização do aplicativo, limpeza do banco de dados etc.) e os autotestes de regressão são executados para verificar a operação da funcionalidade principal do sistema, o que resulta em um relatório usando o plug-in Allure Reports para Jenkins. Após a instalação, a equipe de controle de qualidade é notificada no Telegram sobre os resultados da execução do autoteste e a disponibilidade da versão para o teste de regressão manual.
Se os defeitos aparecerem durante o teste de regressão, a versão atual da ramificação release-mn é baixada e, a partir da última confirmação, a ramificação hotfix / BUGNAME é criada pelo nome do defeito no Jira (git checkout -b hotfix / BUGNAME [BASECOMMIT]).
Um check-out é feito automaticamente na ramificação criada, as correções necessárias são feitas e as alterações são confirmadas no hotfix / BUGNAME da ramificação local (git commit hotfix / BUGNAME -m “Commit message”). Quando a correção está concluída e pronta para ser enviada ao ambiente de teste de regressão, elas são enviadas para uma ramificação remota com o mesmo nome (hotfix de origem git push -u / BUGNAME) e uma solicitação de mesclagem é criada com a ramificação release-mn

Para solicitar uma mesclagem, o desenvolvedor resolve conflitos de mesclagem (se houver) e realiza uma revisão de código, durante a qual é possível criar confirmações adicionais com correções nos comentários recebidos durante a revisão de código. Essas confirmações também são feitas no hotfix / BUGNAME da ramificação local (git commit hotfix / BUGNAME -m “Commit message”) e são enviadas para uma ramificação remota com o mesmo nome (git push -u hotfix / BUGNAME). Após a conclusão da revisão, as ramificações são mescladas. A mesclagem inicializa o lançamento do Web Hook para chamar a tarefa no Jenkins, semelhante à anterior, mas diferente por baixar o código do Git, obter o nome do defeito, usar a API do Jira para solicitar uma lista de componentes que foram alterados como parte da correção, coletar esses componentes, baixa para o Sonatype Nexus e os instala em um ambiente de teste de regressão. Além disso, por analogia, o ambiente é preparado para autoteste, os autotestes de regressão são executados e seus resultados são notificados.
Quando todos os defeitos são corrigidos, a liberação é instalada em um ambiente produtivo. Para fazer isso, mescle a ramificação release-mn com as ramificações de desenvolvimento e mestre e também crie uma tag de liberação.
Quando é criado, inicializa o lançamento do Web Hook para chamar a tarefa no Jenkins, que baixa o código-fonte do Git, obtém o número do release e, usando a API Jira, solicita uma lista de tarefas incluídas no release e nos componentes que foram alterados como parte dessas tarefas, depois que bombeia a versão atual dos artefatos do Sonatype Nexus e os instala em um ambiente produtivo.
Com os hotfixes para vendas, foi decidido usar um processo semelhante ao do release - caso contrário, as etapas de teste das alterações feitas serão perdidas.
Ao implementar o processo, também foi realizado treinamento para funcionários que não tinham experiência em trabalhar com o Git e o GitLab, para os quais foi desenvolvido um programa de treinamento apropriado. Com isso, você poderá realizar um treinamento sobre o uso da Árvore de Origem e do Intellij IDEA para trabalhar com o Git, bem como o GitLab para realizar revisões de código. No próximo post eu darei a ela, complementando com ilustrações.