Guia de CI/CD no GitLab para (quase) iniciantes absolutos

Ou como obter belos crachás para seu projeto em uma única noite de codificação descontraída

Provavelmente, todo desenvolvedor que tem pelo menos um projeto pessoal, em algum momento, sente a necessidade de criar belos crachás com status, cobertura de código, versões de pacotes no nuget... E essa necessidade me levou a escrever este artigo. Durante o processo de preparação, eu obtive essa beleza em um dos meus projetos:

Guia de CI/CD no GitLab para (quase) iniciantes absolutos

Neste artigo, será abordada a configuração básica de integração contínua e entrega contínua para um projeto de biblioteca de classes em .Net Core no GitLab, com a publicação de documentação no GitLab Pages e o envio de pacotes construídos para um feed privado no Azure DevOps.

Como ambiente de desenvolvimento, foi utilizado o VS Code com a extensão GitLab Workflow para validação do arquivo de configuração diretamente do ambiente de desenvolvimento.

Introdução breve

CD - é quando você apenas fez o push, e o cliente já está tudo fora do ar?

O que é CI/CD e para que serve - pode ser facilmente encontrado no Google. A documentação completa sobre a configuração de pipelines no GitLab também não é difícil de encontrar. Aqui eu descreverei brevemente e, na medida do possível, sem erros, o processo de funcionamento do sistema de uma visão panorâmica:O desenvolvedor envia um commit para o repositório, cria um merge request pelo site,

  • ou de alguma outra forma explicitamente ou implicitamente inicia o pipeline da configuração são selecionadas todas as tarefas cujas condições permitem que sejam iniciadas nesse contexto,,
  • as tarefas são organizadas de acordo com suas etapas,
  • as etapas são executadas sequencialmente - ou seja,
  • paralelamente todas as tarefas dessa etapa são executadas, se a etapa falhar (ou seja, se pelo menos uma das tarefas da etapa falhar) - o pipeline é interrompido (
  • quase semprese todas as etapas forem concluídas com sucesso, o pipeline é considerado bem-sucedido.),
  • Assim, temos:

um pipeline - um conjunto de tarefas organizadas em etapas, onde é possível compilar, testar, empacotar código, implantar a construção pronta em um serviço em nuvem, etc.,

  • uma etapa (
  • ) - a unidade de organização do pipeline, contém 1+ tarefa,stagetarefa (
  • job) - a unidade de trabalho no pipeline. Consiste em um script (obrigatório), condições de execução, configurações de publicação/cache de artefatos e muito mais.) — unidade de trabalho no pipeline. Consiste em um script (obrigatório), condições de execução, configurações de publicação/cache de artefatos e muito mais.

Assim, a tarefa ao configurar CI/CD é criar um conjunto de tarefas que realizem todas as ações necessárias para compilar, testar e publicar o código e os artefatos.

Antes de começar: por quê?

  • Por que GitLab?

Porque quando surgiu a necessidade de criar repositórios privados para projetos pessoais, eles eram pagos no GitHub, e eu sou econômico. Os repositórios se tornaram gratuitos, mas isso ainda não é motivo suficiente para eu migrar para o GitHub.

  • Por que não Azure DevOps Pipelines?

Porque lá a configuração é simples — nem é necessário saber usar a linha de comando. A integração com provedores git externos é feita em poucos cliques, a importação de chaves SSH para enviar commits para o repositório também é fácil, e o pipeline é facilmente configurável mesmo sem um template.

Ponto de partida: o que temos e o que queremos

Temos:

  • um repositório no GitLab.

Queremos:

  • compilação e teste automático para cada merge request,
  • compilação de pacotes para cada merge request e push no master, desde que haja uma certa linha na mensagem do commit,
  • envio dos pacotes compilados para um feed privado no Azure DevOps,
  • compilação da documentação e publicação no GitLab Pages,
  • badges!11

Os requisitos descritos se encaixam perfeitamente no seguinte modelo de pipeline:

  • Etapa 1 — compilação
    • Compilamos o código, publicamos os arquivos de saída como artefatos
  • Etapa 2 — teste
    • Obtemos os artefatos da etapa de compilação, executamos os testes e coletamos os dados de cobertura de código
  • Etapa 3 — envio
    • Tarefa 1 — compilamos o pacote NuGet e enviamos para o Azure DevOps
    • Tarefa 2 — compilamos o site a partir do xmldoc no código-fonte e publicamos no GitLab Pages

