Una guía de CI/CD en GitLab para el (casi) principiante absoluto

O cómo obtener hermosas insignias para su proyecto en una noche de codificación fácil

Probablemente, todos los desarrolladores que tienen al menos un proyecto favorito en algún momento sienten curiosidad por las hermosas insignias con estados, cobertura de código, versiones de paquetes en nuget... Y esta necesidad me llevó a escribir este artículo. En preparación para escribirlo, obtuve esta belleza en uno de mis proyectos:

Una guía de CI/CD en GitLab para el (casi) principiante absoluto

Este artículo lo guiará a través de la configuración básica de integración y entrega continuas para un proyecto de biblioteca de clases de .Net Core en GitLab, la publicación de documentación en GitLab Pages y el envío de paquetes creados a una fuente privada en Azure DevOps.

VS Code se utilizó como entorno de desarrollo con la extensión Flujo de trabajo de GitLab (para validar el archivo de configuración directamente desde el entorno de desarrollo).

Breve introducción

CD: ¿es cuando acaba de presionar y todo ya ha caído sobre el cliente?

¿Qué es CI / CD y por qué lo necesita? Puede buscarlo fácilmente en Google. Encuentre documentación completa sobre la configuración de canalizaciones en GitLab también fácil. Aquí describiré brevemente y, si es posible, sin fallas, el proceso del sistema a vista de pájaro:

  • el desarrollador envía una confirmación al repositorio, crea una solicitud de fusión a través del sitio, o de alguna otra manera, explícita o implícitamente inicia la canalización,
  • todas las tareas se seleccionan de la configuración, cuyas condiciones permiten que se inicien en el contexto dado,
  • Las tareas se organizan según sus etapas,
  • las etapas se ejecutan a su vez, es decir, paralelo a todas las tareas de esta etapa se completan,
  • si la etapa falla (es decir, al menos una de las tareas de la etapa falla), la canalización se detiene (casi siempre),
  • si todas las etapas se completan con éxito, la tubería se considera exitosa.

Por lo tanto, tenemos:

  • canalización: un conjunto de tareas organizadas en etapas en las que puede compilar, probar, empaquetar código, implementar una compilación terminada en un servicio en la nube, etc.
  • escenario (escenario) — unidad de organización de tubería, contiene 1+ tarea,
  • tarea (trabajo) es una unidad de trabajo en la canalización. Consiste en un script (obligatorio), condiciones de lanzamiento, configuraciones para publicar/almacenar en caché artefactos y mucho más.

En consecuencia, la tarea al configurar CI/CD se reduce a crear un conjunto de tareas que implementen todas las acciones necesarias para construir, probar y publicar código y artefactos.

Antes de empezar: ¿por qué?

  • ¿Por qué Gitlab?

Porque cuando se hizo necesario crear repositorios privados para proyectos favoritos, se les pagaba en GitHub y yo era codicioso. Los repositorios se han vuelto gratuitos, pero hasta ahora esto no es motivo suficiente para cambiarme a GitHub.

  • ¿Por qué no canalizaciones de Azure DevOps?

Porque allí la configuración es elemental: ni siquiera se requiere conocimiento de la línea de comando. Integración con proveedores de git externos: en un par de clics, importación de claves SSH para enviar confirmaciones al repositorio; también, la canalización se configura fácilmente incluso sin una plantilla.

Posición inicial: lo que tienes y lo que quieres

Tenemos:

  • repositorio en GitLab.

Queremos:

  • montaje automático y prueba para cada solicitud de fusión,
  • construyendo paquetes para cada solicitud de fusión y empujando al maestro, siempre que haya una cierta línea en el mensaje de confirmación,
  • enviar paquetes creados a una fuente privada en Azure DevOps,
  • montaje de documentación y publicación en GitLab Pages,
  • insignias! 11

Los requisitos descritos caen orgánicamente en el siguiente modelo de tubería:

  • Etapa 1 - Montaje
    • Recopilamos el código, publicamos los archivos de salida como artefactos
  • Etapa 2 - prueba
    • Obtenemos artefactos de la etapa de construcción, ejecutamos pruebas, recopilamos datos de cobertura de código
  • Etapa 3 - Enviar
    • Tarea 1: compilar el paquete nuget y enviarlo a Azure DevOps
    • Tarea 2: recopilamos el sitio de xmldoc en el código fuente y lo publicamos en GitLab Pages

¡Empecemos!

Recopilación de la configuración

Preparando cuentas

  1. Crea una cuenta en microsoft Azure

  2. Pasamos a Azure DevOps

  3. Creamos un nuevo proyecto

    1. Nombre - cualquiera
    2. Visibilidad - cualquiera
      Una guía de CI/CD en GitLab para el (casi) principiante absoluto

  4. Cuando haga clic en el botón Crear, se creará el proyecto y será redirigido a su página. En esta página, puede deshabilitar funciones innecesarias yendo a la configuración del proyecto (enlace inferior en la lista de la izquierda -> Descripción general -> Bloque de Azure DevOps Services)
    Una guía de CI/CD en GitLab para el (casi) principiante absoluto

  5. Vaya a Atrifacts, haga clic en Crear feed

    1. Ingrese el nombre de la fuente
    2. Elige visibilidad
    3. Desmarcar Incluir paquetes de fuentes públicas comunes, para que la fuente no se convierta en un clon nuget de volcado
      Una guía de CI/CD en GitLab para el (casi) principiante absoluto

  6. Haga clic en Conectar a fuente, seleccione Visual Studio, copie Fuente desde el bloque Configuración de máquina
    Una guía de CI/CD en GitLab para el (casi) principiante absoluto

  7. Vaya a la configuración de la cuenta, seleccione Token de acceso personal
    Una guía de CI/CD en GitLab para el (casi) principiante absoluto

  8. Crear un nuevo token de acceso

    1. Nombre - arbitrario
    2. Organización - actual
    3. Válido por un máximo de 1 año
    4. Alcance: empaquetado/lectura y escritura
      Una guía de CI/CD en GitLab para el (casi) principiante absoluto

  9. Copie el token creado - después de que se cierre la ventana modal, el valor no estará disponible

  10. Vaya a la configuración del repositorio en GitLab, seleccione la configuración de CI / CD
    Una guía de CI/CD en GitLab para el (casi) principiante absoluto

  11. Expanda el bloque Variables, agregue uno nuevo

    1. Nombre: cualquiera sin espacios (estará disponible en el shell de comandos)
    2. Valor - token de acceso del párrafo 9
    3. Seleccionar variable Máscara
      Una guía de CI/CD en GitLab para el (casi) principiante absoluto

Esto completa la configuración previa.

Preparación del marco de configuración

Por defecto, la configuración de CI/CD en GitLab usa el archivo .gitlab-ci.yml desde la raíz del repositorio. Puede establecer una ruta arbitraria a este archivo en la configuración del repositorio, pero en este caso no es necesario.

Como puede ver en la extensión, el archivo contiene una configuración en el formato YAML. La documentación detalla qué claves pueden estar contenidas en el nivel superior de la configuración y en cada uno de los niveles anidados.

Primero, agreguemos un enlace a la imagen de la ventana acoplable en el archivo de configuración, en el que se realizarán las tareas. Para esto encontramos Página de imágenes de .Net Core en Docker Hub. En GitHub hay una guía detallada sobre qué imagen elegir para diferentes tareas. Una imagen con .Net Core 3.1 es adecuada para que la construyamos, así que no dude en agregar la primera línea a la configuración

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

Ahora, cuando se inicie la canalización desde el repositorio de imágenes de Microsoft, se descargará la imagen especificada, en la que se ejecutarán todas las tareas de la configuración.

El siguiente paso es agregar escenario's. Por defecto, GitLab define 5 etapas:

  • .pre - realizado hasta todas las etapas,
  • .post - realizado después de todas las etapas,
  • build - primero después .pre escenario,
  • test - segunda fase,
  • deploy - la tercera etapa.

Sin embargo, nada le impide declararlos explícitamente. El orden en que se enumeran los pasos afecta el orden en que se realizan. Para completar, agreguemos a la configuración:

stages:
  - build
  - test
  - deploy

Para la depuración, tiene sentido obtener información sobre el entorno en el que se ejecutan las tareas. Agreguemos un conjunto global de comandos que se ejecutarán antes de cada tarea con before_script:

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

Queda por agregar al menos una tarea para que cuando se envíen los commits se inicie el pipeline. Por ahora, agreguemos una tarea vacía para demostrar:

dummy job:
  script:
    - echo ok

Comenzamos la validación, recibimos un mensaje de que todo está bien, nos comprometemos, presionamos, miramos los resultados en el sitio ... Y recibimos un error de secuencia de comandos: bash: .PSVersion: command not found. wtf?

Todo es lógico: de forma predeterminada, los corredores (responsables de ejecutar scripts de tareas y proporcionados por GitLab) usan bash para ejecutar comandos. Puede solucionar esto especificando explícitamente en la descripción de la tarea qué etiquetas debe tener el ejecutor de la canalización en ejecución:

dummy job on windows:
  script:
    - echo ok
  tags:
    - windows

¡Excelente! La canalización ahora se está ejecutando.

Un lector atento, después de haber repetido los pasos indicados, notará que la tarea se completó en la etapa test, aunque no especificamos el escenario. Como puedes adivinar test es el paso predeterminado.

Sigamos creando el esqueleto de configuración agregando todas las tareas descritas anteriormente:

build job:
  script:
    - echo "building..."
  tags:
    - windows
  stage: build

test and cover job:
  script:
    - echo "running tests and coverage analysis..."
  tags:
    - windows
  stage: test

pack and deploy job:
  script:
    - echo "packing and pushing to nuget..."
  tags:
    - windows
  stage: deploy

pages:
  script:
    - echo "creating docs..."
  tags:
    - windows
  stage: deploy

Obtuvimos una tubería no particularmente funcional, pero sin embargo correcta.

Configuración de disparadores

Debido al hecho de que no se especifican filtros desencadenantes para ninguna de las tareas, la canalización completamente ejecutarse cada vez que se envía una confirmación al repositorio. Dado que este no es el comportamiento deseado en general, configuraremos filtros de activación para tareas.

Los filtros se pueden configurar en dos formatos: solo/excepto и reglas. Brevemente, only/except permite configurar filtros por disparadores (merge_request, por ejemplo, establece la tarea que se ejecutará cada vez que se cree una solicitud de extracción y cada vez que se envíen confirmaciones a la rama que es el origen de la solicitud de fusión) y los nombres de las ramas (incluido el uso de expresiones regulares); rules le permite personalizar un conjunto de condiciones y, opcionalmente, cambiar la condición de ejecución de la tarea según el éxito de las tareas anteriores (when en GitLab CI/CD).

Recordemos un conjunto de requisitos: ensamblaje y prueba solo para solicitudes de combinación, empaquetado y envío a Azure DevOps, para solicitudes de combinación y envíos al maestro, generación de documentación, para envíos al maestro.

Primero, configuremos la tarea de compilación de código agregando una regla que se active solo en la solicitud de combinación:

build job:
  # snip
  only:
    - merge_request

Ahora configuremos la tarea de empaquetado para que se active en la solicitud de fusión y agregue confirmaciones al maestro:

pack and deploy job:
  # snip
  only:
    - merge_request
    - master

Como puede ver, todo es simple y directo.

También puede configurar la tarea para que se active solo si se crea una solicitud de combinación con una rama de destino o fuente específica:

  rules:
    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"

Bajo condiciones, puede usar variables enumeradas aquí; normas rules incompatible con las normas only/except.

Configuración del guardado de artefactos

durante una tarea build job tendremos artefactos de construcción que se pueden reutilizar en tareas posteriores. Para hacer esto, debe agregar las rutas a la configuración de la tarea, los archivos a lo largo de los cuales deberá guardar y reutilizar en las siguientes tareas, a la clave artifacts:

