Criar o pipeline

Concluído

Nesta unidade, você segue a equipe da web da Tailspin enquanto eles definem seu pipeline de lançamento para o site do Space Game .

Quando você planeja um pipeline de liberação, geralmente começa identificando os estágios, ou divisões principais, desse pipeline. Cada estágio normalmente é mapeado para um ambiente. Por exemplo, no módulo anterior, o pipeline básico de Andy e Mara tinha um estágio de Implantação mapeado para uma instância do Serviço de Aplicativo do Azure.

Neste módulo, você promove mudanças de um estágio para o outro. Dentro de cada estágio, você implanta o site do Space Game no ambiente associado a esse estágio.

Depois de definir quais estágios você precisa, considere como as mudanças são promovidas de um estágio para o próximo. Cada estágio pode definir os critérios de sucesso que devem ser atendidos antes que a compilação possa passar para o próximo estágio. O Azure Pipelines fornece várias maneiras de ajudá-lo a controlar como e quando as alterações passam pelo pipeline. Como um todo, essas abordagens são usadas para o gerenciamento de versões.

Nesta secção, pode:

  • Aprenda as diferenças entre os estágios comuns do pipeline, como Build, Dev, Test e Staging.
  • Entenda como usar gatilhos de implantação manuais, programados e contínuos para controlar quando um artefato passa para o próximo estágio no pipeline.
  • Veja 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 web da Tailspin está reunida. Em Criar um pipeline de lançamento com o Azure Pipelines, a equipe planejou suas tarefas para o sprint atual. Cada tarefa está relacionada à construção de seu pipeline de lançamento para o site do Space Game .

Lembre-se que a equipa decidiu estas cinco tarefas para o seu sprint:

  • Crie um pipeline de vários estágios.
  • Conecte o aplicativo Web a um banco de dados.
  • Automatize testes de qualidade.
  • Automatize testes de desempenho.
  • Melhore a cadência de lançamento.

A equipe se reúne para falar sobre a primeira tarefa, Criar um pipeline de vários estágios. Depois que a equipe define o pipeline, ele pode passar de sua prova básica de conceito para um pipeline de liberação que inclui mais estágios, verificações de qualidade e aprovações.

Amita e Tim estão assistindo Andy e Mara demonstrarem o pipeline de lançamento uma segunda vez. Eles veem que o artefato foi criado e instalado no Serviço de Aplicativo.

Quais estágios de pipeline você precisa?

Quando você deseja implementar um pipeline de liberação, é importante primeiro identificar quais estágios você precisa. As etapas que você escolhe dependem de suas necessidades. Vamos acompanhar a equipe enquanto eles decidem suas etapas.

Tim: OK, eu entendo a ideia de um pipeline automatizado. Gosto de como é fácil implantar no Azure. Mas para onde vamos a partir desta demonstração? Precisamos de algo que possamos realmente usar para nossos lançamentos.

Amita: Certo! Precisamos acrescentar outras etapas. Por exemplo, neste momento, não temos lugar para uma fase de testes.

Tim: Além disso, precisamos de um palco onde possamos mostrar novas funcionalidades para a gestão. Não posso enviar nada para a produção sem a aprovação da gerência.

Andy: Com certeza! Agora que está atualizado sobre o que um pipeline de liberação faz, como podemos fazer com que esse pipeline faça o que precisamos?

Mara: Vamos esboçar nossos requisitos para nos ajudar a planejar nossos próximos passos. Comecemos pelo que temos.

Mara se move para o quadro branco e esboça o pipeline existente.

Diagram of the whiteboard illustrating build and dev stages. Build stage produces .zip file. Dev stage deploys .zip file to Azure App Service.

Mara: O estágio Build constrói o código-fonte e produz um pacote. No nosso caso, esse pacote é um arquivo .zip . O estágio Implantar instala o arquivo .zip, que é o site do Jogo Espacial, em uma instância do Serviço de Aplicativo. O que está faltando em nosso pipeline de lançamento?

Adicionar o estágio de desenvolvimento

Andy: Posso ser tendencioso, mas acho que precisamos de um estágio de Dev . Esta etapa deve ser a primeira parada para o artefato depois de construído. Os desenvolvedores nem sempre podem executar todo o serviço a partir de seu ambiente de desenvolvimento local. Por exemplo, um sistema de comércio eletrônico pode exigir um site, banco de dados de produtos e sistema de pagamento. Precisamos de um palco que inclua tudo o que o aplicativo precisa.

No nosso caso, o recurso de tabela de classificação do site Space Game lê pontuações altas de uma fonte externa. Neste momento, lê partituras fictícias de um ficheiro. Configurar um estágio de desenvolvimento nos daria um ambiente onde podemos integrar o aplicativo Web com um banco de dados real. Esse banco de dados ainda pode conter pontuações fictícias, mas nos deixa um passo mais perto do nosso aplicativo final.

Mara: Eu gosto. Ainda não nos integraremos com uma base de dados real. Mas em um estágio de desenvolvimento, podemos implantar em um ambiente onde podemos adicionar um banco de dados.

Mara atualiza seu desenho no quadro branco. Ela substitui "Deploy" por "Dev" para mostrar o estágio de Dev .

Diagram that shows the whiteboard illustrating build and dev stages. Build stage produces .zip file. Dev stage deploys .zip file to Azure App Service.

Andy: Você traz um ponto interessante. Criamos o aplicativo cada vez que enviamos uma alteração para o GitHub. Isso significa que cada compilação é promovida para o estágio de desenvolvimento depois de concluída?

Mara: Construir continuamente nos dá feedback importante sobre nossa saúde de construção e teste. Mas queremos promover para o estágio de desenvolvimento apenas quando mesclamos o código em algum ramo central: principal ou outro ramo de lançamento. Vou atualizar o desenho para mostrar esse requisito.

Diagram that shows whiteboard illustrating build and dev stages. A condition promotes to the Dev stage only when changes happen on a release branch.

Mara: Acho que essa promoção será fácil de realizar. Podemos definir uma condição que promova para o estágio de desenvolvimento somente quando as alterações acontecem em uma ramificação de lançamento.

O que são condições?

No Azure Pipelines, use uma condição para executar uma tarefa ou trabalho com base no estado do pipeline. Você trabalhou com condições em módulos anteriores.

Lembre-se, algumas das condições que você pode especificar são:

  • Apenas quando todas as tarefas dependentes anteriores tiverem sido bem-sucedidas.
  • 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.
  • Apenas quando uma dependência anterior falhou.
  • Alguma condição personalizada.

Eis um exemplo básico:

steps:
  - script: echo Hello!
    condition: always()

A always() condição faz com que esta tarefa imprima "Olá!" incondicionalmente, mesmo que as tarefas anteriores tenham falhado.

Esta condição é usada se você não especificar uma condição:

condition: succeeded()

A succeeded() função interna verifica se a tarefa anterior foi bem-sucedida. Se a tarefa anterior falhar, esta tarefa e as tarefas posteriores que usam a mesma condição serão ignoradas.

Aqui você deseja criar uma condição que especifique:

  • A tarefa anterior foi bem sucedida.
  • O nome da ramificação atual do Git é release.

Para compilar esta condição, utilize a função and() incorporada. Esta função verifica se cada uma das suas condições é verdadeira. Se alguma condição não for verdadeira, a condição geral falhará.

Para obter o nome da ramificação atual, use a variável interna Build.SourceBranchName . Você pode acessar variáveis dentro de uma condição de algumas maneiras. Aqui você usa a variables[] sintaxe.

Para testar o valor de uma variável, pode utilizar a função incorporada eq(). Esta função verifica se os respetivos argumentos são iguais.

Com isso em mente, você aplica essa condição para executar o estágio de desenvolvimento somente quando o nome da ramificação atual é "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 da ramificação atual é igual a release.

No YAML, você usa a sintaxe pipe (|) para definir uma cadeia de caracteres que abrange várias linhas. Pode definir a condição numa única linha, mas vamos escrevê-la desta forma para que seja mais legível.

Nota

Neste módulo, usamos a ramificação de lançamento como exemplo. Você pode combinar condições para definir o comportamento de que precisa. Por exemplo, você pode criar uma condição que executa o estágio somente quando a compilação é acionada por uma solicitação pull na ramificação principal .

Na próxima unidade, ao configurar o estágio de desenvolvimento , você trabalha com um exemplo mais completo.

Para obter uma descrição mais completa das condições no Azure Pipelines, consulte a documentação de expressões.

Mara: Usando condições, você pode controlar quais mudanças são promovidas para quais estágios. Podemos produzir um artefato de construção para qualquer alteração para validar nossa compilação e confirmar que ela está saudável. Quando estivermos prontos, podemos mesclar essas alterações em uma ramificação de lançamento e promover essa compilação para o estágio de desenvolvimento .

Adicionar o estágio de teste

Mara: Até agora, temos as etapas de Build e Dev . O que vem a seguir?

Amita: Podemos adicionar a próxima etapa de teste ? Esse parece ser o lugar certo para eu testar as últimas mudanças.

