Compreender a ramificação
Quando você cria modelos do Bicep e trabalha em um repositório Git, todas as alterações da sua equipe são eventualmente mescladas na ramificação principal do repositório. É importante proteger a ramificação principal para que nenhuma alteração indesejada seja implantada em seu ambiente de produção. No entanto, você também quer que seus colaboradores possam trabalhar de forma flexível, colaborar com sua equipe e experimentar ideias facilmente.
Nesta unidade, você aprenderá sobre estratégias de ramificação e como proteger o ramo principal. Você também aprenderá como configurar um processo de revisão para suas filiais.
Por que você quer proteger o ramo principal?
A ramificação principal é a fonte de verdade para o que é implementado nos seus ambientes do Azure. Para muitas soluções, você terá vários ambientes, como de desenvolvimento, de garantia de qualidade (QA) e de produção. Em outros cenários, você pode ter apenas um ambiente de produção. Independentemente de quantos ambientes você usa, a ramificação principal é a ramificação para a qual os membros da sua equipe contribuem. Suas mudanças acabam por ser integradas no ramo principal.
Um processo típico pode ser o seguinte:
- Um membro da equipe clona seu repositório compartilhado.
- Eles fazem alterações locais em uma ramificação em sua própria cópia local do repositório.
- Quando terminarem as alterações, elas mesclarão essas alterações na ramificação principal do repositório local.
- Eles enviam essas alterações para a ramificação principal do repositório remoto.
- Em alguns cenários, o push do repositório remoto aciona um pipeline automatizado para verificar, testar e implantar o código. Você aprenderá mais sobre pipelines em outros módulos do Microsoft Learn.
O diagrama a seguir ilustra esse processo:
Suponha que as alterações do membro da equipe introduziram um bug sutil. Depois de o processo completo ser executado, o bug já está na ramificação principal do projeto e é implementado em produção. Você pode não se aperceber até tentar implementá-lo e obter um erro. Ou, para outros tipos de bugs, a implantação pode ser bem-sucedida, mas causar problemas sutis mais tarde.
Em outro cenário, suponha que um membro da equipe esteja trabalhando em um recurso e envie metade do trabalho concluído do recurso para a ramificação principal do repositório compartilhado. Agora você tem alterações na ramificação principal que não foram concluídas ou testadas. Essas alterações provavelmente não devem ser implantadas em seu ambiente de produção. As implantações em produção podem precisar ser bloqueadas até que a funcionalidade seja concluída. Se os recursos recém-concluídos estiverem na ramificação principal, talvez não seja possível implantá-los para seus clientes.
Gorjeta
Esses problemas são particularmente difíceis para grandes equipes, onde várias pessoas contribuem para o mesmo código, mas a orientação neste módulo é valiosa assim que você colabora com mais de uma pessoa. A orientação é valiosa mesmo quando é apenas você trabalhando em um projeto e está trabalhando em vários recursos ao mesmo tempo.
Uma melhor maneira de trabalhar é manter as tuas alterações separadas enquanto trabalhas nelas. Em seguida, você pode fazer com que outro membro da equipe revise quaisquer alterações antes que elas sejam mescladas na ramificação principal do repositório compartilhado da sua equipe. Esse processo ajuda sua equipe a tomar uma decisão informada sobre uma alteração antes de aprová-la para ser mesclada.
Ramificações de funcionalidades
Uma ramificação de funcionalidade indica uma nova parte do trabalho que estás a iniciar. O trabalho pode ser uma alteração de configuração para um recurso definido no arquivo Bicep ou um novo conjunto de recursos que você precisa implantar. Sempre que inicias um novo trabalho, crias uma nova ramificação de funcionalidades.
Você cria uma ramificação de função a partir da ramificação principal. Ao criar uma ramificação, você garante que está começando a partir do estado atual do seu ambiente do Azure. Em seguida, você faz todas as alterações necessárias.
Como todas as alterações de código são confirmadas na ramificação do recurso, elas não interferem na ramificação principal do repositório. Se alguém da sua equipe precisar fazer uma alteração urgente na ramificação principal, ela poderá fazer isso em outra ramificação de recurso independente da sua.
Você também pode colaborar em ramificações de funcionalidades. Ao publicar e fazer push da sua branch de funcionalidades para o repositório partilhado, você e os membros da sua equipa podem trabalhar juntos numa alteração. Você também pode entregar um recurso para outra pessoa para completar quando você vai de férias.
Atualize as suas branches de funcionalidades
Enquanto a sua ramificação de funcionalidade está em desenvolvimento, outras funcionalidades podem ser integradas na ramificação principal do repositório. O resultado é que o ramo de funcionalidade e o ramo principal do projeto começarão a divergir. Quanto mais eles se afastam, mais difícil se torna fundir os dois ramos novamente em um ponto posterior, e mais conflitos de fusão você pode encontrar.
Você deve atualizar o seu ramo de funcionalidade regularmente para incorporar quaisquer alterações feitas na ramificação principal do repositório. Também é uma boa ideia atualizar o seu ramo funcional antes de começar a integrar esse ramo de volta ao ramo principal. Dessa forma, você garante que suas novas alterações possam ser mescladas na ramificação principal facilmente.
Gorjeta
Mescle a ramificação principal na sua ramificação de funcionalidade com frequência.
Utilize ramos de tamanho pequeno e de curta duração
Opte por branches de curta duração. Essa abordagem ajuda a evitar conflitos de mesclagem, reduzindo a quantidade de tempo que suas ramificações podem ficar fora de sincronia. Essa abordagem também torna mais fácil para seus colegas entenderem as alterações que você fez, o que é útil quando você precisa que alguém revise suas alterações.
Divida grandes blocos de trabalho em partes menores e crie um ramo de funcionalidade para cada uma. Quanto maior a funcionalidade, mais tempo será necessário para alguém trabalhar nela e mais tempo o ramo da funcionalidade permanecerá. Pode implementar as alterações menores em produção ao fundir cada ramo de funcionalidades e, gradualmente, construir o trabalho mais amplo.
Imagine que você está fazendo algumas alterações em um conjunto de código Bicep. Você está movendo algumas definições de recursos para módulos. Você também precisa adicionar alguns novos recursos aos seus arquivos Bicep. Pode ser uma boa ideia fazer primeiro toda a refatoração do módulo numa branch própria. Depois que os módulos são mesclados, você pode começar a trabalhar nas adições aos seus arquivos Bicep. Ao separar suas alterações, você mantém cada alteração — e seu ramo — pequena e fácil de entender.
Quando você trabalha dessa maneira, pode ser útil usar a palavra-chave if
para desabilitar a implantação de recursos até que eles estejam prontos. O código de exemplo a seguir mostra como você usaria a palavra-chave if
para criar um arquivo Bicep que define uma conta de armazenamento, mas desabilita a implantação da conta de armazenamento até concluir todas as alterações.
@description('Specifies whether the storage account is ready to be deployed.')
param storageAccountReady bool = false
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = if (storageAccountReady) {
name: storageAccountName
location: location
kind: 'StorageV2'
sku: {
name: 'Premium_LRS'
}
}
Você pode usar parâmetros para especificar valores diferentes para a variável storageAccountReady
em ambientes diferentes. Por exemplo, você pode definir o valor do parâmetro como true
para seu ambiente de teste e false
para seu ambiente de produção. Dessa forma, você pode experimentar a nova conta de armazenamento em seu ambiente de teste.
Nota
Na hora de ativar o recurso em produção, lembre-se de que você precisa seguir as seguintes etapas para que a alteração entre em vigor:
- Altere o valor do parâmetro.
- Reimplante seu arquivo Bicep.
Mesclando branches de funcionalidades
Quando terminar de trabalhar em uma ramificação de recurso, você precisará mesclá-la na ramificação principal do repositório. É uma boa prática rever as alterações feitas no ramo de funcionalidades antes de fundir. As solicitações pull permitem que você revise seu código. Você aprenderá mais sobre pull requests mais adiante neste módulo.
Proteções de ramificação
No GitHub, você pode configurar proteções de ramificação para a ramificação principal do repositório compartilhado. As proteções de ramo impõem regras como:
- Nenhuma alteração pode ser integrada na ramificação principal, exceto por meio de um pull request.
- As mudanças precisam ser revistas por pelo menos outras duas pessoas.
Se alguém tentar enviar uma confirmação diretamente para uma ramificação protegida, o envio falhará. Você aprenderá como aplicar proteções de ramificação na próxima unidade.
Políticas de sucursais
No Azure DevOps, você pode configurar políticas de ramificação para a ramificação principal do repositório compartilhado. As políticas de filial impõem regras como:
- Nenhuma alteração pode ser fundida na ramificação principal, exceto através de um pull request.
- As mudanças precisam ser revistas por pelo menos outras duas pessoas.
Se alguém tentar enviar uma confirmação diretamente para uma ramificação protegida, o envio falhará. Você aprenderá como aplicar políticas de filial na próxima unidade.
Outras estratégias de ramificação
Quando se colabora no código Bicep, pode-se utilizar várias estratégias de ramificação. Cada estratégia de ramificação tem benefícios e desvantagens.
O processo de que tu aprendeste até agora é uma versão da estratégia de desenvolvimento baseada em troncos. Nessa estratégia de ramificação, o trabalho é feito em ramos de funcionalidades de curta duração e, em seguida, é integrado em um único ramo principal. Você pode implantar automaticamente o conteúdo da ramificação principal do repositório compartilhado na produção sempre que uma alteração for mesclada, ou pode fazer alterações em lote e liberá-las em um cronograma, como todas as semanas. O desenvolvimento baseado em tronco é fácil de entender e permite a colaboração sem muita sobrecarga.
Algumas equipes separam o trabalho que concluíram do trabalho que implantaram na produção. Eles usam um ramo de desenvolvimento de longa duração como alvo para integrar as suas ramificações de funcionalidades. Eles fundem o desenvolvimento ramificação em seu ramo principal quando lançam alterações na produção.
Algumas outras estratégias de ramificação exigem criar ramificações de lançamento . Quando tiveres um conjunto de alterações pronto para implantar na produção, criarás um ramo de lançamento com as alterações a serem implantadas. Essas estratégias podem fazer sentido quando você implanta sua infraestrutura do Azure em uma cadência regular ou quando integra suas alterações com muitas outras equipes.
Outras estratégias de ramificação incluem Gitflow, GitHub Flow e GitLab Flow. Algumas equipes usam o GitHub Flow ou o GitLab Flow porque ele permite separar o trabalho de equipes diferentes, além de separar correções urgentes de bugs de outras alterações. Esses processos também podem permitir que separe os seus commits em diferentes lançamentos da sua solução, o que é chamado de cherry picking. No entanto, eles exigem mais gerenciamento para garantir que suas alterações sejam compatíveis entre si. A seção Resumo deste módulo fornece links para mais informações sobre essas estratégias de ramificação.
A estratégia de ramificação certa para sua equipe depende da maneira como ela trabalha, colabora e libera suas alterações. É uma boa ideia começar a partir de um processo simples, como o desenvolvimento baseado em tronco. Se você achar que sua equipe não pode trabalhar efetivamente usando esse processo, introduza gradualmente outras camadas de ramificação ou adote uma estratégia de ramificação; Mas esteja ciente de que, à medida que você adiciona mais ramificações, o gerenciamento do repositório se torna mais complexo.
Gorjeta
Independentemente da estratégia de ramificação usada, é bom usar políticas de ramificação para proteger a ramificação principal e usar solicitações pull para revisar suas alterações. Outras estratégias de ramificação também introduzem ramos importantes que você deve proteger.
Neste módulo, usamos o desenvolvimento baseado em tronco com ramificações de recursos, porque é fácil de usar.