Wdrażanie z repozytorium
Repozytorium jest źródłem aplikacji Archestack, tak jak kod źródłowy jest źródłem programu. Wdrożenie traktuje Archestack jak kompilator: pipeline buduje z plików repozytorium tymczasowy Archestack, uruchamia na nim testy i dopiero gdy przejdą, planuje zmianę względem hostowanego środowiska i wprowadza ją tam. Hostowane środowisko przez cały ten czas obsługuje swoich użytkowników.
Stan: Archestack CLI uruchamia każdy z poniższych etapów jako krok skryptu dowolnego pipeline'u. Gotowe zadania pipeline'u dla Azure DevOps i GitHub Actions, które go opakowują, są w trakcie tworzenia; sekcja Co działa dziś mówi, co uruchamia każdy etap.
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 Pull request uruchamia build, testy i plan względem środowiska testowego, więc recenzent widzi, co by się zmieniło, zanim cokolwiek zostanie scalone. Merge do gałęzi głównej uruchamia wszystkie etapy, a środowisko akceptacyjne i produkcyjne czekają, aż ktoś zatwierdzi plan każdego z nich.
1. Build: Archestack jako kompilator
Pipeline uruchamia na agencie builda pusty Archestack, w Dockerze z tego samego obrazu API, na którym działają środowiska, albo z folderu runtime'u takiego jak ten, którym rozszerzenie VS Code uruchamia projekty, i wczytuje do niego repozytorium: tabele wszystkich packages w jednym wdrożeniu, potem artefakty każdego package'a, zależności przed packages, które ich potrzebują. To tutaj błąd wychodzi na jaw najwcześniej, tak jak błąd kompilacji: odwołanie do Business Entity, tabeli albo skryptu, których nie ma, albo nazwa, której używa już inny package, zatrzymuje wczytywanie. Wynikiem jest środowisko zbudowane wyłącznie z plików, bez żadnych pozostałości z czyjejkolwiek maszyny.
2. Testy
Przypadki testowe wszystkich packages działają na tym buildzie, każdy we własnej bazie sandbox, a maile i powiadomienia są rejestrowane, a nie wysyłane. Każdy skrypt, który uruchamia test, jest najpierw kompilowany, więc test ze skryptem, który przestał się kompilować, kończy się niepowodzeniem. Jeden nieudany przypadek zatrzymuje pipeline i nic nie zostaje wdrożone.
3. Plan względem środowiska docelowego
Te same pliki są planowane względem środowiska docelowego: które artefakty zostaną tam utworzone, zmienione lub usunięte i które zmiany tabel zostaną wykonane jako SQL, z ryzykiem każdej operacji i typowanymi skryptami, które po tej zmianie przestałyby się kompilować. Plan ma swój hash. Wdrożenie wprowadza dokładnie ten plan, który został zatwierdzony: jeśli środowisko docelowe w międzyczasie się zmieniło, wdrożenie jest odrzucane, a plan powstaje od nowa.
4. Wdrożenie: schemat, pliki, wydanie
- Schemat. Zmiany tabel są wykonywane jako wdrożenie bazy danych, widoczne w historii wdrożeń środowiska jak każde inne. Zmiana, która traci dane, jest wykonywana tylko wtedy, gdy pipeline wprost pozwala na utratę danych.
- Pliki. Artefakty są zapisywane w jednej transakcji, więc użytkownicy widzą całą nową wersję package'a albo nic z niej. Wdrożenie dotyka tylko tego, co package zawiera i tworzy, i nigdy tego, o czym każde środowisko decyduje samo.
- Wydanie. Gdy pliki są już na miejscu, pipeline sam publikuje wydanie. To moment, w którym nowe strony i układy aplikacji docierają do opublikowanej aplikacji, i nikt nie publikuje ręcznie. Każde wdrożenie to nowa wersja aplikacji z własnym wydaniem.
Środowisko, które nigdy nie opublikowało wydania, pokazuje swoje wersje robocze, więc nowe pliki byłyby widoczne w chwili, gdy trafią na miejsce. Przed pierwszym wdrożeniem na takie środowisko pipeline publikuje więc wydanie tego, co środowisko już zawiera, a od tej pory nowe pliki czekają jako wersje robocze na własne wydanie, tak jak przy każdym kolejnym wdrożeniu.
Dlaczego środowisko działa bez przerwy
- Nic się nie restartuje. Wdrożenie to dane w bazach danych środowiska, a nie nowy build serwera. API przez cały czas odpowiada, a zmieniony skrypt jest kompilowany przy pierwszym uruchomieniu.
- Pliki trafiają na miejsce naraz. Jedna transakcja na package, więc nikt nie pracuje na połowie package'a.
- Strony przełączają się w jednym kroku. Opublikowana aplikacja czyta bieżące wydanie. Nowe strony czekają jako wersje robocze, dopóki wydanie nie zostanie opublikowane, co przenosi na nie wszystkich użytkowników w tym samym momencie. Aktywacja poprzedniego wydania wycofuje zmiany; przywraca strony i układy, nigdy dane ani tabele.
- Zmiany tabel są planowane i przeglądane. Dodanie tabeli albo kolumny dopuszczającej wartości null nikomu nie przeszkadza, a wszystko, co traci dane, wymaga wyraźnej zgody.
Najpierw rozszerz, potem zawęź
Script Modules, Business Events i Business Entities działają od chwili, w której ich pliki trafią na miejsce, a nie od wydania. Zmiana, która zmienia nazwę kolumny albo ją usuwa, trafia więc na środowisko w dwóch wdrożeniach:
- Rozszerz. Dodaj nową tabelę albo kolumnę i wdróż skrypty i strony, które z niej korzystają, podczas gdy stara wciąż jest na miejscu.
- Zawęź. W późniejszym wdrożeniu, gdy nic już nie czyta starej kolumny, usuń ją. Plan oznacza usunięcie jako utratę danych, a sprawdzenie typowanych skryptów mówi, czy coś nadal jej używa.
Zmiana, która przepisuje dużą tabelę, na przykład nowy typ kolumny, blokuje tę tabelę, dopóki trwa. Zaplanuj takie zmiany na spokojny moment.
Środowiska
Repozytorium wymienia swoje środowiska w archestack.json. Środowisko oznaczone
"mode": "pipeline" jest wdrażane wyłącznie przez pipeline, a rozszerzenie VS Code nie
pozwala ręcznie wysyłać do niego zmian:
"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" }
} To, o czym każde środowisko decyduje samo, nie znajduje się w plikach ani w żadnym wdrożeniu: użytkownicy i role, uprawnienia stron, oznaczenia jako publiczne, uprawnienia i klucze Data API, konta pocztowe i połączenia z innymi systemami. Ustawiają je administratorzy każdego środowiska, więc wdrożenie nigdy nie może uczynić niczego publicznym ani nikomu dać dostępu.
Plik pipeline'u
Pipeline znajduje się w repozytorium i z niego wdraża: każde uruchomienie wykonuje checkout
jednego commita, i to właśnie te pliki są budowane, testowane i wdrażane. Nic nie jest
eksportowane z przestrzeni roboczej. Poniżej jest ten sam pipeline dla trzech systemów CI, a każdy
z nich przeprowadza zmianę przez środowisko testowe, akceptacyjne i produkcyjne. Polecenia
archestack pochodzą z Archestack CLI, więc każdy inny system CI,
który uruchamia .NET i Dockera na Linuksie, wykonuje te same kroki.
- Etap Build and test uruchamia się dla każdego pull requesta i każdego merge'a do gałęzi main. Buduje z commita tymczasowy Archestack, uruchamia testy wszystkich packages i pakuje repozytorium w jeden artefakt, więc każde środowisko dostaje dokładnie te same pliki.
- Krok planu i krok wdrożenia dla każdego środowiska. Plan powstaje względem środowiska i jest pokazywany w uruchomieniu; wdrożenie wprowadza potem dokładnie ten plan, po zatwierdzeniu w przypadku środowiska akceptacyjnego i produkcyjnego. Środowiska idą jedno po drugim, więc akceptacyjne jest planowane dopiero po wdrożeniu testowego, a produkcyjne dopiero po wdrożeniu akceptacyjnego. Pull request zatrzymuje się po planie względem środowiska testowego.
- Tokeny wdrożeniowe. Token każdego środowiska tworzy się w builderze tego
środowiska, w Operations, Deploy Tokens. Jest pokazywany tylko raz, działa
jako administrator i służy wyłącznie do wdrażania: nigdy nie odczytuje danych środowiska. Adres
środowiska pochodzi z
archestack.json.
Azure DevOps
Pipeline to azure-pipelines.yml w katalogu głównym repozytorium:
# 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) - Zatwierdzenia. Utwórz środowiska
archestack-tst,archestack-acciarchestack-prdw Pipelines, Environments i dodaj do akceptacyjnego i produkcyjnego sprawdzenie Approvals. Azure DevOps czeka wtedy na osobę zatwierdzającą, zanim ruszą te etapy wdrożenia, a plan widać w podsumowaniu uruchomienia. Wyniki testów są publikowane w uruchomieniu. - Poświadczenia. Token wdrożeniowy każdego środowiska to sekret
ARCHESTACK_TOKENw grupie zmiennych o tej samej nazwie co środowisko, na przykładarchestack-prd. - Utrata danych. Allow changes that lose data to pole wyboru przy ręcznym uruchomieniu, domyślnie odznaczone. Bez jego zaznaczenia plan, który usuwa tabelę albo kolumnę, zatrzymuje pipeline.
- Pull requesty w Azure Repos. Azure Repos ignoruje sekcję
pr:; zamiast tego dodaj pipeline jako build validation branch policy na gałęzi main. - Pipeline utworzony w edytorze webowym jest zapisywany jako nowy plik nazwany
tak jak pipeline. Wskaż w ustawieniach pipeline'u plik
azure-pipelines.yml, bo inaczej plik, który edytujesz, nie jest tym, który się uruchamia.
GitHub Actions
Workflow to .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 }} Każde środowisko jest planowane i wdrażane przez ten sam reusable workflow obok niego:
# .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 }} - Zatwierdzenia. Utwórz środowiska
archestack-tst,archestack-acciarchestack-prdw Settings, Environments i dodaj do akceptacyjnego i produkcyjnego required reviewers. Job wdrożenia czeka na recenzenta, a plan jest już w podsumowaniu uruchomienia. W prywatnym repozytorium środowiska wymagają GitHub Pro, Team albo Enterprise. - Poświadczenia. Tokeny wdrożeniowe to sekrety repozytorium
ARCHESTACK_TOKEN_TST,ARCHESTACK_TOKEN_ACCiARCHESTACK_TOKEN_PRD, więc plan może się wykonać przed zatwierdzeniem. Workflow na dowolnej gałęzi repozytorium może odczytać sekret repozytorium; żeby token produkcyjny był dostępny tylko dla zatwierdzonych uruchomień, zrób z niego zamiast tego sekret środowiskaarchestack-prd, a jego plan wykona się wtedy po zatwierdzeniu. - Utrata danych. Allow changes that lose data to pole wyboru pod Run workflow, domyślnie odznaczone.
- Pull requesty z forków nie dostają sekretów, więc ich plan względem środowiska testowego się nie powiedzie; pull requesty z gałęzi samego repozytorium są planowane jak zwykle.
-
concurrencynie pozwala dwóm uruchomieniom wdrażać na to samo środowisko w tym samym czasie. Wyniki testów są zachowywane jako artefakttestsuruchomienia.
GitLab CI
Pipeline to .gitlab-ci.yml w katalogu głównym repozytorium:
# .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. Build uruchamia tymczasowy Archestack w usłudze
docker:dindobok joba, co wymaga runnera pozwalającego na kontenery uprzywilejowane, tak jak własne runnery GitLab.com.DOCKER_HOSTmówi CLI, gdzie jest Docker, i tam CLI łączy się z Archestack. - Zatwierdzenia. Wdrożenie na środowisko akceptacyjne i produkcyjne to ręczne joby, które blokują pipeline, a każdy z nich uruchamia się po przeczytaniu jego planu. Każdy plan jest zachowywany przy swoim jobie, a plan względem środowiska testowego jest też podlinkowany w merge requeście. W GitLab Premium dodatkowo zabezpiecz te środowiska i wymagaj zatwierdzeń.
- Poświadczenia. Tokeny wdrożeniowe to maskowane zmienne CI/CD
ARCHESTACK_TOKEN_TST,ARCHESTACK_TOKEN_ACCiARCHESTACK_TOKEN_PRD. Oznacz zmienne akceptacyjnego i produkcyjnego jako chronione, żeby odczytywała je tylko gałąź main. Chroniona zmienna nie trafia do pipeline'u merge requesta, więc zostaw zmienną testowego niechronioną, żeby merge requesty mogły planować względem środowiska testowego. - Utrata danych. Uruchom pipeline ręcznie z
ALLOW_DATA_LOSSustawionym natrue. Wyniki testów widać w merge requeście. -
resource_groupnie pozwala dwóm pipeline'om wdrażać na to samo środowisko w tym samym czasie.
Archestack CLI
CLI to narzędzie .NET Archestack.Cli, instalowane poleceniem
dotnet tool install --global Archestack.Cli na dowolnym agencie z .NET 8 lub nowszym.
Jego polecenia uruchamia się z katalogu głównego repozytorium albo z opcją --from
wskazującą folder lub spakowany plik ZIP:
-
archestack builduruchamia tymczasowy Archestack i wczytuje do niego repozytorium. Działa w Dockerze z obrazu, który wskazuje sekcjaprojectwarchestack.json, a w przeciwnym razie z najnowszego opublikowanego;--imagewybiera inny, a--runtimeuruchamia folder runtime'u bez Dockera. Jest gotowy, gdy pakiety NuGet wskazane w repozytorium zostaną przywrócone, i działa dalej na potrzeby kolejnego kroku, aż doarchestack stop.--nuget-cache <folder>zachowuje te pobrane pliki dla następnego buildu, który inaczej pobiera je od nowa; dwa buildy działające jednocześnie potrzebują każdy własnego folderu. -
archestack testuruchamia na nim przypadki testowe wszystkich packages, po cztery naraz, i zapisuje wyniki JUnit z opcją--junit. -
archestack pack --out app.zippakujearchestack.json,packages/iworkspace/. Te same pliki zawsze dają te same bajty, a plan zapisuje ich hash, więc wdrożenie odrzuca pliki inne niż te, które zostały zaplanowane. -
archestack planiarchestack deploydziałają tylko na środowisku oznaczonym"mode": "pipeline", z jego tokenem wdrożeniowym wARCHESTACK_TOKEN_<ENV>(na przykładARCHESTACK_TOKEN_PRD) alboARCHESTACK_TOKEN. Artefakt usunięty z repozytorium zostaje wyjęty ze swojego package'a i pozostaje w środowisku; zaplanuj z--delete-removed true, żeby usunąć go także tam. Package w środowisku, którego repozytorium nie zawiera, zostaje nietknięty i jest wymieniony w planie. Gdy repozytorium wskazuje pakiety NuGet, oba polecenia najpierw pytają środowisko, czy da się je tam przywrócić, adeploypo ostatnim wysłaniu zmian czeka do pięciu minut, aż środowisko je przywróci, zanim opublikuje wydanie. Jeśli to czekanie się nie powiedzie, pliki są wdrożone, ale żadne wydanie nie zostaje opublikowane.
Kod wyjścia mówi, co zatrzymało krok: 3 token został odrzucony, 4 środowisko zmieniło się od
czasu planu (zaplanuj ponownie), 5 plików nie da się wprowadzić w obecnej postaci, 6 plan traci
dane, a nie było na to zgody, 7 test się nie powiódł, 9 zawiódł serwer albo sieć, 10 środowisko
działa na innej wersji głównej Archestack niż CLI albo na wersji bez obsługi NuGet. Pakiety NuGet,
których nie da się przywrócić razem z plikami, dają 5, tak samo jak środowisko, w którym pakiety
NuGet albo typowany dostęp do danych są wyłączone. W plan i deploy błąd
NuGet, którego pliki nie mogą naprawić, daje 9: na przykład serwer z za małą ilością miejsca na
dysku, feed, do którego nie ma dostępu, albo przywracanie po ostatnim wysłaniu zmian, które się
nie powiodło lub nie skończyło w ciągu pięciu minut. Ten sam krok może się wtedy udać przy
następnym uruchomieniu.
Co działa dziś
- Build, testy, plan i wdrożenie działają na CLI, jako kroki skryptu, jak w pipeline'ach powyżej. Na maszynie programisty projekt rozszerzenia VS Code to ten sam build: Reset Project Database buduje go od zera, a Run Tests uruchamia na nim testy wszystkich packages.
- Zadania pipeline'u dla Azure DevOps i GitHub Actions, które opakowują CLI: w trakcie tworzenia.
Pułapki
- Wycofanie nie cofa tabel ani danych. Każde wdrożenie jest wydaniem, więc każdą wersję wdrożoną przez pipeline można aktywować ponownie, ale przywraca to tylko strony i układy. Przywrócenie tabel to osobne wdrożenie, planowane i przeglądane jak każde inne.
- Script Modules i Business Events nie czekają na wydanie. Działają od chwili, w której ich pliki trafią na miejsce, dlatego zmiana, która coś usuwa, trafia na środowisko w dwóch wdrożeniach.
- Każde środowisko pobiera własne pakiety NuGet. Pakiety NuGet deklarowane w
nuget.jsonpackage'a pobiera każde środowisko, które go otrzymuje, łącznie z buildem, więc każde musi mieć dostęp do nuget.org albo do feedu, z którym skonfigurowano jego serwery. Build bierzeScripting__NuGet__Sourcesi ustawieniaScripting__NuGet__Feeds__*ze środowiska, w którym działa CLI. Gdy pakietów NuGet nie da się przywrócić, wysłanie zmian jest odrzucane i niczego nie zmienia:planw CLI sprawdza to, zanim cokolwiek zostanie wdrożone, abuildideployczekają, aż zostaną przywrócone.
Co dalej
Sekcja Praca w zespole opisuje, jak programiści dzielą repozytorium, które wdraża pipeline. Strona Przestrzenie robocze i hosting wyjaśnia, na jakie środowiska wdraża, a sekcja Database Deployments opisuje etap schematu.