Criar o pipeline
Nesta unidade, você acompanhará a equipe da Web da Tailspin na definição do pipeline de lançamento do site do Space Game.
Ao planejar um pipeline de lançamento, você geralmente começa identificando as fases (ou as divisões principais) desse pipeline. Normalmente, cada fase é mapeada para um ambiente. Por exemplo, no módulo anterior, o pipeline básico de Clara e Paulo tinha uma fase de Implantação que era mapeada para uma instância do Serviço de Aplicativo do Azure.
Neste módulo, você promove alterações de uma fase para a outra. Em cada fase, você implanta o site do Space Game no ambiente associado à fase.
Após definir quais fases são necessárias, considere como as alterações são promovidas de uma fase para a outra. Cada fase pode definir os critérios de sucesso que precisam ser atendidos antes que o build possa prosseguir. O Azure Pipelines ajuda de várias maneiras a controlar como e quando as alterações se movem no pipeline. Como um todo, essas abordagens são usadas para o gerenciamento de versão.
Nesta seção, você:
- Aprender as diferenças entre as fases de pipeline comuns, por exemplo, Build, Desenvolvimento, Testee Preparo.
- Entender como usar gatilhos de implantação manual, agendada e contínua permitirá controlar quando um artefato passa para a próxima fase do pipeline.
- Ver como uma aprovação de versão pausa o pipeline até que um aprovador aceite ou rejeite a versão.
A reunião
Toda a equipe da Web da Tailspin está reunida. Em Create a release pipeline in Azure Pipelines, a equipe planejou as tarefas do sprint atual. Cada tarefa está relacionada à criação do pipeline de lançamento do site do Game Space.
Lembre-se de que a equipe optou por estas cinco tarefas para seu sprint:
- Criar um pipeline de várias fases.
- Conectar o aplicativo Web a um banco de dados.
- Automatizar os testes de qualidade.
- Automatizar os testes de desempenho.
- Aprimorar a cadência das versões.
A equipe se reúne para falar sobre a primeira tarefa, Create a multistage pipeline. Depois que a equipe define o pipeline, ele pode passar de sua prova básica de conceito para um pipeline de lançamento que inclui mais estágios, verificações de qualidade e aprovações.
Marina e Pedro assistem enquanto Paulo e Clara demonstram o pipeline de lançamento uma segunda vez. Eles veem que o artefato é compilado e instalado no Serviço de Aplicativo.
Quais fases de pipeline são necessárias?
Quando você quer implementar um pipeline de lançamento, primeiro é importante identificar quais fases são necessárias. As fases escolhidas dependem de seus requisitos. Vamos acompanhar a equipe enquanto eles decidem sobre suas fases.
Pedro: OK, entendi a ideia de um pipeline automatizado. Gosto de como é fácil implantar no Azure. Mas o que fazemos depois dessa demonstração? Precisamos de algo que possamos de fato usar em nossas versões.
Marina: Certo. Precisamos adicionar outras fases. Por exemplo, atualmente, não temos lugar para um estágio de teste.
Pedro: Além disso, precisamos de uma fase na qual possamos mostrar novos recursos para a gerência. Não posso enviar nada para produção sem aprovação da gerência.
Paulo: Com certeza. Agora que ele estamos atualizados sobre o que um pipeline de lançamento pode fazer, como fazemos esse pipeline fazer o que precisamos?
Clara: Vamos esboçar nossos requisitos para nos ajudar a planejar os próximos passos. Vamos começar com o que temos.
Clara vai até o quadro e esboça o pipeline existente.
Clara: A fase de Build compila o código-fonte e produz um pacote. Em nosso caso, o pacote é um arquivo .zip. A fase de Implantação instala o arquivo .zip, que é o site do Game Space, em uma instância do Serviço de Aplicativo. O que está faltando no pipeline de lançamento?
Adicionar a fase de Desenvolvimento
Paulo: Eu posso ter algum viés, mas acho que precisamos de uma fase de Desenvolvimento. Essa fase deve ser a primeira parada do artefato após ser compilado. Os desenvolvedores nem sempre podem executar o serviço inteiro no ambiente de desenvolvimento local. Por exemplo, um sistema de comércio eletrônico pode exigir um site, o banco de dados de produtos e um sistema de pagamento. Precisamos de uma fase que inclua tudo de que o aplicativo precisa.
Em nosso caso, o recurso de placar de líderes do site do Space Game lê pontuações altas de uma fonte externa. No momento, ele lê pontuações fictícias de um arquivo. A configuração de uma fase de Desenvolvimento nos daria um ambiente no qual integrar o aplicativo Web a um banco de dados real. Esse banco de dados ainda poderia conter pontuações fictícias, mas nos aproximaria um pouco mais de nosso aplicativo final.
Clara: Gostei. Ainda não vamos integrar com um banco de dados real. Mas, em uma fase de Desenvolvimento, podemos implantar em um ambiente onde é possível adicionar um banco de dados.
Clara atualiza o desenho no quadro. Ela substitui "Implantação" por "Desenvolvimento" para mostrar a fase de Desenvolvimento.
Paulo: Você traz um aspecto interessante. Nós compilamos o aplicativo cada vez que efetuamos push de uma alteração para o GitHub. Isso significa que cada build é promovido para a fase de Desenvolvimento após ser concluído?
Clara: Compilar continuamente nos fornece comentários importantes sobre a integridade de nosso build e de nossos testes. Mas queremos promover para a fase de Desenvolvimento somente quando mesclarmos o código a um branch central: seja o branch principal ou outro branch de lançamento. Atualizarei o desenho para mostrar esse requisito.
Clara: Acho que essa promoção será fácil de realizar. Podemos definir uma condição de promover para a fase de Desenvolvimento somente quando as alterações ocorrerem em um branch de lançamento.
O que são condições?
No Azure Pipelines, use uma condição para executar a tarefa ou o trabalho com base no estado do pipeline. Você trabalhou com condições em módulos anteriores.
Lembre-se de que algumas das condições que você pode especificar são:
- Somente quando todas as tarefas dependentes anteriores tiverem êxito.
- Mesmo que uma dependência anterior tenha falhado, a menos que a execução tenha sido cancelada.
- Mesmo que uma dependência anterior tenha falhado, mesmo que a execução tenha sido cancelada.
- Somente quando uma dependência anterior tiver falhado.
- Alguma condição personalizada.
Este é um exemplo básico:
steps:
- script: echo Hello!
condition: always()
A condição always()
faz com que essa tarefa imprima "Olá!" incondicionalmente, mesmo se as tarefas anteriores falharem.
Esta condição será usada se você não especificar uma:
condition: succeeded()
A função interna succeeded()
verifica se a tarefa anterior foi bem-sucedida. Se a tarefa anterior tiver falhado, essa tarefa e as posteriores que usam a mesma condição serão ignoradas.
Aqui, você deseja criar uma condição que especifica que:
- A tarefa anterior foi bem-sucedida.
- O nome do GIT branch atual é release.
Para criar essa condição, você usa a função and()
interna. Essa função verifica se cada uma das condições é verdadeira. Se alguma condição não for verdadeira, a condição global falhará.
Para obter o nome do branch atual, use a variável Build.SourceBranchName
interna. Você pode acessar as variáveis dentro de uma condição de algumas maneiras. Aqui, você usa a sintaxe variables[]
.
Para testar o valor da variável, você pode usar a função eq()
interna. Essa função verifica se os argumentos são iguais.
Com isso em mente, você aplica a condição para executar a fase de Desenvolvimento somente quando o nome do branch atual for "release":
condition: |
and
(
succeeded(),
eq(variables['Build.SourceBranchName'], 'release')
)
A primeira condição na função and()
verifica se a tarefa anterior foi bem-sucedida. A segunda condição verifica se o nome do branch atual é igual a release.
No YAML, você usa a sintaxe de pipe (|
) para definir uma cadeia de caracteres que abrange várias linhas. Você poderia definir a condição em uma única linha, mas nós a escrevemos dessa maneira para torná-la mais legível.
Observação
Neste módulo, usamos o branch release como exemplo. Você pode combinar condições para definir o comportamento de que precisa. Por exemplo, você pode criar uma condição que executa a fase somente quando o build é disparado por uma solicitação de pull para o branch principal.
Na próxima unidade, ao configurar o estágio Dev, você trabalhará com um exemplo mais completo.
Para ver uma descrição mais completa das condições no Azure Pipelines, confira a documentação sobre expressões.
Clara: Usando condições, você pode controlar quais alterações são promovidas para quais fases. Podemos produzir um artefato de compilação para qualquer alteração para validar o build e confirmar sua integridade. Quando estivermos prontos, poderemos mesclar essas alterações em um branch de lançamento e promover o build para a fase de Desenvolvimento.
Adicionar a fase de Teste
Clara: Até agora, temos as fases de Build e Desenvolvimento. Qual é o próximo?
Marina: Podemos adicionar a fase de Teste em seguida? Parece ser o momento certo para testar as alterações mais recentes.
Clara adiciona a fase de Teste ao desenho no quadro.
Marina: Uma preocupação que tenho é a frequência com que preciso testar o aplicativo. Um email me notifica sempre que Clara ou Paulo fazem uma alteração. As alterações acontecem ao longo do dia e eu nunca sei quando participar. Acho que gostaria de ver um build uma vez por dia, talvez quando chego ao escritório. Podemos fazer isso?
Paulo: Claro. Por que não implantamos para Teste fora do horário de trabalho? Poderíamos enviar um build para você todos os dias às 3h.
Clara: parece uma boa ideia. Sempre podemos disparar o processo manualmente se for necessário. Por exemplo, poderemos dispará-lo se precisarmos que você verifique uma correção de bug importante imediatamente.
Mara atualiza o desenho para mostrar que o build passa da fase de Desenvolvimento para a fase de Teste às 3h.
O que são gatilhos?
Marina: Estou mais tranquila agora que sabemos como uma fase passa para outra. Mas como controlamos quando uma fase é executada?
Clara: No Azure Pipelines, podemos usar gatilhos. Um gatilho define quando uma fase é executada. O Azure Pipelines fornece alguns tipos de gatilhos. Estas são nossas opções:
- Gatilho de CI (integração contínua)
- Gatilho de PR (solicitação de pull)
- Gatilho de agendamento
- Gatilho de conclusão do build
Os gatilhos de CI e de PR permitem controlar quais branches participam do processo geral. Por exemplo, você quer compilar o projeto quando uma alteração é feita em qualquer branch. Um gatilho de agendamento inicia uma implantação em um momento específico. Um gatilho de conclusão de build executa um build quando outro, como o de um componente dependente, é concluído com êxito. Parece que queremos um gatilho de agendamento.
O que são gatilhos de agendamento?
Um gatilho de agendamento usa a sintaxe cron para fazer com que um build seja executado segundo uma agenda definida.
Em sistemas Unix e Linux, cron é uma forma popular de agendar trabalhos para execução em um intervalo de tempo definido ou em um momento específico. No Azure Pipelines, os gatilho de agendamento usam a sintaxe cron para definir quando uma fase é executada.
Uma expressão cron inclui campos que correspondem a determinados parâmetros de tempo. Estes são os campos:
mm HH DD MM DW
\ \ \ \ \__ Days of week
\ \ \ \____ Months
\ \ \______ Days
\ \________ Hours
\__________ Minutes
Por exemplo, esta expressão cron descreve "3h, todos os dias”: 0 3 * * *
Uma expressão cron pode incluir caracteres especiais para especificar uma lista ou um intervalo de valores. Neste exemplo, o asterisco (*) corresponde a todos os valores dos campos Dias, Meses e Dias da semana.
Em outras palavras, esta expressão cron é lida como:
- No minuto 0,
- Na terceira hora,
- Em qualquer dia do mês,
- Em qualquer mês,
- Em qualquer dia da semana,
- Executar o trabalho
Para especificar 3h somente de segunda a sexta-feira, você usaria esta expressão: 0 3 * * 1-5
Observação
O fuso horário para agendamentos cron é UTC (Tempo Universal Coordenado) e, portanto, neste exemplo, 3h significa 3h UTC. Na prática, talvez você queira ajustar a hora em sua agenda cron em relação ao UTC para que o pipeline seja executado na hora esperada por você e sua equipe.
Para configurar um gatilho de agendamento no Azure Pipelines, você precisa de uma seção schedules
no arquivo YAML. Veja um exemplo:
schedules:
- cron: '0 3 * * *'
displayName: 'Deploy every day at 3 A.M.'
branches:
include:
- release
always: false
Nesta seção de schedules
:
cron
especifica a expressão cron.branches
especifica a implantação somente do branchrelease
.always
especifica se a implantação deve ser executada incondicionalmente (true
) ou somente quando o branchrelease
tiver sido alterado desde a última execução (false
). Aqui, você especificafalse
porque precisa implantar somente quando o branchrelease
tiver sido alterado desde a última execução.
Todo o pipeline é executado quando o Azure Pipelines executa um gatilho de agendamento. O pipeline também é executado sob outras condições, por exemplo, quando você efetua push de uma alteração para o GitHub. Para executar uma fase somente em resposta a um gatilho de agendamento, você pode usar uma condição que verifica se o motivo do build é uma execução agendada.
Veja um exemplo:
- stage: 'Test'
displayName: 'Deploy to the Test environment'
condition: and(succeeded(), eq(variables['Build.Reason'], 'Schedule'))
Essa fase, Test
, é executada somente quando a fase anterior é bem-sucedida e a variável de pipeline Build.Reason
interna é igual a Schedule
.
Você verá um exemplo mais completo mais adiante neste módulo.
Marina: Gostei. Não preciso nem selecionar a versão manualmente e instalá-la. Está pronto para mim.
Paulo: E lembre-se, se depois quisermos automatizar mais, poderemos. Nada é definitivo. O pipeline evolui conforme nos aprimoramos e aprendemos.
Adicionar a fase de Preparo
Pedro: É minha vez. Preciso de uma fase para fazer mais testes de estresse. Também precisamos de uma fase em que possamos demonstrar para a gerência para conseguir a aprovação deles. Por enquanto, podemos combinar essas duas necessidades em uma fase que podemos chamar de Preparo.
Paulo: Muito bem, Pedro. Ter um ambiente de preparo ou pré-produção é importante. Esse ambiente de preparo costuma ser a última parada antes que um recurso ou correção de bug chegue a nossos usuários.
Clara adiciona Preparo ao desenho no quadro.
Marina: Usamos um gatilho de agendamento para promover alterações da fase de Desenvolvimento para a de Teste. Mas como promover as alterações de Teste para Preparo? Essa promoção também precisa ocorrer segundo uma agenda?
Clara: Acho que a melhor maneira de fazer isso seria uma aprovação de versão. Uma aprovação de versão permite promover manualmente uma alteração de uma fase para o outro.
Marina: É disso mesmo que eu preciso! Uma aprovação de versão me daria tempo para testar as últimas alterações antes de apresentarmos o build à gerência. Posso promover o build quando eu estiver pronta.
Clara atualiza o desenho para mostrar que o build passa do Teste para o Preparo somente após a aprovação de Marina.
Pedro: Eu diria que também podemos usar aprovações de versão para promover do Preparo para a Produção após a aprovação da gerência. Nunca consigo prever quanto tempo isso leva. Após a autorização, posso aprovar a versão e promovê-la para a produção manualmente. Mas como as aprovações de versão funcionam?
O que são aprovações de versão?
Uma aprovação de versão é uma forma de pausar o pipeline até que um aprovador aceite ou rejeite a versão. Para definir seu fluxo de trabalho de lançamento, você pode combinar aprovações, condições e gatilhos.
Lembre-se de que, em Create a release pipeline in Azure Pipelines, você definiu um ambiente na configuração do pipeline para representar seu ambiente de implantação. Veja um exemplo de seu pipeline existente:
- stage: 'Deploy'
displayName: 'Deploy the web application'
dependsOn: Build
jobs:
- deployment: Deploy
pool:
vmImage: 'ubuntu-20.04'
environment: dev
variables:
- group: Release
Seu ambiente pode incluir critérios específicos para sua versão. Os critérios podem especificar quais pipelines podem ser implantados nesse ambiente e quais aprovações humanas são necessárias para promover a versão de uma fase para a outra.
Posteriormente neste módulo, você definirá o ambiente de preparo e atribuirá a si mesmo como um aprovador para promover o aplicativo Web do Space Game do estágio de teste para o de preparo.
Automatizar exatamente o que for necessário
O Azure Pipelines proporciona a você a flexibilidade de automatizar algumas fases enquanto controla manualmente outros que não estão prontos para automação.
Pedro: Fico feliz que possamos definir os critérios que promovem as alterações de uma fase para a outra. Mas definimos alguns critérios manuais em nosso pipeline. Eu achava que, em DevOps, devíamos automatizar tudo.
Clara: Essa é uma boa observação. Em DevOps, realmente automatizamos tarefas repetitivas e propensas a erros. Às vezes, a intervenção humana é necessária. Por exemplo, recebemos aprovação da gerência antes de lançarmos novos recursos. Conforme ganharmos mais experiência com nossas implantações automatizadas, poderemos automatizar mais de nossas etapas manuais para acelerar o processo. Por exemplo, podemos automatizar mais verificações de qualidade no estágio de teste, para que a Amita não precise aprovar cada build.
Pedro: Parece ótimo. Vamos seguir esse plano por enquanto e veremos como acelerar o sistema mais tarde.
Marina: Falando em nosso plano, podemos resumir as próximas etapas?
O plano
Vamos analisar o plano da equipe da Tailspin conforme eles passam para as próximas etapas.
Clara: Este é o pipeline de lançamento que queremos criar.
Clara aponta para o quadro.
Clara: Para resumir, nossas etapas são:
- Produzir um artefato de compilação sempre que efetuamos push de uma alteração para o GitHub. Essa etapa ocorre na fase de Build.
- Promover o artefato de compilação para a fase de Desenvolvimento. Essa etapa ocorre automaticamente quando a fase de build é bem-sucedida e a alteração está no branch de lançamento.
- Promova o artefato de build ao estágio de Teste a cada manhã, às 3h Usamos um gatilho agendado para promover o artefato de build automaticamente.
- Promover o artefato de compilação para o Preparo após Marina testar e aprovar o build. Usamos uma aprovação de versão para promover o artefato de compilação.
Depois que a gerência aprovar o build, poderemos implantar o artefato de compilação em um ambiente de produção.
Marina: Vai ser difícil? Parece muito trabalho.
Clara: Não acho que seja tão ruim. Cada fase é separada de todas as outras. As fases são discretas. Cada uma delas tem o próprio conjunto de tarefas. Por exemplo, o que acontece na fase de Teste permanece na fase de Teste.
Cada fase de implantação no pipeline também tem o próprio ambiente. Por exemplo, quando implantamos o aplicativo para Desenvolvimento ou Teste, o ambiente é uma instância do Serviço de Aplicativo.
Por fim, testamos apenas uma versão por vez. Nunca alteramos as versões no meio do pipeline. Usamos a mesma versão nas fases de Desenvolvimento e de Preparo, e cada versão tem o próprio número de versão. Se a versão apresentar alguma falha em uma das fases, nós a corrigiremos e compilaremos novamente com um novo número de versão. Essa nova versão passa pelo pipeline desde o início.
Algumas observações sobre qualidade
Você acabou de ver a equipe projetar um pipeline que leva seu aplicativo desde o build até o preparo. O objetivo desse pipeline não é apenas facilitar a vida deles. É garantir a qualidade do software que eles estão fornecendo aos clientes.
Como medir a qualidade de seu processo de lançamento? A qualidade do processo de lançamento não pode ser medida diretamente. O que você pode medir é o quanto o processo funciona bem. Se você estiver constantemente alterando o processo, isso pode ser uma indicação de que há algo errado. Versões que falham consistentemente em um ponto específico do pipeline também podem indicar que há um problema com o processo de lançamento.
As versões sempre falham em um dia ou hora específica? Elas sempre falham após você implantar em um ambiente específico? Observe esses e outros padrões para ver se alguns aspectos do processo de lançamento são dependentes ou relacionados.
Uma boa maneira de controlar a qualidade do processo de lançamento é criar visualizações da qualidade das versões. Por exemplo, adicione um widget de painel que mostra o status de cada versão.
Quando quiser medir a qualidade de uma versão em si, você poderá executar todos os tipos de verificações dentro do pipeline. Por exemplo, você pode executar diferentes tipos de testes, como testes de carga e testes de interface do usuário, enquanto executa seu pipeline.
Usar um portão de qualidade também é uma ótima maneira de verificar a qualidade da versão. Há vários portões de qualidade diferentes. Por exemplo, portões de item de trabalho podem verificar a qualidade de seu processo de requisitos. Você também pode adicionar mais verificações de segurança e conformidade. Por exemplo, você está em conformidade com o princípio dos quatro olhos ou tem uma rastreabilidade adequada?
À medida que você avança nesse roteiro de aprendizagem, você vê muitas dessas técnicas colocadas em prática.
Por fim, ao criar um processo de versão de qualidade, pense em que tipo de documentação ou notas de versão você precisa fornecer ao usuário. Manter a documentação atualizada pode ser difícil. Talvez seja melhor usar uma ferramenta, como o Azure DevOps Release Notes Generator. O gerador é um aplicativo de funções que contém uma função disparada por HTTP. Usando o Armazenamento de Blobs do Azure, ele cria um arquivo Markdown sempre que uma versão é criada no Azure DevOps.