build job:
  # snip
  artifacts:
    paths:
      - path/to/build/artifacts
      - another/path
      - MyCoolLib.*/bin/Release/*

Las rutas admiten comodines, lo que definitivamente las hace más fáciles de configurar.

Si una tarea crea artefactos, cada tarea subsiguiente podrá acceder a ellos; se ubicarán a lo largo de las mismas rutas en relación con la raíz del repositorio que se recopilaron de la tarea original. Los artefactos también están disponibles para descargar en el sitio.

Ahora que tenemos un marco de configuración listo (y probado), podemos proceder a escribir scripts para tareas.

Escribimos guiones

Tal vez, alguna vez, en una galaxia muy, muy lejana, crear proyectos (incluidos los de .net) desde la línea de comandos era una molestia. Ahora puede compilar, probar y publicar el proyecto en 3 equipos:

dotnet build
dotnet test
dotnet pack

Naturalmente, hay algunos matices por los que complicaremos un poco los comandos.

  1. Queremos una compilación de lanzamiento, no una compilación de depuración, por lo que agregamos a cada comando -c Release
  2. Al realizar pruebas, queremos recopilar datos de cobertura de código, por lo que debemos incluir un analizador de cobertura en las bibliotecas de prueba:
    1. Agregar el paquete a todas las bibliotecas de prueba coverlet.msbuild: dotnet add package coverlet.msbuild de la carpeta del proyecto
    2. Agregar al comando de ejecución de prueba /p:CollectCoverage=true
    3. Agregue una clave a la configuración de la tarea de prueba para obtener resultados de cobertura (consulte a continuación)
  3. Al empaquetar el código en paquetes nuget, configure el directorio de salida para los paquetes: -o .

Recopilación de datos de cobertura de código

Después de ejecutar las pruebas, Coverlet imprime estadísticas de ejecución en la consola:

Calculating coverage result...
  Generating report 'C:Usersxxxsourcereposmy-projectmyProject.testscoverage.json'

+-------------+--------+--------+--------+
| Module      | Line   | Branch | Method |
+-------------+--------+--------+--------+
| project 1   | 83,24% | 66,66% | 92,1%  |
+-------------+--------+--------+--------+
| project 2   | 87,5%  | 50%    | 100%   |
+-------------+--------+--------+--------+
| project 3   | 100%   | 83,33% | 100%   |
+-------------+--------+--------+--------+

+---------+--------+--------+--------+
|         | Line   | Branch | Method |
+---------+--------+--------+--------+
| Total   | 84,27% | 65,76% | 92,94% |
+---------+--------+--------+--------+
| Average | 90,24% | 66,66% | 97,36% |
+---------+--------+--------+--------+

GitLab le permite especificar una expresión regular para obtener estadísticas, que luego se pueden obtener en forma de insignia. La expresión regular se especifica en la configuración de la tarea con la clave coverage; la expresión debe contener un grupo de captura, cuyo valor se pasará a la insignia:

test and cover job:
  # snip
  coverage: /|s*Totals*|s*(d+[,.]d+%)/

Aquí obtenemos estadísticas de una línea con cobertura total de línea.

Publicar paquetes y documentación.

Ambas acciones están programadas para la última etapa de la tubería: ya que el montaje y las pruebas han pasado, podemos compartir nuestros desarrollos con el mundo.

Primero, considere publicar en la fuente del paquete:

  1. Si el proyecto no tiene un archivo de configuración nuget (nuget.config), crea uno nuevo: dotnet new nugetconfig

    Para qué: es posible que la imagen no tenga acceso de escritura a las configuraciones globales (usuario y máquina). Para no detectar errores, simplemente creamos una nueva configuración local y trabajamos con ella.

  2. Agreguemos una nueva fuente de paquete a la configuración local: nuget sources add -name <name> -source <url> -username <organization> -password <gitlab variable> -configfile nuget.config -StorePasswordInClearText
    1. name - nombre de fuente local, no crítico
    2. url - URL de la fuente de la etapa "Preparación de cuentas", página 6
    3. organization - nombre de la organización en Azure DevOps
    4. gitlab variable - el nombre de la variable con el token de acceso agregado a GitLab ("Preparación de cuentas", p. 11). Naturalmente, en el formato $variableName
    5. -StorePasswordInClearText - un truco para eludir el error de acceso denegado (No soy el primero en pisar este rastrillo)
    6. En caso de errores, puede ser útil agregar -verbosity detailed
  3. Envío del paquete a la fuente: nuget push -source <name> -skipduplicate -apikey <key> *.nupkg
    1. Enviamos todos los paquetes desde el directorio actual, por lo que *.nupkg.
    2. name - del paso anterior.
    3. key - cualquier línea. En Azure DevOps, en la ventana Conectar a fuente, el ejemplo siempre es la línea az.
    4. -skipduplicate - al intentar enviar un paquete ya existente sin esta clave, la fuente devolverá un error 409 Conflict; con la tecla se saltará el envío.

Ahora configuremos la creación de documentación:

  1. Primero, en el repositorio, en la rama maestra, inicializamos el proyecto docfx. Para hacer esto, ejecute el comando desde la raíz docfx init y establecer de forma interactiva los parámetros clave para la documentación de construcción. Descripción detallada de la configuración mínima del proyecto aquí.
    1. Al configurar, es importante especificar el directorio de salida ..public - GitLab por defecto toma el contenido de la carpeta pública en la raíz del repositorio como fuente para Pages. Porque el proyecto se ubicará en una carpeta anidada en el repositorio: agregue una salida al nivel superior en la ruta.
  2. Empujemos los cambios a GitLab.
  3. Agregar una tarea a la configuración de canalización pages (palabra reservada para tareas de publicación de sitios en GitLab Pages):
    1. script:
      1. nuget install docfx.console -version 2.51.0 - instalar docfx; la versión se especifica para garantizar que las rutas de instalación del paquete sean correctas.
      2. .docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json - recopilar documentación
    2. Artefactos de nodo:

pages:
  # snip
  artifacts:
    paths:
      - public

Digresión lírica sobre docfx

Anteriormente, al configurar un proyecto, especificaba el código fuente de la documentación como un archivo de solución. La principal desventaja es que también se crea documentación para proyectos de prueba. En caso de que esto no sea necesario, puede establecer este valor en el nodo metadata.src:

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

  1. metadata.src.src: "../" - subimos un nivel en relación con la ubicación docfx.json, porque en los patrones, la búsqueda en el árbol de directorios no funciona.
  2. metadata.src.files: ["**/*.csproj"] - un patrón global, recopilamos todos los proyectos C # de todos los directorios.
  3. metadata.src.exclude: ["*.tests*/**"] - patrón global, excluye todo de las carpetas con .tests en el nombre

Subtotal

Una configuración tan simple se puede crear en solo media hora y un par de tazas de café, lo que le permitirá verificar que el código está construido y las pruebas pasan, construir un nuevo paquete, actualizar la documentación y complacer a la vista con hermosas insignias en el LÉAME del proyecto con cada solicitud de fusión y envío al maestro.

.gitlab-ci.yml final

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

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

stages:
  - build
  - test
  - deploy

build job:
  stage: build
  script:
    - dotnet build -c Release
  tags:
    - windows
  only:
    - merge_requests
    - master
  artifacts:
    paths:
      - your/path/to/binaries

test and cover job:
  stage: test
  tags:
    - windows
  script:
    - dotnet test -c Release /p:CollectCoverage=true
  coverage: /|s*Totals*|s*(d+[,.]d+%)/
  only:
    - merge_requests
    - master

pack and deploy job:
  stage: deploy
  tags:
    - windows
  script:
    - dotnet pack -c Release -o .
    - dotnet new nugetconfig
    - nuget sources add -name feedName -source https://pkgs.dev.azure.com/your-organization/_packaging/your-feed/nuget/v3/index.json -username your-organization -password $nugetFeedToken -configfile nuget.config -StorePasswordInClearText
    - nuget push -source feedName -skipduplicate -apikey az *.nupkg
  only:
    - master

pages:
  tags:
    - windows
  stage: 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
  artifacts:
    paths:
      - public
  only:
    - master

Hablando de insignias

¡Por ellos, después de todo, todo comenzó!

Las insignias con estados de canalización y cobertura de código están disponibles en GitLab en la configuración de CI/CD en el bloque de canalizaciones Gtntral:

Una guía de CI/CD en GitLab para el (casi) principiante absoluto

Creé una insignia con un enlace a la documentación en la plataforma escudos.io - Todo es bastante sencillo allí, puede crear su propia insignia y recibirla mediante una solicitud.

![Пример с Shields.io](https://img.shields.io/badge/custom-badge-blue)

Una guía de CI/CD en GitLab para el (casi) principiante absoluto

Azure DevOps Artifacts también le permite crear insignias para paquetes con la versión más reciente. Para hacer esto, en la fuente en el sitio de Azure DevOps, debe hacer clic en Crear insignia para el paquete seleccionado y copiar el marcado de descuento:

Una guía de CI/CD en GitLab para el (casi) principiante absoluto

Una guía de CI/CD en GitLab para el (casi) principiante absoluto

Agregando belleza

Resaltar fragmentos de configuración comunes

Mientras escribía la configuración y buscaba en la documentación, encontré una característica interesante de YAML: la reutilización de fragmentos.

Como puede ver en la configuración de tareas, todas requieren la etiqueta windows en el corredor, y se activan cuando se envía una solicitud de fusión al maestro/creada (excepto la documentación). Agreguemos esto al fragmento que reutilizaremos:

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

Y ahora podemos insertar el fragmento declarado anteriormente en la descripción de la tarea:

build job:
  <<: *common_tags
  <<: *common_only

Los nombres de los fragmentos deben comenzar con un punto, para que no se interpreten como una tarea.

Versiones de paquetes

Al crear un paquete, el compilador verifica los interruptores de la línea de comando y, en su ausencia, los archivos del proyecto; cuando encuentra un nodo Version, toma su valor como la versión del paquete que se está construyendo. Resulta que para crear un paquete con una nueva versión, debe actualizarlo en el archivo del proyecto o pasarlo como un argumento de línea de comando.

Agreguemos una lista de deseos más: deje que los dos números menores en la versión sean el año y la fecha de compilación del paquete, y agregue versiones preliminares. Por supuesto, puede agregar estos datos al archivo del proyecto y verificar antes de cada envío, pero también puede hacerlo en la tubería, recopilando la versión del paquete del contexto y pasándola a través del argumento de la línea de comando.

Acordemos que si el mensaje de confirmación contiene una línea como release (v./ver./version) <version number> (rev./revision <revision>)?, luego tomaremos la versión del paquete de esta línea, la complementaremos con la fecha actual y la pasaremos como argumento al comando dotnet pack. En ausencia de una línea, simplemente no recogeremos el paquete.

El siguiente script resuelve este problema:

# регулярное выражение для поиска строки с версией
$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

Adición de un script a una tarea pack and deploy job y observar el ensamblaje de paquetes estrictamente en presencia de una cadena determinada en el mensaje de confirmación.

En total

Después de pasar aproximadamente media hora o una hora escribiendo la configuración, depurando el powershell local y, posiblemente, un par de lanzamientos fallidos, obtuvimos una configuración simple para automatizar tareas de rutina.

Por supuesto, GitLab CI/CD es mucho más extenso y multifacético de lo que parece después de leer esta guía. esta completamente equivocado. allí incluso Auto DevOps espermitiendo

detectar, construir, probar, implementar y monitorear automáticamente sus aplicaciones

Ahora los planes son configurar una canalización para implementar aplicaciones en Azure, usando Pulumi y determinando automáticamente el entorno de destino, que se tratará en el siguiente artículo.

Fuente: habr.com

Añadir un comentario