Vamos lá!

Compilamos a configuração

Preparamos as contas

  1. Criamos uma conta no Microsoft Azure

  2. Vamos para Azure DevOps

  3. Criamos um novo projeto

    1. Nome — qualquer um
    2. Visibilidade — qualquer uma
      Guia de CI/CD no GitLab para (quase) iniciantes absolutos

  4. Ao clicar no botão Criar, o projeto será criado e iremos para sua página. Nessa página, é possível desativar funcionalidades desnecessárias, acessando as configurações do projeto (link inferior na lista à esquerda -> Visão Geral -> bloco de Serviços do Azure DevOps)
    Guia de CI/CD no GitLab para (quase) iniciantes absolutos

  5. Vamos para Atrifacts, clicamos em Criar feed

    1. Inserimos o nome da fonte
    2. Escolhemos a visibilidade
    3. Desmarcamos a opção Incluir pacotes de fontes públicas comuns, para que a fonte não se transforme em um depósito de clones do NuGet
      Guia de CI/CD no GitLab para (quase) iniciantes absolutos

  6. Clicamos em Conectar ao feed, escolhemos Visual Studio, copiamos a Fonte do bloco Configuração da Máquina
    Guia de CI/CD no GitLab para (quase) iniciantes absolutos

  7. Vamos para as configurações da conta, escolhemos Token de Acesso Pessoal
    Guia de CI/CD no GitLab para (quase) iniciantes absolutos

  8. Criamos um novo token de acesso

    1. Nome — qualquer um
    2. Organização — a atual
    3. Prazo de validade — no máximo 1 ano
    4. Escopo — Packaging/Read & Write
      Guia de CI/CD no GitLab para (quase) iniciantes absolutos

  9. Copiamos o token criado — após fechar a janela modal, o valor não estará mais disponível

  10. Acesse as configurações do repositório no GitLab, escolha as configurações de CI/CD
    Guia de CI/CD no GitLab para (quase) iniciantes absolutos

  11. Expanda o bloco Variables, adicione um novo

    1. Nome — qualquer um sem espaços (estará disponível no shell)
    2. Valor — token de acesso do item 9
    3. Escolha Mask variable
      Guia de CI/CD no GitLab para (quase) iniciantes absolutos

Com isso, a configuração preliminar está concluída.

Preparando a estrutura de configuração

Por padrão, para configurar CI/CD no GitLab, usa-se o arquivo .gitlab-ci.yml na raiz do repositório. É possível configurar um caminho arbitrário para esse arquivo nas configurações do repositório, mas neste caso, isso não é necessário.

Como pode ser visto pela extensão, o arquivo contém a configuração no formato YAML. A documentação descreve em detalhes quais chaves podem ser contidas no nível superior da configuração e em cada um dos níveis aninhados.

Primeiro, adicionaremos ao arquivo de configuração um link para a imagem do Docker, onde as tarefas serão executadas. Para isso, encontramos a página de imagens .Net Core no Docker Hub. No GitHub que fornece um guia detalhado sobre qual imagem escolher para diferentes tarefas. Para compilações, vamos usar a imagem com .Net Core 3.1, então simplesmente adicionamos a primeira linha na configuração

image: mcr.microsoft.com/dotnet/core/sdk:3.1

Agora, ao executar o pipeline, a imagem especificada será baixada do repositório de imagens da Microsoft, onde todas as tarefas da configuração serão executadas.

A próxima etapa é adicionar stageestágios. Por padrão, o GitLab define 5 estágios:

  • .pre — é executado antes de todos os estágios,
  • .post — é executado após todos os estágios,
  • build — primeiro após .pre estágio,
  • test — segundo estágio,
  • deploy — terceiro estágio.

Nada impede que os declaramos explicitamente. A ordem em que os estágios são especificados afeta a ordem em que são executados. Para completar, adicionamos à configuração:

stages:
  - build
  - test
  - deploy

Para depuração, faz sentido obter informações sobre o ambiente em que as tarefas são executadas. Adicionaremos um conjunto global de comandos que será executado antes de cada tarefa, usando before_script:

before_script:
  - $PSVersionTable.PSVersion
  - dotnet --version
  - nuget help | select-string Version

Resta adicionar pelo menos uma tarefa, para que ao enviar commits o pipeline seja executado. Por ora, vamos adicionar uma tarefa vazia para demonstração:

