Guida - 12 min

Il deploy dal repository

Il repository è la fonte di un'app Archestack, così come il codice sorgente è la fonte di un programma. Un deployment tratta Archestack come il compilatore: una pipeline costruisce un Archestack usa e getta dai file del repository, ci esegue i test e solo se passano pianifica la modifica rispetto all'ambiente ospitato e la applica lì. L'ambiente ospitato continua a servire i suoi utenti per tutto il tempo.

Stato: l'Archestack CLI esegue tutte le fasi qui sotto, da uno step di script in qualsiasi pipeline. I task di pipeline già pronti per Azure DevOps e GitHub Actions che la racchiudono sono in sviluppo; Cosa funziona oggi dice cosa esegue ogni fase.

Il tuo sistema CI

La 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 esegue la build, i test e il piano rispetto all'ambiente di test, così un revisore vede cosa cambierebbe prima che venga fatto il merge di qualsiasi cosa. Un merge sul branch principale esegue tutte le fasi, e collaudo e produzione aspettano ciascuno che una persona ne approvi il piano.

1. Build: Archestack come compilatore

La pipeline avvia un Archestack vuoto sull'agente di build, in Docker dalla stessa immagine dell'API che fanno girare gli ambienti, oppure da una cartella di runtime come quella con cui l'estensione VS Code fa girare i progetti, e ci carica il repository: le tabelle di tutti i package in un solo deployment, poi gli artefatti di ogni package, con le dipendenze prima dei package che ne hanno bisogno. È qui che un errore si vede per primo, come un errore di compilazione: un riferimento a una business entity, a una tabella o a uno script che non esiste, o un nome che un altro package usa già, ferma il caricamento. Il risultato è un ambiente creato solo dai file, senza niente rimasto dalla macchina di qualcuno.

2. Test

I test case di ogni package girano sulla build, ognuno in un proprio database sandbox, con mail e notifiche registrate invece che inviate. Ogni script eseguito da un test viene prima compilato, quindi uno script che non compila più fa fallire il suo test. Un solo test case fallito ferma la pipeline, e non viene fatto il deploy di niente.

3. Piano rispetto all'ambiente di destinazione

Gli stessi file vengono pianificati rispetto all'ambiente di destinazione: quali artefatti vengono creati, modificati o rimossi lì, e quali modifiche alle tabelle vengono eseguite come SQL, con il rischio di ogni operazione e gli script tipizzati che la modifica smetterebbe di far compilare. Il piano porta con sé un hash. Il deployment applica esattamente il piano approvato: se nel frattempo la destinazione è cambiata, viene rifiutato e il piano viene rifatto.

4. Deploy: schema, file, release

  1. Schema. Le modifiche alle tabelle vengono eseguite come deployment del database, elencato nella cronologia dei deployment dell'ambiente come qualsiasi altro. Una modifica che perde dati viene eseguita solo quando la pipeline consente esplicitamente la perdita di dati.
  2. File. Gli artefatti vengono scritti in un'unica transazione, quindi gli utenti vedono tutta la nuova versione di un package o niente. Un deployment tocca solo ciò che il package contiene e crea, e mai ciò che ogni ambiente decide per conto suo.
  3. Release. Una volta arrivati i file, la pipeline pubblica una release da sola. È il momento in cui le nuove pagine e gli app layout raggiungono l'app pubblicata, e nessuno pubblica a mano. Ogni deployment è una nuova versione dell'app con una release tutta sua.

Un ambiente che non ha mai pubblicato una release mostra le sue bozze, quindi i nuovi file sarebbero visibili nel momento in cui arrivano. Prima del primo deployment in un ambiente del genere, la pipeline pubblica perciò una release di ciò che l'ambiente contiene già, e da lì in poi i nuovi file aspettano come bozze finché non arriva la loro release, come in ogni deployment successivo.

Perché l'ambiente resta disponibile

  • Niente si riavvia. Un deployment consiste in dati nei database dell'ambiente, non in una nuova build del server. L'API continua a rispondere per tutto il tempo, e uno script modificato viene compilato la prima volta che gira.
  • I file arrivano tutti insieme. Una transazione per package, quindi nessuno lavora su mezzo package.
  • Le pagine cambiano in un solo passo. L'app pubblicata legge la release corrente. Le nuove pagine aspettano come bozze finché la release non viene pubblicata, cosa che porta tutti gli utenti alle nuove pagine nello stesso momento. Attivare la release precedente fa il rollback; questo ripristina le pagine e i layout, mai i dati o le tabelle.
  • Le modifiche alle tabelle vengono pianificate e riviste. Aggiungere una tabella o una colonna nullable non intralcia nessuno, e tutto ciò che perde dati richiede un sì esplicito.

Prima espandi, poi contrai

Script module, business event e business entity sono attivi nel momento in cui arrivano i loro file, non alla release. Una modifica che rinomina o rimuove una colonna si fa quindi in due deployment:

  1. Espandi. Aggiungi la nuova tabella o colonna, e fai il deploy degli script e delle pagine che la usano, con quella vecchia ancora al suo posto.
  2. Contrai. In un deployment successivo, quando niente legge più la vecchia colonna, eliminala. Il piano segna l'eliminazione come perdita di dati, e il controllo degli script tipizzati dice se qualcosa la usa ancora.

Una modifica che riscrive una tabella grande, come un nuovo tipo per una colonna, tiene un lock su quella tabella mentre gira. Programma modifiche come queste per un momento tranquillo.

Ambienti

Il repository elenca i suoi ambienti in archestack.json. Un ambiente marcato "mode": "pipeline" riceve i deploy solo dalla pipeline, e l'estensione VS Code si rifiuta di fare un push manuale verso di esso:

"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" }
}

Ciò che ogni ambiente decide per conto suo non è nei file e non è in nessun deployment: utenti e ruoli, permessi delle pagine, flag pubblici, autorizzazioni e chiavi della Data API, account di posta e connessioni ad altri sistemi. Li impostano gli amministratori di ogni ambiente, quindi un deployment non può mai rendere pubblico qualcosa o dare accesso a qualcuno.

Il file della pipeline

La pipeline vive nel repository e fa il deploy da lì: ogni esecuzione fa il checkout di un solo commit, e build, test e deploy si fanno proprio su quei file. Niente viene esportato da un workspace. Qui sotto c'è la stessa pipeline per tre sistemi di CI, e ognuna porta una modifica in test, collaudo e produzione. I comandi archestack sono quelli dell'Archestack CLI, quindi qualsiasi altro sistema di CI che fa girare .NET e Docker su Linux esegue gli stessi passi.

  • La fase Build and test gira per ogni pull request e per ogni merge su main. Costruisce un Archestack usa e getta dal commit, esegue i test di ogni package e impacchetta il repository in un unico artefatto, così ogni ambiente riceve esattamente gli stessi file.
  • Un passo di piano e uno di deploy per ogni ambiente. Il piano viene fatto rispetto all'ambiente e mostrato nell'esecuzione; il deploy applica poi esattamente quel piano, dopo un'approvazione per collaudo e produzione. Gli ambienti vengono uno dopo l'altro, quindi il collaudo viene pianificato solo dopo il deploy in test, e la produzione solo dopo il deploy in collaudo. Una pull request si ferma dopo il piano rispetto all'ambiente di test.
  • Token di deploy. Il token di ogni ambiente si crea nel builder di quell'ambiente, in Operations, Deploy Tokens. Viene mostrato una sola volta, agisce come amministratore e serve solo per il deploy: non legge mai i dati dell'ambiente. L'indirizzo dell'ambiente viene da archestack.json.
Il tuo sistema CI

Azure DevOps

La pipeline è azure-pipelines.yml nella radice del repository:

# 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)
  • Approvazioni. Crea gli ambienti archestack-tst, archestack-acc e archestack-prd in Pipelines, Environments, e aggiungi un controllo Approvals a collaudo e produzione. Azure DevOps aspetta allora un approvatore prima che partano quelle fasi di deploy, con il piano nel riepilogo dell'esecuzione. I risultati dei test vengono pubblicati nell'esecuzione.
  • Credenziali. Il token di deploy di ogni ambiente è il segreto ARCHESTACK_TOKEN in un gruppo di variabili con lo stesso nome dell'ambiente, come archestack-prd.
  • Perdita di dati. Allow changes that lose data è una casella di controllo che compare quando un'esecuzione viene avviata a mano, disattivata per impostazione predefinita. Se non è spuntata, un piano che elimina una tabella o una colonna ferma la pipeline.
  • Pull request su Azure Repos. Azure Repos ignora la sezione pr:; aggiungi invece la pipeline come build validation branch policy su main.
  • Una pipeline creata nell'editor web viene salvata come un nuovo file con il nome della pipeline. Nelle impostazioni della pipeline puntala su azure-pipelines.yml, altrimenti il file che modifichi non è quello che gira.

GitHub Actions

Il workflow è .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 }}

Ogni ambiente viene pianificato e riceve il deploy dallo stesso workflow riutilizzabile accanto:

# .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 }}
  • Approvazioni. Crea gli ambienti archestack-tst, archestack-acc e archestack-prd in Settings, Environments, e aggiungi dei required reviewers a collaudo e produzione. Il job di deploy aspetta un revisore, con il piano già nel riepilogo dell'esecuzione. Su un repository privato, gli ambienti richiedono GitHub Pro, Team o Enterprise.
  • Credenziali. I token di deploy sono i segreti del repository ARCHESTACK_TOKEN_TST, ARCHESTACK_TOKEN_ACC e ARCHESTACK_TOKEN_PRD, così il piano può girare prima dell'approvazione. Un workflow su qualsiasi branch del repository può leggere un segreto del repository; per riservare il token di produzione alle esecuzioni approvate, rendilo invece un segreto dell'ambiente archestack-prd, e il suo piano gira allora dopo l'approvazione.
  • Perdita di dati. Allow changes that lose data è una casella di controllo sotto Run workflow, disattivata per impostazione predefinita.
  • Le pull request da un fork non ricevono segreti, quindi il loro piano rispetto all'ambiente di test fallisce; le pull request dai branch del repository stesso vengono pianificate come al solito.
  • concurrency impedisce a due esecuzioni di fare il deploy nello stesso ambiente nello stesso momento. I risultati dei test restano come artefatto tests dell'esecuzione.

GitLab CI

La pipeline è .gitlab-ci.yml nella radice del repository:

# .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 build fa girare l'Archestack usa e getta su un servizio docker:dind accanto al job, cosa che richiede un runner che consenta container privilegiati, come i runner di GitLab.com stesso. DOCKER_HOST dice alla CLI dove si trova Docker, e la CLI raggiunge lì l'Archestack.
  • Approvazioni. Il deploy in collaudo e quello in produzione sono job manuali che bloccano la pipeline, avviati ciascuno dopo che il suo piano è stato letto. Ogni piano resta con il suo job, e il piano rispetto all'ambiente di test è anche collegato dalla merge request. Su GitLab Premium, proteggi anche quegli ambienti e richiedi le approvazioni.
  • Credenziali. I token di deploy sono le variabili CI/CD mascherate ARCHESTACK_TOKEN_TST, ARCHESTACK_TOKEN_ACC e ARCHESTACK_TOKEN_PRD. Proteggi quelle di collaudo e produzione, così solo il branch principale le legge. Una variabile protetta non arriva a una pipeline di merge request, quindi lascia non protetta quella di test perché le merge request possano fare il piano rispetto all'ambiente di test.
  • Perdita di dati. Avvia la pipeline a mano con ALLOW_DATA_LOSS impostato a true. I risultati dei test compaiono nella merge request.
  • resource_group impedisce a due pipeline di fare il deploy nello stesso ambiente nello stesso momento.

L'Archestack CLI

La CLI è lo strumento .NET Archestack.Cli, installato con dotnet tool install --global Archestack.Cli su qualsiasi agente con .NET 8 o successivo. I suoi comandi girano dalla radice del repository, oppure prendono --from con una cartella o uno ZIP impacchettato:

  • archestack build avvia l'Archestack usa e getta e ci carica il repository. Gira in Docker dall'immagine indicata dalla sezione project di archestack.json, altrimenti dall'ultima pubblicata; --image ne sceglie un'altra, e --runtime fa girare una cartella di runtime senza Docker. È pronto quando i pacchetti NuGet che il repository nomina sono ripristinati, e resta in esecuzione per il passo successivo fino a archestack stop. --nuget-cache <folder> conserva quei download per la build successiva, che altrimenti li scarica di nuovo; due build che girano nello stesso momento hanno bisogno ciascuna di una cartella propria.
  • archestack test ci esegue i test case di ogni package, quattro alla volta, e scrive JUnit con --junit.
  • archestack pack --out app.zip impacchetta archestack.json, packages/ e workspace/. Gli stessi file danno sempre gli stessi byte, e il piano ne registra l'hash, quindi un deployment rifiuta file diversi da quelli pianificati.
  • archestack plan e archestack deploy funzionano solo su un ambiente marcato "mode": "pipeline", con il suo token di deploy in ARCHESTACK_TOKEN_<ENV> (come ARCHESTACK_TOKEN_PRD) o ARCHESTACK_TOKEN. Un artefatto eliminato dal repository viene tolto dal suo package e lasciato nell'ambiente; pianifica con --delete-removed true per eliminarlo anche lì. Un package nell'ambiente che il repository non contiene viene lasciato com'è e indicato nel piano. Quando il repository nomina pacchetti NuGet, entrambi chiedono prima all'ambiente se lì si possono ripristinare, e deploy aspetta fino a cinque minuti dopo l'ultimo push che l'ambiente li abbia ripristinati, prima di pubblicare la release. Se l'attesa non va a buon fine, il deploy dei file è fatto ma nessuna release viene pubblicata.

Il codice di uscita dice cosa ha fermato un passo: 3 il token è stato rifiutato, 4 l'ambiente è cambiato dopo il piano (rifai il piano), 5 i file non si possono applicare così come sono, 6 il piano perde dati e non era consentito, 7 un test è fallito, 9 il server o la rete non hanno funzionato, 10 l'ambiente fa girare una versione major di Archestack diversa da quella della CLI, o una senza supporto per NuGet. Pacchetti NuGet che non si ripristinano con i file danno 5, e così un ambiente in cui i pacchetti NuGet o l'accesso ai dati tipizzato sono disattivati. Per plan e deploy, un errore NuGet che i file non possono correggere dà 9: per esempio un server con poco spazio su disco, un feed che non raggiunge, o un ripristino dopo l'ultimo push che è fallito o non è finito in cinque minuti. Lo stesso passo può riuscire quando viene rieseguito.

Cosa funziona oggi

  • Build, test, piano e deploy girano sulla CLI, da step di script come nelle pipeline sopra. Sulla macchina di uno sviluppatore il progetto dell'estensione VS Code è la stessa build: Reset Project Database la crea da zero, e Run Tests ci esegue i test di tutti i package.
  • Task di pipeline per Azure DevOps e GitHub Actions che racchiudono la CLI: in sviluppo.

Trappole

  • Un rollback non annulla tabelle o dati. Ogni deployment è una release, quindi qualsiasi versione di cui la pipeline ha fatto il deploy può essere riattivata, ma questo ripristina solo pagine e layout. Riportare indietro le tabelle è un deployment a sé, pianificato e rivisto come qualsiasi altro.
  • Script module e business event non aspettano la release. Sono attivi nel momento in cui arrivano i loro file, ed è per questo che una modifica che rimuove qualcosa si fa in due deployment.
  • Ogni ambiente scarica i propri pacchetti NuGet. I pacchetti NuGet che il nuget.json di un package dichiara vengono scaricati da ogni ambiente che riceve quel package, la build compresa, quindi ognuno deve raggiungere nuget.org o il feed con cui sono configurati i suoi server. La build prende Scripting__NuGet__Sources e le impostazioni Scripting__NuGet__Feeds__* dall'ambiente in cui gira la CLI. Un push i cui pacchetti NuGet non si possono ripristinare viene rifiutato e non cambia niente: il comando plan della CLI lo controlla prima che venga fatto il deploy di qualsiasi cosa, e build e deploy aspettano che siano ripristinati.

Dove andare dopo

Lavorare in team descrive come gli sviluppatori condividono il repository di cui la pipeline fa il deploy. Workspace e hosting spiega gli ambienti in cui fa il deploy, e Database Deployments la fase dello schema.