Mara adiciona o estágio de teste ao seu desenho no quadro branco.

Diagram that shows the whiteboard illustrating build, dev and test stages. The Test stage deploys the build to Azure App Service.

Amita: Uma preocupação que tenho é a frequência com que preciso testar o aplicativo. Um e-mail me notifica sempre que Mara ou Andy faz uma alteração. As mudanças acontecem ao longo do dia, e eu nunca sei quando entrar. Acho que gostaria de ver uma construção uma vez por dia, talvez quando chegar ao escritório. Podemos fazê-lo?

Andy: Claro. Por que não implantamos para testar fora do horário de expediente? Digamos que lhe enviamos uma compilação todos os dias às 3 da manhã.

Mara: Isso soa bem. Podemos sempre acionar manualmente o processo também, se necessário. Por exemplo, podemos acioná-lo se precisarmos que você verifique uma correção de bug importante imediatamente.

Mara atualiza seu desenho para mostrar que a construção passa do estágio Dev para o estágio Test às 3 da manhã todas as manhãs.

Diagram that shows the whiteboard showing Build, Dev, and Test stages. The schedule promotes the change from Dev to Test at 3 A.M. each morning.

O que são gatilhos?

Amita: Estou me sentindo melhor agora que sabemos como uma etapa se move para outra. Mas como controlar quando uma etapa corre?

Mara: No Azure Pipelines, podemos usar gatilhos. Um gatilho define quando um estágio é executado. O Azure Pipelines fornece alguns tipos de gatilhos. Aqui estão as nossas escolhas:

  • Gatilho de integração contínua (CI)
  • Gatilho de solicitação pull (PR)
  • Gatilho programado
  • Gatilho de conclusão de construção

Os gatilhos de CI e RP permitem controlar quais filiais participam do processo geral. Por exemplo, você deseja criar o projeto quando uma alteração é feita em qualquer ramificação. Um gatilho agendado inicia uma implantação em um momento específico. Um gatilho de conclusão de compilação executa uma compilação quando outra compilação, como uma para um componente dependente, é concluída com êxito. Parece que queremos um gatilho programado.

O que são gatilhos agendados?

Um gatilho agendado usa a sintaxe cron para fazer com que uma compilação seja executada em um cronograma definido.

Em sistemas Unix e Linux, cron é uma maneira popular de agendar trabalhos para serem executados em um intervalo de tempo definido ou em um horário específico. No Azure Pipelines, os gatilhos agendados usam a sintaxe cron para definir quando um estágio é executado.

Uma expressão cron inclui campos que correspondem a determinados parâmetros de tempo. Aqui estão os campos:

mm HH DD MM DW
 \  \  \  \  \__ Days of week
  \  \  \  \____ Months
   \  \  \______ Days
    \  \________ Hours
     \__________ Minutes

Por exemplo, esta expressão cron descreve "3 A.M. todos os dias": 0 3 * * *

Uma expressão cron pode incluir caracteres especiais para especificar uma lista de valores ou um intervalo de valores. Neste exemplo, o asterisco (*) corresponde a todos os valores dos campos Dias, Meses e Dias da semana.

Dito de outra forma, esta expressão cron lê-se como:

  • Ao minuto 0,
  • À terceira hora,
  • Em qualquer dia do mês,
  • Em qualquer mês,
  • Em qualquer dia da semana,
  • Executar a tarefa

Para especificar 3 horas da manhã apenas nos dias de segunda a sexta-feira, você usaria esta expressão: 0 3 * * 1-5

Nota

O fuso horário para horários cron é Tempo Universal Coordenado (UTC), portanto, neste exemplo, 3 A.M. refere-se a 3 A.M. em UTC. Na prática, você pode querer ajustar o tempo em sua programação cron em relação ao UTC para que o pipeline seja executado no horário esperado para você e sua equipe.

Para configurar um gatilho agendado no Azure Pipelines, você precisa de uma schedules seção em seu arquivo YAML. Eis um exemplo:

schedules:
- cron: '0 3 * * *'
  displayName: 'Deploy every day at 3 A.M.'
  branches:
    include:
    - release
  always: false

Nesta schedules secção:

  • cron especifica a expressão cron.
  • branches Especifica para implantar somente a partir da release ramificação.
  • alwaysEspecifica se a implantação deve ser executada incondicionalmente () ou somente quando a ramificação tiver sido alterada desde a release última execução ().truefalse Aqui, você especifica false porque precisa implantar somente quando a ramificação tiver sido alterada desde a release última execução.

