Guía · 12 min

Desplegar desde el repositorio

El repositorio es la fuente de una aplicación de Archestack, igual que el código fuente es la fuente de un programa. Un despliegue trata a Archestack como el compilador: un pipeline construye un Archestack desechable a partir de los archivos del repositorio, ejecuta las pruebas contra él y, solo cuando pasan, planifica el cambio contra el entorno alojado y lo aplica allí. El entorno alojado sigue atendiendo a sus usuarios durante todo el proceso.

Estado: la Archestack CLI ejecuta todas las etapas descritas abajo, desde un paso de script en cualquier pipeline. Las tareas de pipeline listas para usar en Azure DevOps y GitHub Actions que la envuelven están en desarrollo; Lo que funciona hoy indica qué ejecuta cada etapa.

Tu sistema de CI

El pipeline

merge to main
  build     a throwaway Archestack made from the repository's files
  test      every package's test cases, each in a sandbox
  plan      against tst: artifacts and SQL, with a plan hash
  deploy    tst: schema, then files, then the release
  approve   the plan against acc, then deploy acc
  approve   the plan against prd, then deploy prd

Una pull request ejecuta la compilación, las pruebas y el plan contra el entorno de pruebas, así que quien revisa ve lo que cambiaría antes de fusionar nada. Una fusión con la rama principal ejecuta todas las etapas, y aceptación y producción esperan cada una a que una persona apruebe su plan.

1. Compilar: Archestack como compilador

El pipeline arranca un Archestack vacío en el agente de compilación, en Docker a partir de la misma imagen de la API que ejecutan los entornos, o a partir de una carpeta de runtime como la que usa la extensión de VS Code para ejecutar los proyectos, y carga en él el repositorio: las tablas de todos los paquetes en un solo despliegue y después los artefactos de cada paquete, con las dependencias antes que los paquetes que las necesitan. Aquí es donde aparece primero un error, igual que un error de compilación: una referencia a una business entity, una tabla o un script que no existe, o un nombre que ya usa otro paquete, detiene la carga. El resultado es un entorno hecho solo a partir de los archivos, sin nada que haya quedado de la máquina de nadie.

2. Probar

Los casos de prueba de todos los paquetes se ejecutan contra el resultado de la compilación, cada uno en una base de datos sandbox propia, con los correos y las notificaciones registrados en lugar de enviados. Cada script que ejecuta una prueba se compila primero, así que un script que ya no compila hace fallar su prueba. Un solo caso fallido detiene el pipeline, y no se despliega nada.

3. Planificar contra el destino

Los mismos archivos se planifican contra el entorno de destino: qué artefactos se crean, cambian o eliminan allí, y qué cambios de tablas se ejecutan como SQL, con el riesgo de cada operación y los scripts tipados que dejarían de compilar. El plan lleva un hash. El despliegue aplica exactamente el plan que se aprobó: si el destino ha cambiado entretanto, se rechaza y el plan se vuelve a hacer.

4. Desplegar: esquema, archivos, release

  1. Esquema. Los cambios de tablas se ejecutan como un despliegue de base de datos, que aparece en el historial de despliegues del entorno como cualquier otro. Un cambio que pierde datos solo se ejecuta cuando el pipeline permite explícitamente la pérdida de datos.
  2. Archivos. Los artefactos se escriben en una sola transacción, así que los usuarios ven toda la nueva versión de un paquete o nada de ella. Un despliegue solo toca lo que el paquete contiene y crea, y nunca lo que cada entorno decide por sí mismo.
  3. Release. Una vez escritos los archivos, el pipeline publica una release por sí solo. Ese es el momento en que las nuevas páginas y los app layouts llegan a la aplicación publicada, y nadie publica a mano. Cada despliegue es una nueva versión de la aplicación con una release propia.

Un entorno que nunca ha publicado una release muestra sus borradores, así que los archivos nuevos serían visibles en cuanto llegan. Por eso, antes de su primer despliegue en un entorno así, el pipeline publica una release de lo que el entorno ya contiene, y a partir de ahí los archivos nuevos esperan como borradores hasta su propia release, igual que en cada despliegue posterior.

Por qué el entorno sigue en marcha

  • No se reinicia nada. Un despliegue son datos en las bases de datos del entorno, no una nueva compilación del servidor. La API sigue respondiendo todo el tiempo, y un script cambiado se compila la primera vez que se ejecuta.
  • Los archivos llegan todos a la vez. Una transacción por paquete, así que nadie trabaja contra medio paquete.
  • Las páginas cambian en un solo paso. La aplicación publicada lee la release actual. Las páginas nuevas esperan como borradores hasta que se publica la release, que lleva a todos los usuarios a ellas en el mismo momento. Activar la release anterior revierte el cambio; eso restaura las páginas y los layouts, nunca los datos ni las tablas.
  • Los cambios de tablas se planifican y se revisan. Añadir una tabla o una columna que admite nulos no le estorba a nadie, y todo lo que pierde datos necesita un sí explícito.

Expandir, después contraer

Los script modules, los business events y las business entities entran en vigor en cuanto llegan sus archivos, no con la release. Por eso, un cambio que renombra o elimina una columna sale en dos despliegues:

  1. Expandir. Añade la tabla o la columna nueva y despliega los scripts y las páginas que la usan, con la antigua todavía en su sitio.
  2. Contraer. En un despliegue posterior, cuando ya nada lea la columna antigua, elimínala. El plan marca la eliminación como pérdida de datos, y la comprobación de scripts tipados indica si algo la sigue usando.

Un cambio que reescribe una tabla grande, como un tipo nuevo para una columna, mantiene un bloqueo sobre esa tabla mientras se ejecuta. Programa esos cambios para un momento tranquilo.

Entornos

El repositorio enumera sus entornos en archestack.json. Un entorno marcado con "mode": "pipeline" solo lo despliega el pipeline, y la extensión de VS Code se niega a enviarle nada a mano:

"environments": {
  "tst": { "url": "https://acme-tst.example.com", "apiUrl": "https://api.example.com", "workspace": "acme-tst.example.com", "mode": "pipeline" },
  "acc": { "url": "https://acme-acc.example.com", "apiUrl": "https://api.example.com", "workspace": "acme-acc.example.com", "mode": "pipeline" },
  "prd": { "url": "https://acme.example.com", "apiUrl": "https://api.example.com", "workspace": "acme.example.com", "mode": "pipeline" }
}

Lo que cada entorno decide por sí mismo no está en los archivos ni en ningún despliegue: los usuarios y los roles, los permisos de las páginas, lo que es público, los permisos y las claves de la Data API, las cuentas de correo y las conexiones con otros sistemas. Los fijan los administradores de cada entorno, así que un despliegue nunca puede hacer público algo ni dar acceso a nadie.

El archivo del pipeline

El pipeline vive en el repositorio y despliega desde él: cada ejecución hace checkout de un solo commit, y esos archivos son lo que se compila, se prueba y se despliega. No se exporta nada desde un espacio de trabajo. A continuación está el mismo pipeline para tres sistemas de CI, y cada uno lleva un cambio a pruebas, aceptación y producción. Los comandos archestack son los de la Archestack CLI, así que cualquier otro sistema de CI que ejecute .NET y Docker en Linux ejecuta los mismos pasos.

  • La compilación y las pruebas se ejecutan en cada pull request y en cada fusión con main. Se construye un Archestack desechable a partir del commit, se ejecutan las pruebas de todos los paquetes y se empaqueta el repositorio en un solo artefacto, así que todos los entornos reciben exactamente los mismos archivos.
  • Un plan y un despliegue por entorno. El plan se hace contra el entorno y se muestra en la ejecución; después, el despliegue aplica exactamente ese plan, tras una aprobación en aceptación y producción. Los entornos van uno tras otro, así que el de aceptación solo se planifica cuando el de pruebas ya está desplegado, y el de producción solo cuando lo está el de aceptación. Una pull request se detiene tras el plan contra el entorno de pruebas.
  • Tokens de despliegue. El token de cada entorno se crea en el builder de ese entorno, en Operations, Deploy Tokens. Se muestra una sola vez, actúa como administrador y solo sirve para desplegar: nunca lee los datos del entorno. La dirección del entorno sale de archestack.json.
Tu sistema de CI

Azure DevOps

El pipeline es azure-pipelines.yml en la raíz del repositorio:

# azure-pipelines.yml: build and test, then plan and deploy test, acceptance and production
trigger:
  branches:
    include: [main]

pr:
  branches:
    include: [main]

parameters:
  - name: environments
    type: object
    default: [tst, acc, prd]
  - name: allowDataLoss
    displayName: Allow changes that lose data
    type: boolean
    default: false

pool:
  vmImage: ubuntu-latest

stages:
  - stage: build
    displayName: Build and test
    jobs:
      - job: build
        steps:
          - checkout: self
            displayName: The repository at this commit
          - script: |
              dotnet tool install --global Archestack.Cli
              echo "##vso[task.prependpath]$HOME/.dotnet/tools"
            displayName: Install the Archestack CLI
          - script: archestack build
            displayName: Build a throwaway Archestack from the repository
          - script: archestack test --junit $(Agent.TempDirectory)/tests.xml
            displayName: Run every package's tests
          - task: PublishTestResults@2
            condition: succeededOrFailed()
            inputs:
              testResultsFormat: JUnit
              testResultsFiles: $(Agent.TempDirectory)/tests.xml
          - script: archestack pack --out $(Build.ArtifactStagingDirectory)/app.zip
            displayName: Pack the repository
          - publish: $(Build.ArtifactStagingDirectory)
            artifact: app

  - ${{ each env in parameters.environments }}:
    - stage: plan_${{ env }}
      displayName: Plan ${{ env }}
      ${{ if ne(env, 'tst') }}:
        condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
      variables:
        - group: archestack-${{ env }}
      jobs:
        - job: plan
          steps:
            - download: current
              artifact: app
            - script: |
                dotnet tool install --global Archestack.Cli
                echo "##vso[task.prependpath]$HOME/.dotnet/tools"
              displayName: Install the Archestack CLI
            - script: >-
                archestack plan --env ${{ env }}
                --from $(Pipeline.Workspace)/app/app.zip
                --allow-data-loss ${{ parameters.allowDataLoss }}
                --out $(Build.ArtifactStagingDirectory)/plan.json
                --summary $(Build.ArtifactStagingDirectory)/plan.md
              displayName: Plan against ${{ env }}
              env:
                ARCHESTACK_TOKEN: $(ARCHESTACK_TOKEN)
            - script: echo "##vso[task.uploadsummary]$(Build.ArtifactStagingDirectory)/plan.md"
              displayName: Show the plan in the run
            - publish: $(Build.ArtifactStagingDirectory)
              artifact: plan-${{ env }}

    - stage: deploy_${{ env }}
      displayName: Deploy ${{ env }}
      condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
      variables:
        - group: archestack-${{ env }}
      jobs:
        - deployment: deploy
          environment: archestack-${{ env }}
          strategy:
            runOnce:
              deploy:
                steps:
                  - download: current
                    artifact: app
                  - download: current
                    artifact: plan-${{ env }}
                  - script: |
                      dotnet tool install --global Archestack.Cli
                      echo "##vso[task.prependpath]$HOME/.dotnet/tools"
                    displayName: Install the Archestack CLI
                  - script: >-
                      archestack deploy --env ${{ env }}
                      --from $(Pipeline.Workspace)/app/app.zip
                      --plan $(Pipeline.Workspace)/plan-${{ env }}/plan.json
                    displayName: Schema, files and release
                    env:
                      ARCHESTACK_TOKEN: $(ARCHESTACK_TOKEN)
  • Aprobaciones. Crea los entornos archestack-tst, archestack-acc y archestack-prd en Pipelines, Environments, y añade una comprobación Approvals a aceptación y producción. Azure DevOps espera entonces a un aprobador antes de que empiecen esas etapas de despliegue, con el plan en el resumen de la ejecución. Los resultados de las pruebas se publican en la ejecución.
  • Credenciales. El token de despliegue de cada entorno es el secreto ARCHESTACK_TOKEN en un grupo de variables con el mismo nombre que el entorno, como archestack-prd.
  • Pérdida de datos. Allow changes that lose data es una casilla que aparece cuando una ejecución se inicia a mano, desmarcada por defecto. Si no se marca, un plan que elimina una tabla o una columna detiene el pipeline.
  • Pull requests en Azure Repos. Azure Repos ignora la sección pr:; en su lugar, añade el pipeline como build validation branch policy en main.
  • Un pipeline creado en el editor web se guarda como un archivo nuevo con el nombre del pipeline. En su configuración, haz que el pipeline apunte a azure-pipelines.yml, o el archivo que editas no será el que se ejecuta.

GitHub Actions

El workflow es .github/workflows/archestack.yml:

# .github/workflows/archestack.yml: build and test, then plan and deploy test, acceptance and production
name: Archestack

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:
    inputs:
      allow-data-loss:
        description: Allow changes that lose data
        type: boolean
        default: false

permissions:
  contents: read

jobs:
  build:
    name: Build and test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 8.0.x
      - name: Install the Archestack CLI
        run: dotnet tool install --global Archestack.Cli
      - name: Build a throwaway Archestack from the repository
        run: archestack build
      - name: Run every package's tests
        run: archestack test --junit "$RUNNER_TEMP/tests.xml"
      - uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: tests
          path: ${{ runner.temp }}/tests.xml
      - name: Pack the repository
        run: archestack pack --out "$RUNNER_TEMP/app/app.zip"
      - uses: actions/upload-artifact@v4
        with:
          name: app
          path: ${{ runner.temp }}/app

  # A pull request stops after the plan against test.
  tst:
    needs: build
    uses: ./.github/workflows/archestack-deploy.yml
    with:
      environment: tst
      deploy: ${{ github.event_name != 'pull_request' }}
      allow-data-loss: ${{ inputs.allow-data-loss == true }}
    secrets:
      token: ${{ secrets.ARCHESTACK_TOKEN_TST }}

  acc:
    if: github.event_name != 'pull_request'
    needs: tst
    uses: ./.github/workflows/archestack-deploy.yml
    with:
      environment: acc
      allow-data-loss: ${{ inputs.allow-data-loss == true }}
    secrets:
      token: ${{ secrets.ARCHESTACK_TOKEN_ACC }}

  prd:
    if: github.event_name != 'pull_request'
    needs: acc
    uses: ./.github/workflows/archestack-deploy.yml
    with:
      environment: prd
      allow-data-loss: ${{ inputs.allow-data-loss == true }}
    secrets:
      token: ${{ secrets.ARCHESTACK_TOKEN_PRD }}

Cada entorno lo planifica y lo despliega el mismo workflow reutilizable que está a su lado:

# .github/workflows/archestack-deploy.yml: plans the packed files against one environment, then deploys that plan
name: Archestack environment

on:
  workflow_call:
    inputs:
      environment:
        type: string
        required: true
      deploy:
        type: boolean
        default: true
      allow-data-loss:
        type: boolean
        default: false
    secrets:
      token:
        required: true

jobs:
  plan:
    name: Plan ${{ inputs.environment }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: app
          path: app
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 8.0.x
      - run: dotnet tool install --global Archestack.Cli
      - name: Plan against ${{ inputs.environment }}
        run: >-
          archestack plan --env ${{ inputs.environment }}
          --from app/app.zip
          --allow-data-loss ${{ inputs.allow-data-loss }}
          --out plan/plan.json
          --summary plan/plan.md
        env:
          ARCHESTACK_TOKEN: ${{ secrets.token }}
      - name: Show the plan in the run
        if: ${{ !cancelled() }}
        run: cat plan/plan.md >> "$GITHUB_STEP_SUMMARY"
      - uses: actions/upload-artifact@v4
        with:
          name: plan-${{ inputs.environment }}
          path: plan

  deploy:
    name: Deploy ${{ inputs.environment }}
    if: inputs.deploy
    needs: plan
    runs-on: ubuntu-latest
    environment: archestack-${{ inputs.environment }}
    concurrency: archestack-${{ inputs.environment }}
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: app
          path: app
      - uses: actions/download-artifact@v4
        with:
          name: plan-${{ inputs.environment }}
          path: plan
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 8.0.x
      - run: dotnet tool install --global Archestack.Cli
      - name: Schema, files and release
        run: archestack deploy --env ${{ inputs.environment }} --from app/app.zip --plan plan/plan.json
        env:
          ARCHESTACK_TOKEN: ${{ secrets.token }}
  • Aprobaciones. Crea los entornos archestack-tst, archestack-acc y archestack-prd en Settings, Environments, y añade required reviewers a aceptación y producción. El job de despliegue espera a un revisor, con el plan ya en el resumen de la ejecución. En un repositorio privado, los entornos requieren GitHub Pro, Team o Enterprise.
  • Credenciales. Los tokens de despliegue son los secretos de repositorio ARCHESTACK_TOKEN_TST, ARCHESTACK_TOKEN_ACC y ARCHESTACK_TOKEN_PRD, para que el plan pueda ejecutarse antes de la aprobación. Un workflow de cualquier rama del repositorio puede leer un secreto de repositorio; para reservar el token de producción a las ejecuciones aprobadas, conviértelo en un secreto de entorno de archestack-prd, y entonces su plan se ejecuta después de la aprobación.
  • Pérdida de datos. Allow changes that lose data es una casilla dentro de Run workflow, desmarcada por defecto.
  • Las pull requests desde forks no reciben secretos, así que su plan contra el entorno de pruebas falla; las pull requests desde ramas del propio repositorio planifican como siempre.
  • concurrency impide que dos ejecuciones desplieguen en un mismo entorno a la vez. Los resultados de las pruebas se guardan como el artefacto tests de la ejecución.

GitLab CI

El pipeline es .gitlab-ci.yml en la raíz del repositorio:

# .gitlab-ci.yml: build and test, then plan and deploy test, acceptance and production
workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

variables:
  ALLOW_DATA_LOSS:
    value: "false"
    description: Allow changes that lose data (true or false)

stages: [build, tst, acc, prd]

default:
  image: mcr.microsoft.com/dotnet/sdk:8.0
  before_script:
    - dotnet tool install --global Archestack.Cli
    - export PATH="$PATH:$HOME/.dotnet/tools"

build:
  stage: build
  # The throwaway Archestack runs in Docker, here a Docker service beside the job.
  services:
    - docker:27-dind
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_TLS_CERTDIR: ""
  script:
    - curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-27.3.1.tgz | tar -xz -C /usr/local/bin --strip-components=1 docker/docker
    - archestack build
    - archestack test --junit tests.xml
    - archestack pack --out app.zip
  artifacts:
    when: always
    paths: [app.zip]
    reports:
      junit: tests.xml

.plan:
  script:
    - archestack plan --env "$TARGET" --from app.zip --allow-data-loss "$ALLOW_DATA_LOSS" --out plan.json --summary plan.md
  artifacts:
    when: always
    expose_as: plan
    paths: [plan.md, plan.json]

.deploy:
  script:
    - archestack deploy --env "$TARGET" --from app.zip --plan plan.json

# A merge request stops after the plan against test.
plan-tst:
  extends: .plan
  stage: tst
  needs: [build]
  variables: { TARGET: tst }

deploy-tst:
  extends: .deploy
  stage: tst
  needs: [build, plan-tst]
  environment: archestack-tst
  resource_group: archestack-tst
  variables: { TARGET: tst }
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

plan-acc:
  extends: .plan
  stage: acc
  needs: [build, deploy-tst]
  variables: { TARGET: acc }
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

deploy-acc:
  extends: .deploy
  stage: acc
  needs: [build, plan-acc]
  environment: archestack-acc
  resource_group: archestack-acc
  variables: { TARGET: acc }
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual
  allow_failure: false

plan-prd:
  extends: .plan
  stage: prd
  needs: [build, deploy-acc]
  variables: { TARGET: prd }
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

deploy-prd:
  extends: .deploy
  stage: prd
  needs: [build, plan-prd]
  environment: archestack-prd
  resource_group: archestack-prd
  variables: { TARGET: prd }
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual
  allow_failure: false
  • Docker. La compilación ejecuta el Archestack desechable en un servicio docker:dind junto al job, lo que requiere un runner que permita contenedores privilegiados, como los propios runners de GitLab.com. DOCKER_HOST le indica a la CLI dónde está Docker, y allí llega al Archestack.
  • Aprobaciones. Los despliegues de aceptación y producción son jobs manuales que bloquean el pipeline, y cada uno se inicia una vez leído su plan. Cada plan se guarda con su job, y el plan contra el entorno de pruebas también se enlaza desde la merge request. En GitLab Premium, protege además esos entornos y exige aprobaciones.
  • Credenciales. Los tokens de despliegue son las variables de CI/CD enmascaradas ARCHESTACK_TOKEN_TST, ARCHESTACK_TOKEN_ACC y ARCHESTACK_TOKEN_PRD. Protege las de aceptación y producción, para que solo la rama main las lea. Una variable protegida no llega a un pipeline de merge request, así que deja sin proteger la de pruebas para que las merge requests puedan planificar contra el entorno de pruebas.
  • Pérdida de datos. Ejecuta el pipeline a mano con ALLOW_DATA_LOSS a true. Los resultados de las pruebas aparecen en la merge request.
  • resource_group impide que dos pipelines desplieguen en un mismo entorno a la vez.

La Archestack CLI

La CLI es la herramienta de .NET Archestack.Cli, que se instala con dotnet tool install --global Archestack.Cli en cualquier agente con .NET 8 o posterior. Sus comandos se ejecutan desde la raíz del repositorio, o reciben --from con una carpeta o un ZIP empaquetado:

  • archestack build arranca el Archestack desechable y carga en él el repositorio. Se ejecuta en Docker a partir de la imagen que indica la sección project de archestack.json, o si no, de la última publicada; --image elige otra, y --runtime ejecuta una carpeta de runtime sin Docker. Está listo cuando los paquetes NuGet que nombra el repositorio están restaurados, y sigue en marcha para el paso siguiente hasta archestack stop. --nuget-cache <folder> guarda esas descargas para la compilación siguiente, que si no las vuelve a descargar; dos compilaciones que se ejecutan a la vez necesitan cada una su propia carpeta.
  • archestack test ejecuta contra él los casos de prueba de todos los paquetes, cuatro a la vez, y escribe JUnit con --junit.
  • archestack pack --out app.zip empaqueta archestack.json, packages/ y workspace/. Los mismos archivos dan siempre los mismos bytes, y el plan registra su hash, así que un despliegue rechaza archivos distintos de los planificados.
  • archestack plan y archestack deploy solo funcionan sobre un entorno marcado con "mode": "pipeline", con su token de despliegue en ARCHESTACK_TOKEN_<ENV> (como ARCHESTACK_TOKEN_PRD) o en ARCHESTACK_TOKEN. Un artefacto eliminado del repositorio se saca de su paquete y se deja en el entorno; planifica con --delete-removed true para eliminarlo también allí. Un paquete del entorno que el repositorio no contiene se deja como está y se menciona en el plan. Cuando el repositorio nombra paquetes NuGet, los dos preguntan primero al entorno si se pueden restaurar allí, y deploy espera hasta cinco minutos tras el último push a que el entorno los haya restaurado, antes de publicar la release. Si esa espera falla, los archivos quedan desplegados pero no se publica ninguna release.

El código de salida indica qué detuvo un paso: 3 se rechazó el token, 4 el entorno ha cambiado desde el plan (vuelve a planificar), 5 los archivos no se pueden aplicar tal como están, 6 el plan pierde datos y eso no estaba permitido, 7 falló una prueba, 9 falló el servidor o la red, 10 el entorno ejecuta una versión principal de Archestack distinta de la de la CLI, o una sin soporte para NuGet. Los paquetes NuGet que no se restauran con los archivos dan un 5, y también un entorno que tiene desactivados los paquetes NuGet o el acceso a datos tipado. En plan y deploy, un fallo de NuGet que los archivos no pueden arreglar da un 9: por ejemplo un servidor con poco espacio en disco, un feed al que no llega, o una restauración tras el último push que falló o no terminó en cinco minutos. El mismo paso puede salir bien cuando se vuelve a ejecutar.

Lo que funciona hoy

  • Compilar, probar, planificar y desplegar se ejecutan con la CLI, desde pasos de script como en los pipelines de arriba. En la máquina de un desarrollador, el proyecto de la extensión de VS Code es la misma compilación: Reset Project Database lo crea desde cero, y Run Tests ejecuta contra él las pruebas de todos los paquetes.
  • Tareas de pipeline para Azure DevOps y GitHub Actions que envuelven la CLI: en desarrollo.

A tener en cuenta

  • Una reversión no deshace las tablas ni los datos. Cada despliegue es una release, así que cualquier versión que haya desplegado el pipeline se puede volver a activar, pero eso restaura solo las páginas y los layouts. Devolver las tablas a su estado anterior es un despliegue aparte, planificado y revisado como cualquier otro.
  • Los script modules y los business events no esperan a la release. Entran en vigor en cuanto llegan sus archivos, y por eso un cambio que elimina algo sale en dos despliegues.
  • Cada entorno descarga sus propios paquetes NuGet. Los paquetes NuGet que declara el nuget.json de un paquete los descarga cada entorno que lo recibe, la compilación incluida, así que cada uno necesita llegar a nuget.org o al feed con el que están configurados sus servidores. La compilación toma Scripting__NuGet__Sources y los ajustes Scripting__NuGet__Feeds__* del entorno en el que se ejecuta la CLI. Un push cuyos paquetes NuGet no se pueden restaurar se rechaza y no cambia nada: el plan de la CLI lo comprueba antes de desplegar nada, y build y deploy esperan hasta que estén restaurados.

Hacia dónde ir después

Trabajar en equipo explica cómo comparten los desarrolladores el repositorio que despliega el pipeline. Espacios de trabajo y alojamiento describe los entornos a los que despliega, y Database Deployments, el paso del esquema.