Fazer deploy a partir do repositório
O repositório é a fonte de uma aplicação Archestack, tal como o código-fonte é a fonte de um programa. Um deployment trata o Archestack como o compilador: um pipeline constrói um Archestack descartável a partir dos ficheiros do repositório, corre os testes contra ele e só quando passam planeia a alteração contra o ambiente alojado e a aplica lá. O ambiente alojado continua a servir os seus utilizadores durante todo o processo.
Estado: a Archestack CLI corre todas as etapas abaixo, a partir de um passo de script em qualquer pipeline. As tarefas de pipeline prontas a usar para o Azure DevOps e o GitHub Actions que a envolvem estão em desenvolvimento; O que corre hoje diz o que cada etapa corre.
O 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 Um pull request corre a build, os testes e o plano contra teste, para que um revisor veja o que mudaria antes de ser feito o merge de alguma coisa. Um merge para a branch principal corre todas as etapas, e a aceitação e a produção esperam, cada uma, que uma pessoa aprove o seu plano.
1. Build: o Archestack como compilador
O pipeline arranca um Archestack vazio no agente de build, em Docker a partir da mesma imagem da API que os ambientes correm, ou a partir de uma pasta de runtime como aquela com que a extensão do VS Code corre os projetos, e carrega nele o repositório: as tabelas de todos os packages num só deployment, depois os artefactos de cada package, com as dependências antes dos packages que precisam delas. É aqui que um erro aparece primeiro, tal como um erro de compilação: uma referência a uma Business Entity, tabela ou script que não existe, ou um nome que outro package já usa, para o carregamento. O resultado é um ambiente feito apenas a partir dos ficheiros, sem nada que tenha sobrado da máquina de ninguém.
2. Testar
Os casos de teste de todos os packages correm contra a build, cada um numa base de dados sandbox própria, com o email e as notificações registados em vez de enviados. Cada script que um teste corre é compilado primeiro, por isso um script que já não compila faz falhar o seu teste. Um só caso que falhe para o pipeline, e não é feito deploy de nada.
3. Planear contra o destino
Os mesmos ficheiros são planeados contra o ambiente de destino: que artefactos são criados, alterados ou removidos lá, e que alterações de tabelas correm como SQL, com o risco de cada operação e os scripts tipados que, com a alteração, deixariam de compilar. O plano leva um hash. O deployment aplica exatamente o plano que foi aprovado: se entretanto o destino mudou, é recusado e o plano é feito de novo.
4. Deploy: schema, ficheiros, release
- Schema. As alterações de tabelas correm como um deployment de base de dados, listado no histórico de deployments do ambiente como qualquer outro. Uma alteração que perde dados só corre quando o pipeline permite explicitamente a perda de dados.
- Ficheiros. Os artefactos são escritos numa só transação, por isso os utilizadores veem toda a nova versão de um package ou nada dela. Um deployment toca apenas no que o package contém e cria, e nunca no que cada ambiente decide por si.
- Release. Assim que os ficheiros entram, o pipeline publica uma release por si só. É esse o momento em que as novas páginas e os app layouts chegam à aplicação publicada, e ninguém publica à mão. Cada deployment é uma nova versão da aplicação, com uma release própria.
Um ambiente que nunca publicou uma release mostra os seus rascunhos, por isso os novos ficheiros ficariam visíveis no momento em que entram. Antes do seu primeiro deployment para um ambiente assim, o pipeline publica, por isso, uma release do que o ambiente já contém, e a partir daí os novos ficheiros esperam como rascunhos até à sua própria release, como em todos os deployments seguintes.
Porque é que o ambiente continua disponível
- Nada reinicia. Um deployment são dados nas bases de dados do ambiente, não uma nova build do servidor. A API continua a responder durante todo o processo, e um script alterado é compilado da primeira vez que corre.
- Os ficheiros entram de uma só vez. Uma transação por package, por isso ninguém trabalha sobre meio package.
- As páginas mudam num só passo. A aplicação publicada lê a release atual. As novas páginas esperam como rascunhos até a release ser publicada, o que passa todos os utilizadores para elas no mesmo momento. Ativar a release anterior faz o rollback; isso repõe as páginas e os layouts, nunca os dados nem as tabelas.
- As alterações de tabelas são planeadas e revistas. Acrescentar uma tabela ou uma coluna que aceita nulos não atrapalha ninguém, e tudo o que perde dados precisa de um sim explícito.
Expandir e depois contrair
Os Script Modules, os Business Events e as Business Entities ficam ativos no momento em que os seus ficheiros entram, não na release. Uma alteração que renomeia ou remove uma coluna sai, por isso, em dois deployments:
- Expandir. Acrescente a nova tabela ou coluna e faça deploy dos scripts e das páginas que a usam, com a antiga ainda no lugar.
- Contrair. Num deployment posterior, quando já nada ler a coluna antiga, remova-a. O plano marca a remoção como perda de dados, e a verificação dos scripts tipados diz se alguma coisa ainda a usa.
Uma alteração que reescreve uma tabela grande, como um novo tipo para uma coluna, mantém um bloqueio sobre essa tabela enquanto corre. Agende essas alterações para um momento calmo.
Ambientes
O repositório lista os seus ambientes em archestack.json. Um ambiente marcado com
"mode": "pipeline" só recebe deployments do pipeline, e a extensão do VS Code recusa
fazer push para ele à mão:
"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" }
} O que cada ambiente decide por si não está nos ficheiros nem em nenhum deployment: os utilizadores e as roles, as permissões das páginas, o que está marcado como público, os acessos concedidos e as chaves da Data API, as contas de email e as ligações a outros sistemas. São os administradores de cada ambiente que os definem, por isso um deployment nunca pode tornar algo público nem dar acesso a ninguém.
O ficheiro do pipeline
O pipeline vive no repositório e faz deploy a partir dele: cada execução faz checkout de um só
commit, e são esses ficheiros que passam pela build, pelos testes e pelo deploy. Nada é exportado
de um espaço de trabalho. Abaixo está o mesmo pipeline para três sistemas de CI, cada um a levar
uma alteração a teste, aceitação e produção. Os comandos archestack são os da
Archestack CLI, por isso qualquer outro sistema de CI que corra .NET e Docker em
Linux corre os mesmos passos.
- A etapa Build and test corre em cada pull request e em cada merge para a main. Constrói um Archestack descartável a partir do commit, corre os testes de todos os packages e empacota o repositório num só artefacto, para que todos os ambientes recebam exatamente os mesmos ficheiros.
- Um passo de plano e um de deploy por ambiente. O plano é feito contra o ambiente e mostrado na execução; o deploy aplica depois exatamente esse plano, após uma aprovação para a aceitação e a produção. Os ambientes seguem-se um após o outro, por isso a aceitação só é planeada depois de feito o deploy para teste, e a produção só depois de feito o deploy para aceitação. Um pull request para depois do plano contra teste.
- Tokens de deploy. O token de cada ambiente é criado no builder desse ambiente,
em Operations, Deploy Tokens. É mostrado uma única vez, atua como
administrador e serve apenas para fazer deploy: nunca lê os dados do ambiente. O endereço do
ambiente vem de
archestack.json.
Azure DevOps
O pipeline é azure-pipelines.yml na raiz do repositório:
# 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) - Aprovações. Crie os ambientes
archestack-tst,archestack-accearchestack-prdem Pipelines, Environments, e acrescente uma verificação Approvals à aceitação e à produção. O Azure DevOps espera então por um aprovador antes de essas etapas de deploy começarem, com o plano no resumo da execução. Os resultados dos testes são publicados na execução. - Credenciais. O token de deploy de cada ambiente é o segredo
ARCHESTACK_TOKENnum grupo de variáveis com o mesmo nome do ambiente, comoarchestack-prd. - Perda de dados. Allow changes that lose data é uma caixa de verificação quando uma execução é iniciada à mão, desmarcada por predefinição. Se não estiver marcada, um plano que remove uma tabela ou uma coluna para o pipeline.
- Pull requests no Azure Repos. O Azure Repos ignora a secção
pr:; em vez disso, acrescente o pipeline como build validation branch policy na main. - Um pipeline criado no editor web é guardado como um novo ficheiro com o nome
do pipeline. Aponte o pipeline para
azure-pipelines.ymlnas suas definições, ou o ficheiro que edita não é o que corre.
GitHub Actions
O 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 }} Cada ambiente é planeado e recebe o deploy pelo mesmo workflow reutilizável ao 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 }} - Aprovações. Crie os ambientes
archestack-tst,archestack-accearchestack-prdem Settings, Environments, e acrescente required reviewers à aceitação e à produção. O job de deploy espera por um revisor, com o plano já no resumo da execução. Num repositório privado, os ambientes precisam do GitHub Pro, Team ou Enterprise. - Credenciais. Os tokens de deploy são os segredos do repositório
ARCHESTACK_TOKEN_TST,ARCHESTACK_TOKEN_ACCeARCHESTACK_TOKEN_PRD, para que o plano possa correr antes da aprovação. Um workflow em qualquer branch do repositório pode ler um segredo do repositório; para reservar o token da produção às execuções aprovadas, torne-o antes um segredo do ambientearchestack-prd, e o seu plano passa então a correr depois da aprovação. - Perda de dados. Allow changes that lose data é uma caixa de verificação em Run workflow, desmarcada por predefinição.
- Pull requests a partir de forks não recebem segredos, por isso o seu plano contra teste falha; os pull requests a partir de branches do próprio repositório são planeados como de costume.
-
concurrencyimpede que duas execuções façam deploy para o mesmo ambiente ao mesmo tempo. Os resultados dos testes ficam guardados como o artefactotestsda execução.
GitLab CI
O pipeline é .gitlab-ci.yml na raiz do repositório:
# .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. A build corre o Archestack descartável num serviço
docker:dindao lado do job, o que precisa de um runner que permita containers privilegiados, como os próprios runners do GitLab.com.DOCKER_HOSTdiz à CLI onde está o Docker, e é aí que ela chega ao Archestack. - Aprovações. O deploy para aceitação e o deploy para produção são jobs manuais que bloqueiam o pipeline, cada um iniciado depois de o seu plano ter sido lido. Cada plano fica guardado com o seu job, e o plano contra teste tem também uma ligação no merge request. No GitLab Premium, proteja também esses ambientes e exija aprovações.
- Credenciais. Os tokens de deploy são as variáveis CI/CD mascaradas
ARCHESTACK_TOKEN_TST,ARCHESTACK_TOKEN_ACCeARCHESTACK_TOKEN_PRD. Proteja as da aceitação e da produção, para que só a branch principal as leia. Uma variável protegida não chega a um pipeline de merge request, por isso deixe a de teste desprotegida para que os merge requests possam planear contra teste. - Perda de dados. Corra o pipeline à mão com
ALLOW_DATA_LOSSdefinido comotrue. Os resultados dos testes aparecem no merge request. -
resource_groupimpede que dois pipelines façam deploy para o mesmo ambiente ao mesmo tempo.
A Archestack CLI
A CLI é a ferramenta .NET Archestack.Cli, instalada com
dotnet tool install --global Archestack.Cli em qualquer agente com .NET 8 ou
posterior. Os seus comandos correm a partir da raiz do repositório, ou recebem --from
com uma pasta ou um ZIP empacotado:
-
archestack buildarranca o Archestack descartável e carrega nele o repositório. Corre em Docker a partir da imagem que a secçãoprojectdearchestack.jsonindica, ou então da mais recente publicada;--imageescolhe outra, e--runtimecorre uma pasta de runtime sem Docker. Fica pronto quando os pacotes NuGet que o repositório indica estão restaurados, e continua a correr para o passo seguinte atéarchestack stop.--nuget-cache <folder>guarda esses downloads para a build seguinte, que de outro modo os descarrega de novo; duas builds a correr ao mesmo tempo precisam cada uma da sua própria pasta. -
archestack testcorre contra ele os casos de teste de todos os packages, quatro de cada vez, e escreve JUnit com--junit. -
archestack pack --out app.zipempacotaarchestack.json,packages/eworkspace/. Os mesmos ficheiros dão sempre os mesmos bytes, e o plano regista o seu hash, por isso um deployment recusa ficheiros que não sejam os planeados. -
archestack planearchestack deploysó funcionam num ambiente marcado com"mode": "pipeline", com o seu token de deploy emARCHESTACK_TOKEN_<ENV>(comoARCHESTACK_TOKEN_PRD) ouARCHESTACK_TOKEN. Um artefacto apagado do repositório é retirado do seu package e deixado no ambiente; planeie com--delete-removed truepara o apagar lá também. Um package no ambiente que o repositório não contém é deixado como está e indicado no plano. Quando o repositório indica pacotes NuGet, ambos perguntam primeiro ao ambiente se lá se restauram, edeployespera até cinco minutos depois do último push que o ambiente os tenha restaurado, antes de publicar a release. Se essa espera falhar, o deploy dos ficheiros fica feito, mas nenhuma release é publicada.
O código de saída diz o que parou um passo: 3 o token foi recusado, 4 o ambiente mudou desde o
plano (planeie de novo), 5 os ficheiros não podem ser aplicados tal como estão, 6 o plano perde
dados e isso não foi permitido, 7 um teste falhou, 9 o servidor ou a rede falharam, 10 o ambiente
corre uma versão major do Archestack diferente da da CLI, ou uma sem suporte para NuGet. Pacotes
NuGet que não se restauram com os ficheiros dão 5, tal como um ambiente com os pacotes NuGet ou o
acesso a dados tipado desligados. Em plan e deploy, uma falha do NuGet
que os ficheiros não podem corrigir dá 9: por exemplo um servidor com pouco espaço em disco, um
feed a que não chega, ou uma restauração depois do último push que falhou ou não terminou em
cinco minutos. O mesmo passo pode então correr bem quando for executado de novo.
O que corre hoje
- Build, testes, plano e deploy correm na CLI, a partir de passos de script como nos pipelines acima. Na máquina de um programador, o projeto da extensão do VS Code é a mesma build: Reset Project Database cria-o do zero, e Run Tests corre contra ele os testes de todos os packages.
- Tarefas de pipeline para o Azure DevOps e o GitHub Actions que envolvem a CLI: em desenvolvimento.
Armadilhas
- Um rollback não desfaz tabelas nem dados. Cada deployment é uma release, por isso qualquer versão de que o pipeline fez deploy pode ser ativada de novo, mas isso repõe apenas as páginas e os layouts. Levar as tabelas de volta é um deployment próprio, planeado e revisto como qualquer outro.
- Os Script Modules e os Business Events não esperam pela release. Ficam ativos no momento em que os seus ficheiros entram, e é por isso que uma alteração que remove alguma coisa sai em dois deployments.
- Cada ambiente descarrega os seus próprios pacotes NuGet. Os
pacotes NuGet que o
nuget.jsonde um package declara são descarregados por cada ambiente que o recebe, incluindo a build, por isso cada um precisa de chegar ao nuget.org ou ao feed com que os seus servidores estão configurados. A build lêScripting__NuGet__Sourcese as definiçõesScripting__NuGet__Feeds__*do ambiente em que a CLI corre. Um push cujos pacotes NuGet não podem ser restaurados é recusado e não muda nada: oplanda CLI verifica isso antes de qualquer deploy, ebuildedeployesperam até estarem restaurados.
Para onde seguir a partir daqui
Trabalhar em equipa trata da forma como os programadores partilham o repositório de que o pipeline faz deploy. Espaços de trabalho e alojamento explica os ambientes para onde ele faz deploy, e Database Deployments a etapa do schema.