dummy job:
  script:
    - echo ok

Iniciamos a validação, recebemos a mensagem de que está tudo bem, fazemos o commit, fazemos o push, verificamos os resultados no site… E obtemos um erro de script — bash: .PSVersion: comando não encontrado. O que?!

Tudo faz sentido — por padrão, os runners (responsáveis pela execução dos scripts de tarefas e fornecidos pelo GitLab) usam bash para executar comandos. Podemos corrigir isso, especificando explicitamente na descrição da tarefa quais tags devem estar no runner do pipeline que executa:

tarefa dummy em windows:
  script:
    - echo ok
  tags:
    - windows

Ótimo! Agora o pipeline está sendo executado.

Um leitor atento, ao repetir os passos indicados, notará que a tarefa foi executada na etapa test, embora não tenhamos especificado a etapa. Como pode ser deduzido, test é a etapa padrão.

Vamos continuar a criação da estrutura de configuração, adicionando todas as tarefas descritas acima:

tarefa de build:
  script:
    - echo "building..."
  tags:
    - windows
  stage: build

tarefa de teste e cobertura:
  script:
    - echo "executando testes e análise de cobertura..."
  tags:
    - windows
  stage: test

tarefa de empacotamento e implantação:
  script:
    - echo "empacotando e enviando para nuget..."
  tags:
    - windows
  stage: deploy

páginas:
  script:
    - echo "criando docs..."
  tags:
    - windows
  stage: deploy

Obtivemos um pipeline não muito funcional, mas ainda assim correto.

Configuração de gatilhos

Como não foram especificados filtros de acionamento para nenhuma das tarefas, o pipeline será totalmente executado a cada envio de commits para o repositório. Como esse não é o comportamento desejado na maioria das vezes, iremos configurar filtros de acionamento para as tarefas.

Os filtros podem ser configurados em dois formatos: only/except e rules. Em resumo, only/except permite configurar filtros por gatilhos (merge_request, por exemplo — configura a tarefa para ser executada a cada criação de um pedido de mesclagem e a cada envio de commits para a branch que é a origem do pedido de mesclagem) e nomes de branches (incluindo o uso de expressões regulares); rules permetem configurar um conjunto de condições e, opcionalmente, alterar as condições de execução da tarefa dependendo do sucesso das tarefas anteriores (when no GitLab CI/CD).

Vamos lembrar o conjunto de requisitos — build e teste apenas para merge requests, empacotamento e envio para Azure DevOps — para merge requests e pushes no master, geração de documentação — para pushes no master.

Para começar, vamos configurar a tarefa de build de código, adicionando uma regra de acionamento apenas para merge requests:

tarefa de build:
  # snip
  only:
    - merge_request

Agora vamos configurar a tarefa de empacotamento para ser acionada por merge requests e adições de commits no master:

tarefa de empacotamento e implantação:
  # snip
  only:
    - merge_request
    - master

Como pode ser visto, é tudo simples e direto.

Também é possível configurar a tarefa para ser acionada apenas se um merge request for criado com um branch de destino ou origem específico:

  regras:
    - se: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"

Nas condições, podem ser usadas as variáveis listadas aqui; regras rules não são compatíveis com as regras only/except.

Configuração de salvamento de artefatos

Durante a execução da tarefa tarefa de build teremos artefatos de build criados, que podem ser reutilizados em tarefas subsequentes. Para isso, é necessário adicionar os caminhos na configuração da tarefa onde os arquivos devem ser salvos e reutilizados nas próximas tarefas, na chave artefatos:

tarefa de build:
  # snip
  artefatos:
    caminhos:
      - path/to/build/artifacts
      - another/path
      - MyCoolLib.*/bin/Release/*

Os caminhos suportam wildcards, o que definitivamente facilita a sua definição.

Se a tarefa cria artefatos, então cada tarefa subsequente poderá acessá-los — eles estarão localizados nos mesmos caminhos em relação à raiz do repositório, pelos quais foram coletados da tarefa original. Além disso, os artefatos estão disponíveis para download no site.

Agora que temos a estrutura da configuração pronta (e testada), podemos passar para a escrita dos scripts para as tarefas.

Escrevendo scripts

Talvez, há muito tempo, em uma galáxia muito, muito distante, compilar projetos (incluindo em .net) a partir da linha de comando fosse um desafio. Agora, compilar, testar e publicar um projeto pode ser feito em 3 comandos:

dotnet build
dotnet test
dotnet pack

Naturalmente, existem algumas nuances que farão com que complicamos um pouco os comandos.

  1. Queremos uma compilação de release, e não de debug, então adicionamos -c Release
  2. Ao testar, queremos coletar dados de cobertura de código, portanto precisaremos incluir o analisador de cobertura nas bibliotecas de teste:
    1. Em todas as bibliotecas de teste, deve-se adicionar o pacote coverlet.msbuild: dotnet add package coverlet.msbuild da pasta do projeto
    2. No comando de execução dos testes, adicionaremos /p:CollectCoverage=true
    3. Na configuração da tarefa de teste, adicionaremos uma chave para obter os resultados de cobertura (veja abaixo)
  3. Ao empacotar o código em pacotes nuget, definiremos o diretório de saída para os pacotes: -o .

Coletando dados de cobertura de código

Coverlet, após a execução dos testes, exibe no console as estatísticas sobre a execução:

Calculando o resultado da cobertura...
 Gerando relatório 'C:Usersxxxsourcereposmy-projectmyProject.testscoverage.json'

+-------------+--------+--------+--------+
| Módulo      | Linha  | Ramificação | Método |
+-------------+--------+--------+--------+
| projeto 1   | 83,24% | 66,66% | 92,1%  |
+-------------+--------+--------+--------+
| projeto 2   | 87,5%  | 50%    | 100%   |
+-------------+--------+--------+--------+
| projeto 3   | 100%   | 83,33% | 100%   |
+-------------+--------+--------+--------+

+---------+--------+--------+--------+
|         | Linha  | Ramificação | Método |
+---------+--------+--------+--------+
| Total   | 84,27% | 65,76% | 92,94% |
+---------+--------+--------+--------+
| Média   | 90,24% | 66,66% | 97,36% |
+---------+--------+--------+--------+

O GitLab permite especificar uma expressão regular para obter estatísticas, que depois podem ser apresentadas como um badge. A expressão regular é especificada nas configurações da tarefa com a chave coverage; a expressão deve conter um grupo de captura, cujo valor será passado para o badge:

trabalho de teste e cobertura:
  # snip
  cobertura: \/|s*Totals*|s*(d+[,.]d+%)\/

Aqui obtemos estatísticas da linha com a cobertura total.

Publicar pacotes e documentação

Ambas as ações estão agendadas para a última etapa do pipeline — com a construção e os testes concluídos, podemos compartilhar nossos resultados com o mundo.

Para começar, vamos considerar a publicação na origem dos pacotes:

  1. Se o projeto não contém um arquivo de configuração nuget (nuget.config), vamos criar um novo: dotnet new nugetconfig

    Por quê: na imagem pode ser proibido o acesso de gravação nas configurações globais (do usuário e do sistema). Para evitar erros, basta criar uma nova configuração local e trabalhar com ela.

  2. Vamos adicionar uma nova origem de pacotes à configuração local: nuget sources add -name <nome> -source <url> -username <organização> -password <variável do gitlab> -configfile nuget.config -StorePasswordInClearText
    1. nome — nome local da origem, não é crucial
    2. url — URL da origem da etapa 'Preparando contas', item 6
    3. organização — nome da organização no Azure DevOps
    4. variável do gitlab — nome da variável com o token de acesso, adicionada no GitLab ('Preparando contas', item 11). Naturalmente, no formato $variávelNome
    5. -StorePasswordInClearText — hack para contornar o erro de acesso negado (não fui o primeiro a pisar nesse truque)
    6. Em caso de erros, pode ser útil adicionar -verbosity detailed
  3. Enviando pacote para a origem: nuget push -source <nome> -skipduplicate -apikey <chave> *.nupkg
    1. Enviando todos os pacotes do diretório atual, portanto *.nupkg.
    2. nome — do passo anterior.
    3. key — qualquer string. No Azure DevOps, na janela Conectar ao feed, sempre é apresentada uma string de exemplo az.
    4. -skipduplicate — ao tentar enviar um pacote já existente sem essa chave, a origem retornará um erro 409 Conflito; com a chave, o envio será ignorado.

Agora vamos configurar a criação da documentação:

  1. Primeiro, no repositório, na branch master, inicializamos o projeto docfx. Para isso, a partir da raiz, precisamos executar o comando docfx init e em modo interativo definiremos os parâmetros chave para a construção da documentação. A descrição detalhada da configuração mínima do projeto aqui.
    1. Ao configurar, é importante indicar o diretório de saída ..public — O GitLab, por padrão, usa o conteúdo da pasta public na raiz do repositório como fonte para Pages. Como o projeto estará localizado em uma pasta aninhada ao repositório, adicionamos ao caminho de saída um nível para cima.
  2. Vamos enviar as alterações para o GitLab.
  3. Na configuração do pipeline, adicionaremos a tarefa pages (palavra reservada para tarefas de publicação de sites no GitLab Pages):
    1. Script:
      1. nuget install docfx.console -version 2.51.0 — instalará o docfx; a versão está especificada para garantir a correção dos caminhos de instalação do pacote.
      2. .docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json — estamos construindo a documentação
    2. Nó de artifacts:

pages:
  # snip
  artifacts:
    paths:
      - public

Um desvio lírico sobre o docfx

Anteriormente, ao configurar o projeto, eu indicava a fonte de código para a documentação como um arquivo de solução. A principal desvantagem é que a documentação é criada também para projetos de teste. Caso isso não seja necessário, podemos atribuir esse valor ao nó metadata.src:

{
  "metadata": [
    {
      "src": [
        {
          "src": "..\/",
          "files": [
            "**\/*.csproj"
          ],
          "exclude":[
            "*.tests*\/**"
          ]
        }
      ],
      \/\/ --- snip ---
    },
    \/\/ --- snip ---
  ],
  \/\/ --- snip ---
}

  1. metadata.src.src: "..\/" — saímos um nível acima em relação à localização docfx.json, pois a busca em padrões não funciona para cima na árvore de diretórios.
  2. metadata.src.files: ["**\/*.csproj"] — padrão global, coletamos todos os projetos C# de todos os diretórios.
  3. metadata.src.exclude: ["*.tests*\/**"] — padrão global, excluímos tudo das pastas com .tests no nome

Resumo Intermediário

Esta configuração simples pode ser feita em literalmente meia hora e algumas xícaras de café, permitindo que a cada merge request e envio para master, verifiquemos se o código compila e os testes passam, coletar um novo pacote, atualizar a documentação e alegrar os olhos com belos badges no README do projeto.

O resultado final .gitlab-ci.yml

imagem: mcr.microsoft.com/dotnet/core/sdk:3.1

antes_do_script:
  - $PSVersionTable.PSVersion
  - dotnet --version
  - nuget help | select-string Version

etapas:
  - build
  - test
  - deploy

trabalho de construção:
  etapa: build
  script:
    - dotnet build -c Release
  tags:
    - windows
  somente:
    - merge_requests
    - master
  artefatos:
    caminhos:
      - seu/caminho/para/binaries

trabalho de teste e cobertura:
  etapa: test
  tags:
    - windows
  script:
    - dotnet test -c Release /p:CollectCoverage=true
  cobertura: /|s*Totals*|s*(d+[,.]d+%)|
  somente:
    - merge_requests
    - master

trabalho de empacotamento e implantação:
  etapa: deploy
  tags:
    - windows
  script:
    - dotnet pack -c Release -o .
    - dotnet new nugetconfig
    - nuget sources add -name feedName -source https://pkgs.dev.azure.com/seu-organizacao/_packaging/seu-feed/nuget/v3/index.json -username seu-organizacao -password $nugetFeedToken -configfile nuget.config -StorePasswordInClearText
    - nuget push -source feedName -skipduplicate -apikey az *.nupkg
  somente:
    - master

páginas:
  tags:
    - windows
  etapa: deploy
  script:
    - nuget install docfx.console -version 2.51.0
    - $env:path = "$env:path;$($(get-location).Path)"
    - .docfx.console.2.51.0toolsdocfx.exe .docfxdocfx.json
  artefatos:
    caminhos:
      - public
  somente:
    - master

A propósito dos badges

Por causa deles, tudo foi planejado!

Os badges com os status do pipeline e cobertura de código estão disponíveis no GitLab nas configurações de CI/CD na seção de pipelines Centrais:

Guia de CI/CD no GitLab para (quase) iniciantes absolutos

O badge com link para a documentação eu criei na plataforma Shields.io — lá tudo é bastante direto, você pode criar seu próprio badge e obtê-lo por meio de uma solicitação.

![Exemplo com Shields.io](https://img.shields.io/badge/custom-badge-blue)

Guia de CI/CD no GitLab para (quase) iniciantes absolutos

O Azure DevOps Artifacts também permite criar badges para pacotes com a versão atual. Para isso, na fonte no site do Azure DevOps, você deve clicar em Criar badge no pacote selecionado e copiar a marcação markdown:

Guia de CI/CD no GitLab para (quase) iniciantes absolutos

Guia de CI/CD no GitLab para (quase) iniciantes absolutos

Adicionando beleza

Destacando fragmentos comuns da configuração

Durante a escrita da configuração e pesquisas na documentação, encontrei uma possibilidade interessante do YAML — reutilização de fragmentos.

Como pode ser visto nas configurações das tarefas, todas elas exigem a presença de uma tag windows no runner e são acionadas ao enviar para o master/criar uma solicitação de mesclagem (exceto pela documentação). Vamos adicionar isso ao fragmento que iremos reutilizar:

.common_tags: &common_tags
  tags:
    - windows
.common_only: &common_only
  only:
    - merge_requests
    - master

E agora na descrição da tarefa podemos inserir o fragmento declarado anteriormente:

trabalho de construção:
  <<: *common_tags
  <<: *common_only

Os nomes dos fragmentos devem começar com um ponto, para não serem interpretados como uma tarefa.

Versionamento de pacotes

Ao criar um pacote, o compilador verifica as chaves da linha de comando e, na sua ausência, os arquivos de projeto; ao encontrar o nó Version, ele usa seu valor como a versão do pacote a ser construído. Portanto, para compilar um pacote com uma nova versão, é necessário atualizar a versão no arquivo do projeto ou passá-la como argumento da linha de comando.

Vamos adicionar mais um desejo - que os dois últimos números na versão sejam o ano e a data de construção do pacote, e também adicionar versões pré-lançamento. Adicionar esses dados no arquivo do projeto e verificar antes de cada envio é claro — mas isso pode ser feito também no pipeline, obtendo a versão do pacote a partir do contexto e passando através do argumento da linha de comando.

Concordamos que, se a mensagem do commit contém uma linha do tipo release (v. / ver. / version) (rev. / revisão )?, então vamos pegar a versão do pacote dessa linha, complementá-la com a data atual e passá-la como argumento para o comando dotnet pack. Na ausência da linha - simplesmente não vamos construir o pacote.

A seguinte tarefa é resolvida pelo script:

# регулярное выражение для поиска строки с версией
$rx = "releases+(v.?|ver.?|version)s*(?<maj>d+)(?<min>.d+)?(?<rel>.d+)?s*((rev.?|revision)?s+(?<rev>[a-zA-Z0-9-_]+))?"
# ищем строку в сообщении коммита, передаваемом в одной из предопределяемых GitLab'ом переменных
$found = $env:CI_COMMIT_MESSAGE -match $rx
# совпадений нет - выходим
if (!$found) { Write-Output "no release info found, aborting"; exit }
# извлекаем мажорную и минорную версии
$maj = $matches['maj']
$min = $matches['min']
# если строка содержит номер релиза - используем его, иначе - текущий год
if ($matches.ContainsKey('rel')) { $rel = $matches['rel'] } else { $rel = ".$(get-date -format "yyyy")" }
# в качестве номера сборки - текущие месяц и день
$bld = $(get-date -format "MMdd")
# если есть данные по пререлизной версии - включаем их в версию
if ($matches.ContainsKey('rev')) { $rev = "-$($matches['rev'])" } else { $rev = '' }
# собираем единую строку версии
$version = "$maj$min$rel.$bld$rev"
# собираем пакеты
dotnet pack -c Release -o . /p:Version=$version

Adicionamos o script à tarefa pack and deploy job e observamos a construção dos pacotes rigidamente na presença da linha especificada na mensagem do commit.

Total

Depois de gastar cerca de meia hora a uma hora escrevendo a configuração, depurando no PowerShell local e, possivelmente, algumas execuções malsucedidas, obtivemos uma configuração simples para automatizar tarefas rotineiras.

Claro, o GitLab CI/CD é muito mais abrangente e multifacetado do que pode parecer após a leitura deste guia - não é nada disso. Há até mesmo Auto DevOps disponível, que permite

detecta automaticamente, constrói, testa, implementa e monitora suas aplicações

Agora, nos planos - configurar um pipeline para o deployment de aplicações no Azure, utilizando Pulumi e a detecção automática do ambiente de destino, o que será abordado no próximo artigo.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster