Handleiding - 12 min

Deployen vanuit de repository

De repository is de bron van een Archestack-app, zoals broncode de bron van een programma is. Een deployment behandelt Archestack als de compiler: een pipeline bouwt uit de bestanden van de repository een wegwerp-Archestack, draait de tests ertegen, en pas als die slagen, plant hij de wijziging tegen de gehoste omgeving en voert hij ze daar door. De gehoste omgeving blijft ondertussen haar gebruikers bedienen.

Status: de Archestack CLI voert elke stap hieronder uit, vanuit een scriptstap in eender welke pipeline. Kant-en-klare pipelinetaken voor Azure DevOps en GitHub Actions die hem omhullen, zijn in ontwikkeling; Wat vandaag draait zegt wat elke stap uitvoert.

Je CI-systeem

De 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

Een pull request draait de build, de tests en het plan tegen test, zodat een reviewer ziet wat er zou veranderen voordat er iets gemerged wordt. Een merge naar de main-branch draait elke stap, en acceptatie en productie wachten elk tot iemand hun plan goedkeurt.

1. Build: Archestack als de compiler

De pipeline start een lege Archestack op de build agent, in Docker vanuit hetzelfde API-image dat de omgevingen draaien, of vanuit een runtimemap zoals die waarmee de VS Code-extensie projecten draait, en laadt de repository erin: de tabellen van elke package in één deployment, daarna de artefacten van elke package, afhankelijkheden vóór de packages die ze nodig hebben. Hier komt een fout als eerste aan het licht, zoals een compileerfout: een verwijzing naar een business entity, tabel of script die niet bestaat, of een naam die een andere package al gebruikt, stopt het laden. Het resultaat is een omgeving die alleen uit de bestanden is gemaakt, zonder iets wat van iemands machine is achtergebleven.

2. Test

De testcases van elke package draaien tegen de build, elk in een eigen sandboxdatabase, en mail en meldingen worden vastgelegd in plaats van verstuurd. Elk script dat in een test draait, wordt eerst gecompileerd, dus een script dat niet meer compileert, laat zijn test falen. Eén gefaalde case stopt de pipeline, en er wordt niets gedeployd.

3. Plannen tegen de doelomgeving

Dezelfde bestanden worden gepland tegen de doelomgeving: welke artefacten daar worden aangemaakt, gewijzigd of verwijderd, en welke tabelwijzigingen als SQL draaien, met het risico van elke operatie en de getypte scripts die door de wijziging niet meer zouden compileren. Het plan draagt een hash. De deployment voert precies het plan uit dat is goedgekeurd: als de doelomgeving intussen veranderd is, wordt de deployment geweigerd en het plan opnieuw gemaakt.

4. Deployen: schema, bestanden, release

  1. Schema. De tabelwijzigingen draaien als een database-deployment, die in de deploymentgeschiedenis van de omgeving staat zoals elke andere. Een wijziging die data verliest, draait alleen wanneer de pipeline dataverlies uitdrukkelijk toestaat.
  2. Bestanden. De artefacten worden in één transactie geschreven, dus gebruikers zien de nieuwe versie van een package in zijn geheel of helemaal niet. Een deployment komt alleen aan wat de package bevat en aanmaakt, en nooit aan wat elke omgeving zelf beslist.
  3. Release. Zodra de bestanden binnen zijn, publiceert de pipeline zelf een release. Dat is het moment waarop de nieuwe pagina's en app-layouts de gepubliceerde app bereiken, en niemand publiceert met de hand. Elke deployment is een nieuwe versie van de app, met een eigen release.

Een omgeving die nog nooit een release heeft gepubliceerd, toont haar drafts, dus de nieuwe bestanden zouden zichtbaar zijn zodra ze aankomen. Vóór de eerste deployment naar zo'n omgeving publiceert de pipeline daarom een release van wat de omgeving al bevat, en vanaf dan wachten de nieuwe bestanden als draft tot hun eigen release, zoals bij elke latere deployment.

Waarom de omgeving blijft draaien

  • Er herstart niets. Een deployment is data in de databases van de omgeving, geen nieuwe build van de server. De API blijft de hele tijd antwoorden, en een gewijzigd script wordt gecompileerd de eerste keer dat het draait.
  • Bestanden komen in één keer aan. Eén transactie per package, dus niemand werkt tegen een halve package.
  • Pagina's wisselen in één stap. De gepubliceerde app leest de huidige release. Nieuwe pagina's wachten als draft tot de release gepubliceerd wordt, en dat brengt elke gebruiker op hetzelfde moment naar de nieuwe pagina's. De vorige release activeren is een rollback; die herstelt de pagina's en layouts, nooit data of tabellen.
  • Tabelwijzigingen worden gepland en gereviewd. Een tabel of een nullable kolom toevoegen zit niemand in de weg, en alles wat data verliest, heeft een uitdrukkelijk ja nodig.

Eerst uitbreiden, dan inkrimpen

Script modules, business events en business entities zijn live zodra hun bestanden aankomen, niet pas bij de release. Een wijziging die een kolom hernoemt of verwijdert, gaat daarom in twee deployments uit:

  1. Uitbreiden. Voeg de nieuwe tabel of kolom toe, en deploy de scripts en pagina's die hem gebruiken, terwijl de oude er nog staat.
  2. Inkrimpen. Drop de oude kolom in een latere deployment, zodra niets hem nog leest. Het plan markeert de drop als dataverlies, en de controle van de getypte scripts zegt of iets hem nog gebruikt.

Een wijziging die een grote tabel herschrijft, zoals een nieuw type voor een kolom, houdt zolang ze draait een lock op die tabel. Plan zulke wijzigingen voor een rustig moment.

Omgevingen

De repository somt zijn omgevingen op in archestack.json. Een omgeving die gemarkeerd is met "mode": "pipeline", wordt alleen door de pipeline gedeployd, en de VS Code-extensie weigert er met de hand naar te pushen:

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

Wat elke omgeving zelf beslist, staat niet in de bestanden en in geen enkele deployment: gebruikers en rollen, wie een pagina mag zien, wat openbaar is, Data API-rechten en -sleutels, mailaccounts en koppelingen met andere systemen. De beheerders van elke omgeving stellen ze in, dus een deployment kan nooit iets openbaar maken of iemand toegang geven.

Het pipelinebestand

De pipeline staat in de repository en deployt daaruit: elke run checkt één commit uit, en die bestanden zijn wat er gebouwd, getest en gedeployd wordt. Er wordt niets uit een werkruimte geëxporteerd. Hieronder staat dezelfde pipeline voor drie CI-systemen, die elk een wijziging naar test, acceptatie en productie brengen. De archestack-commando's zijn die van de Archestack CLI, dus elk ander CI-systeem dat .NET en Docker op Linux draait, voert dezelfde stappen uit.

  • Build en test draait bij elke pull request en elke merge naar de main-branch. Die stap bouwt uit de commit een wegwerp-Archestack, draait de tests van elke package en verpakt de repository in één artefact, zodat elke omgeving precies dezelfde bestanden krijgt.
  • Een plan- en een deploystap per omgeving. Het plan wordt tegen de omgeving gemaakt en in de run getoond; de deploystap voert daarna precies dat plan uit, na een goedkeuring voor acceptatie en productie. De omgevingen komen na elkaar aan de beurt, dus acceptatie wordt pas gepland als test gedeployd is, en productie pas als acceptatie gedeployd is. Een pull request stopt na het plan tegen test.
  • Deploytokens. Het token van elke omgeving wordt aangemaakt in de builder van die omgeving, onder Operations, Deploy Tokens. Het wordt één keer getoond, handelt als beheerder en dient alleen om te deployen: de gegevens van de omgeving leest het nooit. Het adres van de omgeving komt uit archestack.json.
Je CI-systeem

Azure DevOps

De pipeline is azure-pipelines.yml in de root van de 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)
  • Goedkeuringen. Maak onder Pipelines, Environments de omgevingen archestack-tst, archestack-acc en archestack-prd aan, en voeg aan acceptatie en productie een Approvals-check toe. Azure DevOps wacht dan op een goedkeurder voordat die deploystappen starten, met het plan in de samenvatting van de run. De testresultaten worden in de run gepubliceerd.
  • Toegangsgegevens. Het deploytoken van elke omgeving is het secret ARCHESTACK_TOKEN in een variabelengroep met dezelfde naam als de omgeving, zoals archestack-prd.
  • Dataverlies. Allow changes that lose data is een selectievakje wanneer een run met de hand wordt gestart, standaard uit. Zonder die optie stopt de pipeline bij een plan dat een tabel of een kolom dropt.
  • Pull requests op Azure Repos. Azure Repos negeert de sectie pr:; voeg de pipeline in plaats daarvan toe als build validation branch policy op de main-branch.
  • Een pipeline die in de webeditor is gemaakt, wordt bewaard als een nieuw bestand met de naam van de pipeline. Laat de pipeline in zijn instellingen naar azure-pipelines.yml wijzen, anders is het bestand dat je bewerkt niet het bestand dat draait.

GitHub Actions

De workflow is .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 }}

Elke omgeving wordt gepland en gedeployd door dezelfde herbruikbare workflow ernaast:

# .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 }}
  • Goedkeuringen. Maak onder Settings, Environments de omgevingen archestack-tst, archestack-acc en archestack-prd aan, en voeg aan acceptatie en productie required reviewers toe. De deployjob wacht op een reviewer, met het plan al in de samenvatting van de run. In een private repository vragen environments GitHub Pro, Team of Enterprise.
  • Toegangsgegevens. De deploytokens zijn de repository secrets ARCHESTACK_TOKEN_TST, ARCHESTACK_TOKEN_ACC en ARCHESTACK_TOKEN_PRD, zodat het plan vóór de goedkeuring kan draaien. Een workflow op eender welke branch van de repository kan een repository secret lezen; om het token van productie voor goedgekeurde runs te houden, maak je het in plaats daarvan een environment secret van archestack-prd, en dan draait zijn plan na de goedkeuring.
  • Dataverlies. Allow changes that lose data is een selectievakje onder Run workflow, standaard uit.
  • Pull requests vanuit forks krijgen geen secrets, dus hun plan tegen test faalt; pull requests vanuit branches van de repository zelf plannen zoals gewoonlijk.
  • concurrency voorkomt dat twee runs tegelijk naar één omgeving deployen. De testresultaten worden bewaard als het artefact tests van de run.

GitLab CI

De pipeline is .gitlab-ci.yml in de root van de 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. De build draait de wegwerp-Archestack op een docker:dind-service naast de job, en daarvoor is een runner nodig die geprivilegieerde containers toelaat, zoals de eigen runners van GitLab.com. DOCKER_HOST zegt de CLI waar Docker is, en daar bereikt hij de Archestack.
  • Goedkeuringen. Acceptatie en productie deployen zijn manuele jobs die de pipeline blokkeren, en elk wordt gestart zodra zijn plan gelezen is. Elk plan wordt bij zijn job bewaard, en het plan tegen test is ook gelinkt vanuit de merge request. Op GitLab Premium bescherm je die omgevingen bovendien en vereis je goedkeuringen.
  • Toegangsgegevens. De deploytokens zijn de gemaskeerde CI/CD-variabelen ARCHESTACK_TOKEN_TST, ARCHESTACK_TOKEN_ACC en ARCHESTACK_TOKEN_PRD. Bescherm die van acceptatie en productie, zodat alleen de main-branch ze leest. Een beschermde variabele bereikt geen merge request-pipeline, dus laat die van test onbeschermd, zodat merge requests tegen test kunnen plannen.
  • Dataverlies. Start de pipeline met de hand met ALLOW_DATA_LOSS op true. De testresultaten verschijnen in de merge request.
  • resource_group voorkomt dat twee pipelines tegelijk naar één omgeving deployen.

De Archestack CLI

De CLI is de .NET-tool Archestack.Cli, geïnstalleerd met dotnet tool install --global Archestack.Cli op elke agent met .NET 8 of hoger. Zijn commando's draaien vanuit de root van de repository, of nemen --from met een map of een verpakte ZIP:

  • archestack build start de wegwerp-Archestack en laadt de repository erin. Hij draait in Docker vanuit het image dat de sectie project van archestack.json noemt, anders het laatst gepubliceerde; --image kiest een ander, en --runtime draait een runtimemap zonder Docker. Hij is klaar zodra de NuGet-packages die de repository noemt binnengehaald zijn, en blijft draaien voor de volgende stap, tot archestack stop. --nuget-cache <folder> bewaart die downloads voor de volgende build, die ze anders opnieuw downloadt; twee builds die tegelijk draaien, hebben elk een eigen map nodig.
  • archestack test draait de testcases van elke package ertegen, vier tegelijk, en schrijft JUnit met --junit.
  • archestack pack --out app.zip verpakt archestack.json, packages/ en workspace/. Dezelfde bestanden geven altijd dezelfde bytes, en het plan legt hun hash vast, dus een deployment weigert andere bestanden dan de geplande.
  • archestack plan en archestack deploy werken alleen op een omgeving die gemarkeerd is met "mode": "pipeline", met haar deploytoken in ARCHESTACK_TOKEN_<ENV> (zoals ARCHESTACK_TOKEN_PRD) of ARCHESTACK_TOKEN. Een artefact dat uit de repository verwijderd is, wordt uit zijn package gehaald en blijft in de omgeving staan; plan met --delete-removed true om het daar ook te verwijderen. Een package in de omgeving die de repository niet bevat, blijft ongemoeid en wordt in het plan genoemd. Noemt de repository NuGet-packages, dan vragen beide eerst aan de omgeving of ze daar binnengehaald kunnen worden, en deploy wacht na de laatste push tot vijf minuten tot de omgeving ze binnengehaald heeft, voor hij de release publiceert. Mislukt dat wachten, dan zijn de bestanden gedeployd maar wordt er geen release gepubliceerd.

De exitcode zegt wat een stap tegenhield: 3 het token werd geweigerd, 4 de omgeving is veranderd sinds het plan (plan opnieuw), 5 de bestanden kunnen niet doorgevoerd worden zoals ze zijn, 6 het plan verliest data en dat was niet toegestaan, 7 een test faalde, 9 de server of het netwerk faalde, 10 de omgeving draait een andere hoofdversie van Archestack dan de CLI, of een zonder ondersteuning voor NuGet. NuGet-packages die niet binnengehaald kunnen worden met de bestanden geven een 5, en een omgeving waar NuGet-packages of getypte datatoegang uitgezet zijn ook. Bij plan en deploy geeft een NuGet-fout die de bestanden niet kunnen oplossen een 9: bijvoorbeeld een server met te weinig schijfruimte, een feed die hij niet kan bereiken, of het binnenhalen na de laatste push dat mislukte of niet binnen vijf minuten klaar was. Dezelfde stap kan dan lukken als hij opnieuw draait.

Wat vandaag draait

  • Build, test, plan en deploy draaien op de CLI, vanuit scriptstappen zoals in de pipelines hierboven. Op de machine van een ontwikkelaar is het project van de VS Code-extensie dezelfde build: Reset Project Database maakt het vanaf nul, en Run Tests draait de tests van elke package ertegen.
  • Pipelinetaken voor Azure DevOps en GitHub Actions die de CLI omhullen: in ontwikkeling.

Valkuilen

  • Een rollback maakt tabellen en data niet ongedaan. Elke deployment is een release, dus elke versie die de pipeline heeft gedeployd, kan opnieuw geactiveerd worden, maar dat herstelt alleen pagina's en layouts. Tabellen terugzetten is een eigen deployment, gepland en gereviewd zoals elke andere.
  • Script modules en business events wachten niet op de release. Ze zijn live zodra hun bestanden aankomen, en daarom gaat een wijziging die iets verwijdert in twee deployments uit.
  • Elke omgeving downloadt haar eigen NuGet-packages. De NuGet-packages die de nuget.json van een package declareert, worden gedownload door elke omgeving die de package krijgt, de build inbegrepen, dus elke omgeving moet nuget.org kunnen bereiken, of de feed waarmee haar servers geconfigureerd zijn. De build neemt Scripting__NuGet__Sources en de instellingen Scripting__NuGet__Feeds__* over uit de omgeving waarin de CLI draait. Een push waarvan de NuGet-packages niet binnengehaald kunnen worden, wordt geweigerd en verandert niets: het CLI-commando plan controleert dat voordat er iets gedeployd wordt, en build en deploy wachten tot ze binnengehaald zijn.

Waar dit naartoe gaat

Werken als team behandelt hoe ontwikkelaars de repository delen die de pipeline deployt. Werkruimtes en hosting legt de omgevingen uit waarnaar hij deployt, en Database Deployments de schemastap.