Azure DevOps - Configurar pipelines de CI / CD para aplicativos Node.js
Tags: azure, node, javascript, devops
Published: 2021-10-30 05:51:06

Use pipelines do Azure DevOps para criar e testar aplicativos Node.js e, em seguida, implantar ou publicar no serviço de aplicativo azure. A seguir estão as etapas a serem realizadas para um fluxo de trabalho de CI / CD completo.

1 - Desenvolva e comprometa seu código no branch de desenvolvimento.

2 - Envie o código do branch de desenvolvimento para → branch de teste → branch master.

3 - Implante seu código em ambientes diferentes; Dev → Teste → Prod usando pipelines CI / CD no Azure DevOps.

![Azure DevOps CI/CD Workflow for NodeJs/Javascript Applications] (https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p56y4pkcncv6cv6669hs.png) 

### Crie um pipeline de build

Acesse dev.azure.com/{organisation-name} → Selecione Projeto → Pipelines

![Vá para projeto → Pipelines](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kk0ezz11p7z7t5u3t3is.png)
 

- Create New Pipeline → Use Azure Git Repos (YAML) para criar um pipeline como código ou **use the classic editor** para criar um pipeline a partir do designer visual. Para este tutorial, usaremos o editor clássico.
- Select a source repo → Select Project Name → Select Repository → Select Branch Name → Click no Continue.
- Selecione o modelo como um Trabalho vazio.

![Crie um novo pipeline usando o editor clássico](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p055olfrhuae21u8yxo6.png)
 

- Altere o nome do pipeline de build de acordo com a convenção de nomenclatura de sua organização → Selecione Pool de agentes de acordo com o requisito {Hosted vs2017-win2016 for Windows Environment & Hosted Ubuntu 18.04 for Linux based environment}.
- Pense nesses agentes como máquinas virtuais com diferentes sabores de sistema operacional.
- Prefira usar Microsoft Hosted Agents em vez de Self Hosted Agents, a menos que você saiba o que está fazendo
- Selecione Fontes de tag → em caso de sucesso para criar tags git sempre que sua construção for bem-sucedida. Você pode manter o formato da tag como **$ (build.buildNumber) ou v $ (build.buildNumber).**

![Selecione o pool de agentes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r3rsrmhoey9mbe0mlosd.png) 

- Clique em Add Tasks(+) → procurar por tarefa → Add Task
- Você pode adicionar várias tarefas.
- Se uma tarefa não estiver disponível em sua organização, você pode instalá-la a partir do Marketplace.

### Detalhes da Tarefa

- **Instalador da ferramenta Node.js** - localiza ou baixa e armazena em cache a especificação da versão especificada do Node.js e a adiciona ao PATH
- A versão mais recente do Node.js LTS já está instalada no agente e é gerenciada pela Microsoft. Se você estiver usando uma versão específica do Node em seu projeto, use esta tarefa para especificar a versão exata que deseja usar.

![Tarefa do instalador da ferramenta Node.Js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sra9ehhrvmu0ltftmd2y.png)
 
- NPM Task - instale e publique pacotes npm ou execute um comando npm. Suporta [npmjs.com](http://npmjs.com/) e registros autenticados como artefatos do Azure.
- Comandos disponíveis: CI, Instalar, Publicar, Personalizar.
- Para comandos personalizados, não há necessidade de prefixar npm.
- Diretório raiz que contém a pasta do pacote: **$ {Build.SourcesDirectory}** - É uma variável predefinida. O caminho local no agente onde seus arquivos de código-fonte são baixados. Por exemplo: c: \ agent \ _work \ 1 \ s. Essas variáveis são definidas automaticamente pelo sistema e somente leitura.
- Mais informações sobre variáveis predefinidas: Vá para Variáveis Predefinidas
- Pode haver várias versões de uma tarefa. Certifique-se de usar a versão estável e evite usar versões de visualização.

![nstall gatsby-cli](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ao8ek0rdtg4f05g3k0gk.png)
 

- O comando `npm install` instalará o devDependencies junto com outras dependências ao executar dentro de um diretório de pacote, em um ambiente de desenvolvimento (o padrão).
- Cada vez que uma nova construção é acionada, haverá uma nova instância do Agente que não conterá nenhum cache npm.
- Evite instalar devDependencies em um ambiente de produção. Use o Custom command → **install — only=prod**
- Podemos adicionar tarefas npm para teste de unidade, linting, etc. Se os testes forem bem-sucedidos, o único pipeline será bem-sucedido.

![ Install node modules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9gsrtdvcyz871g76tf0.png)
 

- Use variáveis de ambiente para parametrizar os comandos. Use **run build - $ (nome da variável) →** Vá para a guia **Variáveis → Add Variable → variable-name → value**

![Construa a solução](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7hnptlktnumnlz974bpd.png)
 
![Adicionar variáveis de ambiente](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfhjj8m7mxe9d2pqpwgv.png)
 

- Arquivar arquivos: compactar arquivos em .7z, .tar.gz ou .zip.
- Faremos a implantação do zip para reduzir o tempo de implantação. Também podemos usar a tarefa de cópia para criar artefato, mas como haverá um grande número de arquivos, será mais lento em comparação com uma implantação zip. Encontre mais sobre a implantação do zip aqui.
- Especifique a pasta / diretório que deseja archive. eg. public/out.
- Especifique o nome do arquivo a ser criado.
- Anexe o nome da pasta raiz → esta caixa de seleção criará uma pasta com um nome de arquivo e colocará todos os arquivos dentro dessa pasta antes de arquivar.
- Substituir o arquivo existente - esta caixa de seleção excluirá o arquivo anterior antes de criar um novo arquivo em cada nova construção.

![Archive the Deployable components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ey2t21s89k7tqvnzo3h7.png) 

- Publique artefatos de compilação: publique artefatos de compilação no Azure Pipelines ou em um compartilhamento de arquivo do Windows.
- Manter as configurações padrão.
- Você pode fornecer um nome de artefato customizado.

![Publicar artefato de construção](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qanld26em5nvbyjmszu.png)
 

- Habilite a integração contínua para acionar o pipeline de construção sempre que qualquer alteração for feita na filter-branch.

![Habilitar integração contínua](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ticex3t5askg24jt7roj.png)

- O formato do número da compilação criará o número da compilação como Major.Minor.Patch.UniqueID → 1.0.0.1 (Versão semântica)
- O controle de versão semântico de buildId fará mais sentido do que apenas ter um número exclusivo como buildId.
- Build.BuildId é uma variável predefinida que é incrementada sempre que uma nova construção é atribuída ao nível da organização (1,2,3… .n).

![Personalize o formato do número da compilação para usar o Controle de Versão Semântico](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/im3wgl2x1ontl9kp551s.png)
 

- Adicione as variáveis Major, Minor e Patch na guia de variáveis.
- Major- 1, Minor- 0, Patch- **$[counter(format(‘{0}.{1}’, variables[‘Major’], variables[‘Minor’]), 0)]**
- A variável Patch começará a partir de 0 e incrementará toda vez que uma nova compilação for acionada. Ele será redefinido para 0 quando o valor Principal ou Secundário for alterado / incrementado.
- Mantenha essas duas variáveis configuráveis no tempo de execução para que a equipe do aplicativo possa alterar as versões principais / secundárias durante o tempo de execução.

![Adicionar contador para variáveis principais, secundárias e de patch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cew31uyv6shp75ljkk7q.png)
 
![BuildId personalizado - Controle de versão semântico](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b16b2v0oa41ihq1j2x5t.png)

- Também podemos agendar o tempo de construção

![Build Scheduler](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akhqrstu3bcq6fjtcjb0.png)
 

- Guia Histórico: para visualizar o histórico das alterações feitas no pipeline de construção e comparar as diferenças.
- Pipelines também podem ser revertidos para seu estado anterior usando a opção Reverter Pipeline.

![Guia Histórico para comparar e reverter as alterações](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0qmdgdk1fsrcivztiih.png)
 

### E se você tiver que criar muitos pipelines em seu projeto que usarão o mesmo conjunto de tarefas?

Grupos de tarefas: Se houver tarefas semelhantes em pipelines diferentes, no mesmo projeto ou em projetos diferentes, você pode criar grupos de tarefas a partir das tarefas de pipeline existentes, conforme mostrado na figura. Selecione todas as tarefas e clique com o botão direito → selecione Criar grupo de tarefas.

![Task Groups](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/topz83f9gpnm3pazpyci.png)
 

- Se os argumentos forem diferentes nas tarefas, então você pode escrevê-lo como variável $ (nome-da-variável) e ele pedirá o valor ao adicioná-lo como um grupo de tarefa, conforme mostrado na imagem abaixo.

![Parâmetros em grupos de tarefas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9rotqdmyxppa0oise6m.png)
 

Podemos exportar e importar os grupos de tarefas para usá-los em vários projetos do Azure DevOps.

![Exportar Grupo de Tarefas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ep2ff7yhximu4m77hre.png)
 

![Importar Grupo de Tarefas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/er29cw8affbboowqwdig.png)
 

### Criar um **Release Pipeline**

Vá para [dev.azure.com/{organisation-name}](http://dev.azure.com/%7Borganisation-name%7D) → Selecione Projeto → Pipelines → Releases.

![Criar pipeline de lançamento](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9i9mcp5ffthaflbpvai.png)
 

- Novo pipeline → Selecionar trabalho vazio
- Renomear estágio
- Clique em Adicionar um artefato → selecione o pipeline de compilação de origem → Versão padrão: Mais recente → Alias do artefato: Padrão → Adicionar
- Alias de origem: criará uma pasta no Agente com o mesmo nome de alias de origem (_Medium-Blogs-CI-Prod no nosso caso). Os artefatos serão armazenados nesta pasta no agente.

![Estágio no pipeline de liberação](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjyof571e3qv0skr6vzd.png)
 

- Habilite a implantação contínua. Sempre que um novo build associado a este pipeline estiver disponível, uma nova versão será acionada.
- Habilite Branch Filter para acionar a liberação apenas de filiais selecionadas.

![Disparador de implantação contínua](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j2b9byd2trjp5d557s4j.png)
 

- Editar Nome do pipeline → Adicionar tarefa: Implantar Serviço de Aplicativo do Azure

![Adicionar tarefas no trabalho do agente](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lrlz2x8msw2wjry2xxji.png)
 

- Vá para o trabalho do agente → Selecione o pool do agente de acordo com o requisito {Hosted vs2017-win2016 para ambiente Windows e Ubuntu 18.04 hospedado para ambiente baseado em Linux}.
- Prefira usar Microsoft Hosted Agents em vez de Self Hosted Agents, a menos que você saiba o que está fazendo

![Especificação do Agente](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tly44v8jx75n8fyy1vdd.png)
 

- Selecione o tipo de serviço de aplicativo como Web App no Windows (tarefa versão 4) / Web App (tarefa versão 3) para a máquina baseada em Windows.
- Implementar no Slot será verificado apenas para pipelines de produção
- Pacote ou pasta: **$ (System.DefaultWorkingDirectory) / ** / *. Zip** → Esta opção encontrará qualquer arquivo zip no diretório de trabalho padrão. Exemplo de localização: - Artefatos vinculados → Alias do artefato → Nome do artefato → $ {BuildId} .zip]

![Tarefa de implantação do Serviço de Aplicativo do Azure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aqqmbcb01d2g9d5cp2ri.png)
 

- Opções adicionais de implantação: se desmarcado, ele detectará automaticamente o melhor método de implantação com base no tipo de aplicativo, formato do pacote e outros parâmetros. Selecione a opção de visualizar os métodos de implantação com suporte e escolha um para implantar seu aplicativo.
- Colocar o Aplicativo Offline: selecione a opção para colocar o Serviço de Aplicativo do Azure offline, colocando um arquivo app_offline.htm no diretório raiz do Serviço de Aplicativo antes do início da operação de sincronização. O arquivo será removido depois que a operação de sincronização for concluída com sucesso.
- Remover arquivos adicionais no destino: selecione a opção de excluir arquivos no Serviço de Aplicativo do Azure que não possuem arquivos correspondentes no pacote ou pasta do Serviço de Aplicativo. Observação: isso também removerá todos os arquivos relacionados a qualquer extensão instalada neste Serviço de Aplicativo do Azure. Para evitar isso, selecione a caixa de seleção ‘Excluir arquivos da pasta App_Data’.
- Exclui arquivos da pasta App_Data: selecione a opção para impedir que arquivos na pasta App_Data sejam implantados / excluídos do Serviço de Aplicativo do Azure.

![Opções adicionais de implantação](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8hrk0d53edymap9o50gu.png)
 

### E se o aplicativo da web não for estático

Teremos que iniciar um servidor de nó no Serviço de Aplicativo do Azure que pode atender às solicitações.

- Para iniciar um servidor de nó no serviço de aplicativo do Windows, teremos que incluir um arquivo `web.config` na raiz do diretório.
- Para criar o arquivo `web.config` durante o lançamento, vá para Transformações de arquivo e opções de substituição de variável → Marque a caixa de seleção Gerar Web.Config e forneça os parâmetros do arquivo `web.config` como nome do arquivo do servidor, tipo de aplicativo, etc. Ele irá gerar um `web.config` arquivo que iniciará o servidor node.exe no aplicativo da web
- O arquivo `web.config` pode variar dependendo do aplicativo. Portanto, use um arquivo `web.config` personalizado e mantenha-o no código-fonte em vez de gerá-lo no tempo de execução. Ao gerar o arquivo `web.config`, ele tenta primeiro descompactar o arquivo zip do artefato em um local temporário (memória limitada) e, em seguida, coloca o arquivo de configuração dentro dele e, em seguida, compactá-lo novamente. Isso leva muito tempo e se o arquivo zip contiver muitos arquivos, ele pode falhar devido à limitação de memória. Ele usa um pacote de nó para compactar e descompactar o arquivo. Eu enfrentei esse problema com vários aplicativos que tinham um grande número de arquivos. Uma solução alternativa será usar a tarefa de cópia no pipeline de construção em vez da tarefa de arquivamento, mas isso tornará o pipeline lento.
- Opções de pós-implantação: Esses scripts serão executados após a implantação bem-sucedida do pacote. Você pode fornecer um script embutido no próprio designer ou pode usar um arquivo de script do diretório de artefatos.

![Gerar arquivo web.config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f06ip74mbi29dkv84otj.png)
 

### Para o Pipeline de Produção, teremos que adicionar mais um estágio para troca de slots.

- Adicione um novo estágio no pipeline de produção para troca de slot.
- Um novo slot denominado Inativo / canário (dependendo do tipo de implantação) precisa ser criado primeiro no serviço de aplicativo.
- No primeiro slot (slot inativo), marque a caixa de seleção - Implementar no slot ou ambiente de serviço de aplicativo → Fornecer o nome do slot (inativo / canário).
- Ele implantará o pacote no slot inativo / canário antes de trocá-lo por um slot Ativo. Isso garantirá tempo de inatividade ~ zero na implantação de produção.

![Marque → Implementar no Slot ou Ambiente de Serviço de Aplicativo → Slot inativo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3aa1dopsycd56bywj8du.png)
 

- Como um slot também hospeda um aplicativo, ele também consumirá memória do ASP, o que pode reduzir o desempenho do aplicativo de produção.
- Portanto, pararemos o slot canário / inativo quando não estiver em uso, ou seja, após a troca de slot e iniciaremos o slot antes da implantação no slot canário / inativo.
- Adicione a tarefa de gerenciamento do serviço de aplicativo do Azure antes da tarefa de implantação do serviço de aplicativo do Azure e defina a ação para iniciar o serviço de aplicativo.

![Esta tarefa iniciará o slot inativo antes da implantação](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2zuqgm9ixgeyaszbbrm.png)
 

![Adicionar estágio de troca de slot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1qblts1e0giggbduo5m.png)
 
- Condições de pré-implantação: Selecione esta opção para adicionar aprovadores para o estágio de troca de slot. Você pode adicionar vários aprovadores ou um grupo de aprovadores.

![Aprovações pré-implantação](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qv4jokwfus083f0mxljr.png)

- Adicionar tarefa - o serviço de Aplicativo do Azure gerencia que pode iniciar, parar, reiniciar, troca de slot, instalar extensões de site ou habilitar o monitoramento contínuo para um Serviço de Aplicativo do Azure

![Troca de slot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n64xwsk3rcssxg9yd5d3.png)
 

- Depois que a troca de slot for concluída, pararemos o slot inativo / canário para reduzir o consumo desnecessário de recursos.

![Slot inicial antes da implantação](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imz2itd7z63yq9lfzi35.png) 

### Escopo para melhorias

- IaC (Infraestrutura como Código) - Este artigo é para iniciantes. Se você já está familiarizado com os pipelines de CI / CD, o pipeline YAML de vários estágios é o caminho a percorrer.
- Aumentando o desempenho do pipeline de construção usando npm-cache
- Uso de ferramentas de análise de código estático como SonarQube no pipeline de construção.
- Validação de build de solicitações pull.

Fontes onde pesquisei esse conteúdo: 
- https://azure.microsoft.com/pt-br/services/devops/
- https://azure.microsoft.com/pt-br/solutions/devops/
- https://azure.microsoft.com/pt-br/features/devops-projects/
- https://levelup.gitconnected.com/configure-ci-cd-pipelines-for-nodejs-applications-with-azure-devops-44e7425f5a99