O pipeline inteiro é executado quando o Azure Pipelines executa um gatilho agendado. O pipeline também é executado sob outras condições, como quando você envia uma alteração para o GitHub. Para executar um estágio somente em resposta a um gatilho agendado, você pode usar uma condição que verifica se o motivo da compilação é uma execução agendada.

Eis um exemplo:

- stage: 'Test'
  displayName: 'Deploy to the Test environment'
  condition: and(succeeded(), eq(variables['Build.Reason'], 'Schedule'))

Este estágio, , Testé executado somente quando o estágio anterior é bem-sucedido e a variável de pipeline interna Build.Reason é Scheduleigual a .

Você verá um exemplo mais completo mais adiante neste módulo.

Amita: Eu gosto disso. Eu nem preciso pegar a versão manualmente e instalá-la. Está pronto para mim.

Andy: E lembre-se, se quisermos automatizar mais tarde, podemos. Nada está escrito em pedra. O pipeline evolui à medida que melhoramos e aprendemos.

Adicionar o estágio de preparo

Tim: É a minha vez. Preciso de um estágio para executar mais testes de stress. Também precisamos de uma etapa em que possamos demonstrar à gerência para obter sua aprovação. Por enquanto, podemos combinar essas duas necessidades em um estágio que podemos chamar de encenação.

Andy: Bem dito, Tim. Ter um ambiente de preparação ou pré-produção é importante. Esse ambiente de preparação geralmente é a última parada antes que um recurso ou correção de bug chegue aos nossos usuários.

Mara acrescenta encenação ao seu desenho no quadro branco.

Diagram where the whiteboard is showing the Build, Dev, Test, and Staging stages. The Staging stage deploys the build to Azure App Service.

Amita: Usamos um gatilho programado para promover mudanças do estágio de desenvolvimento para o estágio de teste. Mas como promover mudanças de teste para preparação? Essa promoção também tem que acontecer dentro de um cronograma?

Mara: Acho que a melhor maneira de lidar com isso seria uma aprovação de lançamento. Uma aprovação de liberação permite que você promova manualmente uma alteração de um estágio para o seguinte.

Amita: Parece exatamente disso que eu preciso! Uma aprovação de lançamento me daria tempo para testar as mudanças mais recentes antes de apresentarmos a compilação ao gerenciamento. Posso promover a compilação quando estiver pronto.

Mara atualiza seu desenho para mostrar que a construção passa de Teste para Encenação apenas quando Amita aprova.

Diagram where the whiteboard shows the Build, Dev, Test, and Staging stages. Changes move from Test to Staging only after approval.

Tim: Eu também poderia imaginar que usássemos aprovações de lançamento para promover desde a preparação até a produção após a aprovação da gerência. Nunca posso prever quanto tempo isso demora. Depois que eles assinarem, posso aprovar a liberação e promovê-la para produção manualmente. Mas como funcionam as aprovações de liberação?

O que são aprovações de lançamento?

Uma aprovação de liberação é uma maneira de pausar o pipeline até que um aprovador aceite ou rejeite a versão. Para definir seu fluxo de trabalho de liberação, você pode combinar aprovações, condições e gatilhos.

Lembre-se de que, em Criar um pipeline de liberação com o Azure Pipelines, você definiu um ambiente em sua configuração de pipeline para representar seu ambiente de implantação. Aqui está um exemplo do 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 liberaçã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 liberação de um estágio para o outro.

Mais adiante neste módulo, você define o ambiente de preparo e atribui-se como aprovador para promover o aplicativo Web do Jogo Espacial do estágio de teste ao preparo.

Automatize o mínimo ou o quanto precisar

O Azure Pipelines oferece a flexibilidade de automatizar alguns estágios enquanto controla manualmente os estágios que não estão prontos para automação.

Tim: Gosto de como podemos definir os critérios que promovem mudanças de uma etapa para outra. Mas definimos alguns critérios manuais em nosso pipeline. Eu pensei que DevOps era sobre automatizar tudo.

Mara: Você levanta um bom ponto. DevOps é realmente sobre automatizar tarefas repetitivas e propensas a erros. Por vezes, é necessária a intervenção humana. Por exemplo, obtemos aprovação da gerência antes de lançarmos novos recursos. À medida que adquirimos mais experiência com nossas implantações automatizadas, podemos automatizar mais de nossas etapas manuais para acelerar o processo. Por exemplo, podemos automatizar mais verificações de qualidade na etapa de teste, para que a Amita não precise aprovar cada compilação.

Tim: Parece ótimo. Vamos seguir com este plano por enquanto e ver como podemos acelerar o sistema mais tarde.

Amita: Falando do nosso plano, podemos resumir nossos próximos passos?

O plano

Vamos rever o plano da equipe Tailspin à medida que avançam para as próximas etapas.

Mara: Aqui está o pipeline de lançamento que queremos construir.

Mara aponta para o quadro branco.

Diagram of the final whiteboard showing the Build, Dev, Test, and Staging stages.

Mara: Para resumir, nossos passos são:

  1. Produza um artefato de construção sempre que enviarmos uma alteração para o GitHub. Esta etapa acontece no estágio Build .
  2. Promova o artefato de construção para o estágio de desenvolvimento . Esta etapa acontece automaticamente quando o estágio de compilação é bem-sucedido e a alteração está na ramificação de versão.
  3. Promova o artefato de construção para o estágio de teste todas as manhãs às 3 da manhã. Usamos um gatilho agendado para promover o artefato de construção automaticamente.
  4. Promova o artefato de construção para preparação após os testes e aprovação da compilação pelo Amita. Usamos uma aprovação de liberação para promover o artefato de construção.

Depois que o gerenciamento aprovar a compilação, podemos implantar o artefato de compilação em um ambiente de produção.

Amita: Isso vai ser difícil de fazer? Parece muito trabalho.

Mara: Não acho muito ruim. Cada etapa é separada de todas as outras. Os palcos são discretos. Cada etapa tem o seu próprio conjunto de tarefas. Por exemplo, o que acontece na etapa de teste permanece na etapa de teste.

Cada estágio de implantação em nosso pipeline também tem seu próprio ambiente. Por exemplo, quando implantamos o aplicativo em Desenvolvimento ou Teste, o ambiente é uma instância do Serviço de Aplicativo.

Finalmente, testamos apenas uma versão de cada vez. Nunca mudamos lançamentos no meio do pipeline. Usamos a mesma versão no estágio de desenvolvimento como no estágio de preparação, e cada versão tem seu próprio número de versão. Se a versão quebrar em um dos estágios, nós o corrigimos e o construímos novamente com um novo número de versão. Essa nova versão, então, passa pelo pipeline desde o início.

Algumas palavras sobre qualidade

Você acabou de ver a equipe projetar um pipeline que leva seu aplicativo desde a compilação até a preparação. O objetivo deste pipeline não é apenas tornar suas vidas mais fáceis. É para garantir a qualidade do software que eles estão entregando aos seus clientes.

Como você mede a qualidade do seu processo de liberação? A qualidade do seu processo de liberação não pode ser medida diretamente. O que você pode medir é o quão bem o seu processo funciona. Se você está constantemente mudando o processo, pode ser um indício de que há algo errado. As versões que falham consistentemente em um ponto específico do pipeline também podem indicar que há um problema com o processo de liberação.

Os lançamentos sempre falham em um determinado dia ou horário? Eles sempre falham depois que você implanta em um ambiente específico? Procure esses e outros padrões para ver se alguns aspetos do processo de liberação são dependentes ou relacionados.

Uma boa maneira de acompanhar a qualidade do seu processo de lançamento é criar visualizações da qualidade dos lançamentos. Por exemplo, adicione um widget de painel que mostre o status de cada versão.

Quando você deseja medir a qualidade de uma liberação em si, você pode 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 durante a execução do pipeline.

Usar um portão de qualidade também é uma ótima maneira de verificar a qualidade do seu lançamento. Existem muitos portões de qualidade diferentes. Por exemplo, portões de item de trabalho podem verificar a qualidade do seu processo de requisitos. Você também pode adicionar mais verificações de segurança e conformidade. Por exemplo, cumpre o princípio dos quatro olhos ou tem a rastreabilidade adequada?

À medida que você progride nesse caminho de aprendizagem, você vê muitas dessas técnicas colocadas em prática.

Por fim, ao projetar um processo de liberaçã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 você queira considerar o uso de uma ferramenta, como o Gerador de Notas de Versão do Azure DevOps. O gerador é um aplicativo de função que contém uma função acionada por HTTP. Usando o Armazenamento de Blobs do Azure, ele cria um arquivo Markdown sempre que uma nova versão é criada no Azure DevOps.

Verifique o seu conhecimento

1.

Seu pipeline inclui muitos testes e verificações de qualidade que levam vários minutos para serem concluídos. Que tipo de gatilho é melhor para executar testes apenas em código que foi revisado por pares?

2.

Qual é a melhor maneira de pausar o pipeline até que um aprovador assine uma alteração?

3.

Você deseja implantar seu aplicativo Web no ambiente de teste sempre que uma compilação for concluída. Qual é a maneira mais fácil de configurar o processo?