Skip to content

docs: actualiseer README naar de huidige repo en modules #571

docs: actualiseer README naar de huidige repo en modules

docs: actualiseer README naar de huidige repo en modules #571

Workflow file for this run

# Deploy naar ZAD (Operations Manager) via RijksICTGilde/zad-actions.
#
# DRIE losse ZAD-projecten (deployments zijn geïsoleerd; cross-project bereik je via de
# https-ingress-URLs `<component>-<deployment>-<projectid>.rig.prd1.gn2.quattro.rijksapps.nl`):
#
# uitvraag (mpfb-8wh) componenten: redis + uitvraag in de deployments
# `test`/`pr-<n>`, plus logius-fsc{pg,mgr,ctl,outway,inway,
# txlog} (FSC-peer van de uitvraag-organisatie) in de EIGEN,
# preview-loze deployment `fsc-logius` — zie
# demo/environment/logius/
# externe-stubs (mpfpsm-lcl) componenten: profiel + notificatie (WireMock-stubs)
# magazijnen (mpfm-w3h) componenten: magazijna + magazijnb in de deployments
# `test`/`pr-<n>`, plus magazijna-fsc{pg,mgr,ctl,inway,
# txlog} (FSC-provider-peer) in de EIGEN, preview-loze
# deployment `fsc-magazijna` — zie
# demo/environment/magazijn-a/
#
# Redis (sessiecache) draait per project intern (centrale ZAD-Redis v7 mist RediSearch);
# interne calls zijn http: redis via redis://…:6379. Het LDV-logboek draait op de
# PostgreSQL die het ZAD-platform per component levert (service `postgresql-database`,
# niet in de component-payloads hieronder — het platform provisioneert 'm zelf); de
# interne JDBC-verbinding daarheen is plaintext, waarvoor
# FBS_LDV_UNSAFE_ALLOW_PLAINTEXT_ENDPOINT aan blijft staan (rationale + voorwaarden in de
# KDoc van OutboundTlsValidator.requireHttps).
#
# HARDE VOORWAARDE voor plaintext-LDV met echte persoonsgegevens: het ZAD-project levert
# pod-to-pod transport-encryptie (mesh-mTLS), niet enkel netwerk-isolatie — de BSN in het
# LDV-dataSubjectId gaat anders onversleuteld over de draad (BIO 13.2.1 / AVG art. 32). De
# applicatie kan dit niet verifiëren; bevestig het per project in het deployment-runbook
# vóór je de override aanzet. Zonder die bevestiging: alleen synthetische test-data.
#
# App-config staat NIET hier (de deploy-action draagt geen env). Configureer de runtime-env
# éénmalig per component op de `test`-deployment van elk project in Operations Manager;
# previews erven via `clone-from: test`. Cross-project-URLs templaten op de ZAD-systeemvar
# `$DEPLOYMENT_NAME` (door ZAD geïnjecteerd + geëxpandeerd), zodat een preview met ZIJN EIGEN
# pr-<n>-buren praat — het doel-project-id staat vast in de URL. Bv. op uitvraag:
# MAGAZIJN_A_URL=https://magazijna-$DEPLOYMENT_NAME-mpfm-w3h.rig... (en magazijnb)
# PROFIEL_SERVICE_URL=https://profiel-$DEPLOYMENT_NAME-mpfpsm-lcl.rig...
# En op magazijnen: AANMELD_URL → uitvraag-webhook (POST /api/v1/aanmeldingen),
# NOTIFICATIE_URL → notificatie-stub (POST /events).
#
# GESTAPELDE PR'S (base != main) deployen niet — zie het `branches`-filter hieronder. Hun
# wijzigingen belanden alsnog in een preview zodra ze de PR bereiken die wél op main mikt: die
# krijgt dan een `synchronize` en rolt zijn eigen pr-<n> opnieuw uit. Wat zo'n PR aan controles
# houdt: test, detekt-gate en infra-image-pins — die workflows draaien zichzelf op elke PR
# BEHALVE die naar main (`branches-ignore: [main]`), en worden voor een PR naar main juist hier
# aangeroepen. CodeQL en de fuzz-check draaien er NIET: codeql.yml filtert op main en
# cflite_pr.yml draait uitsluitend als aangeroepen workflow vanuit deze. Die dekking komt dus pas
# bij de PR naar main. Een gestapelde PR is inhoudelijk getoetst maar niet security-gescand; weeg
# dat mee bij het reviewen ervan.
#
# BEKENDE BEPERKING: wordt een PR ná een preview-deploy handmatig weggericht van main, dan valt
# hij buiten dit filter en ruimt het sluiten zijn pr-<n>-deployments en ghcr-tags niet meer op.
# Handmatig opruimen (of de base terugzetten vóór het sluiten). De omgekeerde beweging —
# GitHub's automatische retarget náár main bij het mergen van de parent — is veilig: de checks
# zijn dan afwezig i.p.v. groen, en `strict: true` op main dwingt sowieso een verse run af.
#
# TIMEOUT-MINUTES OP ELKE JOB: GitHub's default is 360 minuten. Een job die hangt (netwerkstall,
# vastgelopen Testcontainer, een herintroduceerde wachtlus) houdt dan zes uur een runner bezet
# voordat iemand het merkt. De waarden hieronder staan op ~3× de waargenomen maximumduur, dus ruim
# genoeg voor een trage runner maar kort genoeg om verspilling te begrenzen. Jobs die een andere
# workflow aanroepen kunnen de sleutel niet dragen; die staat daar in de aangeroepen workflow.
#
# Repo-secrets (Settings → Secrets and variables → Actions):
# ZAD_API_KEY_UITVRAAG — API-key project mpfb-8wh
# ZAD_API_KEY_PROFIEL — API-key project mpfpsm-lcl (externe-stubs)
# ZAD_API_KEY_MAGAZIJNEN — API-key project mpfm-w3h
# GH_ADMIN_TOKEN — PAT met repo-admin (env-cleanup; GITHUB_TOKEN mag dat niet;
# naam zónder `GITHUB_`-prefix — die is gereserveerd)
name: Deploy ZAD
on:
# `branches` filtert op de DOELbranch: alleen PR's naar main bouwen en deployen. Een gestapelde
# PR (base = een feature-branch) draait deze workflow dus helemaal niet — geen build, geen
# preview, en daarmee ook niets te gaten. Bewust hier en niet als `if:` per job: een job die via
# `if:` overslaat rapporteert `skipped`, en dat telt als succes voor branch protection. De drie
# `deploy-preview-*` zijn required contexts op main, dus zouden gestapelde PR's groene vinkjes
# verzamelen voor deploys die nooit gedraaid hebben. GitHub herricht een gestapelde PR
# automatisch naar main zodra de parent merget, zónder nieuw event — die stale vinkjes zouden
# dan blijven staan. Zonder run zijn de checks afwezig, wat de merge wél blokkeert.
#
# Let op de bewuste asymmetrie met test.yml/detekt.yml/pin-consistency.yml: die dragen het
# complement (`branches-ignore: [main]`), want een gestapelde PR verdient wél inhoudelijke
# toetsing. Alleen de deploy valt weg. Samen dekken de twee filters elke PR precies één keer.
pull_request:
branches: [main]
types: [opened, synchronize, reopened, closed]
push:
branches: [main]
# Least-privilege default voor GITHUB_TOKEN: read-only op workflow-niveau; jobs die schrijven
# (build → packages, cleanup → deployments/packages/pull-requests) declareren dat zelf.
permissions: read-all
# GEEN workflow-brede concurrency. De toetsende checks draaien sinds #173 als jobs ín deze
# workflow; een workflow-brede groep met `cancel-in-progress: false` zou een opvolgende push laten
# wachten tot de vorige deploy klaar is én de achterhaalde testrun helemaal uit laten draaien —
# precies de verspilling die we wegnemen. Met `cancel-in-progress: true` zou een lopende ZAD-deploy
# halverwege afgebroken kunnen worden, wat een deployment in een inconsistente staat achterlaat.
# Beide eisen tegelijk kan alleen per job:
# * build/toetsing → eigen groep met cancel-in-progress: true (achterhaald werk stoppen);
# * deploy/cleanup → eigen groep PER PROJECT + doel-deployment met cancel-in-progress: false
# (nooit halverwege afbreken; per project apart zodat de drie parallelle jobs elkaar niet
# blokkeren, wat met één gedeelde groep wél zou gebeuren).
env:
REGISTRY: ghcr.io
PROJECT_UITVRAAG: mpfb-8wh
PROJECT_EXTERNE_STUBS: mpfpsm-lcl
PROJECT_MAGAZIJNEN: mpfm-w3h
# Publiek infra-image (niet door de cleanup verwijderd). Pin in sync met compose.yaml
# (zie pin-consistency.yml).
#
# Redis draait op ZAD zónder persistence: zet op de redis-component de runtime-env
# `REDIS_ARGS=--save "" --appendonly no` (in Operations Manager, net als de overige
# runtime-env hierboven). Het restricted SecurityContext (willekeurige non-root UID)
# mag niet in de image-datadir `/data` schrijven, dus RDB-snapshots falen met
# "Permission denied". Kan uit: de sessiecache is ephemeral en rekent nergens op
# persistence (idempotente RediSearch-bootstrap, TTL-entries, crash-safe vangnet-lock).
REDIS_IMAGE: redis/redis-stack-server:7.4.0-v3
# Verse preview-provisioning (`clone-from: test` maakt nieuwe volumes + ingress aan) duurt
# structureel langer dan het bijwerken van een bestaande deployment. De action-default van
# 300s is daarvoor te krap: uitvraag en externe-stubs time-outen er reproduceerbaar op
# ("Task did not complete within 300s"), terwijl de test-deploys (bestaande deployment) in
# <100s klaar zijn en de default houden. Gelijkgetrokken met de gate-timeout (900s) zodat
# er één marge-getal in deze workflow rondgaat.
# Let op: dit is de wachttijd van de runner op de OM-task. De melding "timed out waiting for
# application to be created" komt daarentegen van OM zelf (Argo-Application-wait) en wordt
# NIET door deze waarde beïnvloed — die deploys landen alsnog gezond; opnieuw draaien volstaat.
PREVIEW_TASK_TIMEOUT: '900'
jobs:
# Bepaalt in één keer wát er voor deze revisie moet draaien. Levert vier onafhankelijke
# uitkomsten: `run` (code-checks), `deploy` (bouwen en uitrollen), `demo-only` (test-scope)
# en `fuzz` (fuzz-ronde). Voor een bot-PR valt alléén het uitrollen af — tests, detekt en
# fuzz draaien juist wél, want een dependency-bump hoort getoetst te worden.
#
# De build-, gate- en deploy-preview-jobs hangen aan `deploy`; een via `if` overgeslagen job ín
# deze workflow telt als 'skipped' = succes voor de required checks, dus de merge blijft
# mogelijk. Op een push naar main staat alles aan.
#
# Twee gevallen rollen niet uit:
# - Wijzigingen die de uitgerolde applicatie niet raken (docs, bruno, demo, demo-console).
# - PR's van een bot: `zad-actions` weigert die zelf (`skip-bot-prs`, default true), dus de
# preview komt er toch niet. Zonder deze uitsluiting bouwden en pushten we er wél drie
# images voor die nooit een pod bereiken — en de cleanup slaat bot-PR's óók over, dus die
# bleven permanent in ghcr staan (zichtbaar aan `pr-143` en `pr-167` van gesloten
# Dependabot-PR's).
changes:
# Op een close-event slaan alle consumenten over, dus dan valt er niets te bepalen.
if: github.event.action != 'closed'
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
run: ${{ steps.filter.outputs.run }}
deploy: ${{ steps.filter.outputs.deploy }}
demo-only: ${{ steps.filter.outputs.demo-only }}
fuzz: ${{ steps.filter.outputs.fuzz }}
steps:
# Eén plek waar de gewijzigde bestanden opgehaald en beoordeeld worden. De aangeroepen
# workflows stelden dezelfde vraag elk apart; dat kostte per PR vier runner-allocaties
# voor hetzelfde antwoord. Zij krijgen de uitkomst nu als input en slaan hun eigen
# detectie over.
- name: Bepaal wat er moet draaien
id: filter
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
EVENT: ${{ github.event_name }}
REPO: ${{ github.repository }}
PR: ${{ github.event.pull_request.number }}
# Het type komt van GitHub zelf (enum), niet uit door de indiener bepaalde tekst.
PR_AUTHOR_TYPE: ${{ github.event.pull_request.user.type }}
run: |
set -euo pipefail
# Alles aan op een push naar main: er is geen PR-bestandenlijst om tegen af te zetten.
if [ "$EVENT" != "pull_request" ]; then
{
echo "run=true"
echo "deploy=true"
echo "demo-only=false"
echo "fuzz=true"
} >> "$GITHUB_OUTPUT"
exit 0
fi
if [ "$PR_AUTHOR_TYPE" = "Bot" ]; then
# Luid loggen: een overgeslagen deploy laat de required checks 'skipped' (= succes)
# rapporteren, dus een onterechte overslag moet in de run-samenvatting zichtbaar zijn.
# Alleen het uitrollen valt af; de code-checks draaien wél, want een bot-PR
# (bv. een dependency-bump) hoort getoetst te worden. Welke checks nodig zijn volgt
# uit dezelfde bestandsanalyse als bij een gewone PR — een action-pin-bump verdient
# geen fuzz-ronde.
echo "::notice::PR van een bot — zad-actions deployt die niet, dus bouwen we ook niet."
BOT_PR=true
fi
# Fail-safe: kan de bestandenlijst niet opgehaald worden (API-hik, rate-limit), deploy
# dan TÓCH i.p.v. stil overslaan — anders zou een overgeslagen deploy onterecht als
# 'skipped' (= succes) doortellen in de required checks.
if ! files=$(gh api --paginate "repos/$REPO/pulls/$PR/files" --jq '.[].filename'); then
echo "::warning::Kon gewijzigde bestanden niet ophalen — alles draait fail-safe."
{
echo "run=true"
echo "deploy=true"
echo "demo-only=false"
echo "fuzz=true"
} >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Gewijzigde bestanden:"
printf '%s\n' "$files"
# Alle vier de vragen zijn dezelfde grep over de bestandenlijst. Herestring in plaats
# van een pipe: `grep -q` sluit de pipe bij de eerste match, en met `pipefail` zou die
# SIGPIPE als "geen match" doorgaan. `grep` geeft 1 bij geen match en 2 bij een echte
# fout; alleen 1 mag tot overslaan leiden, want een overgeslagen job rapporteert
# 'skipped' en telt als succes in de required checks. Een echte fout valt daarom terug
# op wél draaien.
grep_fail_safe() {
local rc=0
grep -q "$@" <<<"$files" || rc=$?
case "$rc" in
0) return 0 ;;
1) return 1 ;;
*)
echo "::warning::Filter kon niet beoordelen (grep rc=$rc) — uitkomst fail-safe op draaien."
return 0
;;
esac
}
# `run`: raakt de PR iets anders dan documentatie? Poort voor de code-checks.
if grep_fail_safe -vE '(^docs/|\.md$)'; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "Alleen documentatie gewijzigd — code-checks en deploy overgeslagen."
echo "run=false" >> "$GITHUB_OUTPUT"
fi
# `deploy`: kan de wijziging de uitgerolde applicatie raken? Strenger dan `run`, want
# dit is de enige post die échte clustercapaciteit kost (pods, volumes, ingress) in
# plaats van alleen runnertijd. Uitgesloten: documentatie, de Bruno-collectie, de
# demo-stack, demo-console, de fuzz-configuratie en de workflows die uitsluitend
# toetsen. Zonder dat filter kostte een PR aan bijvoorbeeld de fuzz-configuratie tóch
# twee jib-builds plus drie previews — uitrollen van een image dat per definitie gelijk
# is aan main. demo-console zit in geen enkel uitgerold image: het staat niet in de
# build-matrix hieronder en heeft geen ZAD-component.
#
# deploy.yml zelf, .github/actions/ en de zad-actions staan er bewust NIET bij: die
# bepalen de uitrol, dus juist daar is een preview het bewijs dat de wijziging klopt.
#
# Het contract-bootstrap-image komt óók uit demo/, maar wordt alleen op push naar main
# uitgerold; op een PR bouwt en draait `fsc-harness-overlays.yml` hem. Een uitzondering
# hier zou dus de hele deploy-keten (twee jib-images, de stubs en drie previews)
# openzetten voor een wijziging die daar niets mee te maken heeft.
niet_deploybaar='(^docs/|\.md$|^bruno/|^demo/|^services/demo-console/|^\.clusterfuzzlite/|^\.github/workflows/(test|detekt|codeql|scorecard|architecture|pin-consistency|cflite_pr|cflite_batch|cflite_cron|fsc-harness-overlays|fuzz-base-image)\.yml$)'
if [ "${BOT_PR:-false}" = "true" ]; then
echo "deploy=false" >> "$GITHUB_OUTPUT"
elif grep_fail_safe -vE "$niet_deploybaar"; then
echo "deploy=true" >> "$GITHUB_OUTPUT"
else
echo "Geen wijziging die de images of de uitrol raakt — bouwen en deployen overgeslagen."
echo "deploy=false" >> "$GITHUB_OUTPUT"
fi
# `demo-only`: zie de toelichting in test.yml — demo-console is het enige blad in de
# module-graaf zonder koppeling, dus dan volstaat een build van die ene module.
if grep_fail_safe -vE '(^docs/|\.md$|^services/demo-console/|^demo/)'; then
echo "demo-only=false" >> "$GITHUB_OUTPUT"
else
echo "Uitsluitend demo-console geraakt — test-job scoped naar die module."
echo "demo-only=true" >> "$GITHUB_OUTPUT"
fi
# `fuzz`: alleen bronnen die de fuzz-doelen of hun build raken.
if grep_fail_safe -E '(^libraries/|^services/|^pom\.xml$|^\.clusterfuzzlite/)'; then
echo "fuzz=true" >> "$GITHUB_OUTPUT"
else
echo "Geen fuzz-relevante wijzigingen — fuzzing overgeslagen."
echo "fuzz=false" >> "$GITHUB_OUTPUT"
fi
# Afgeleide waarden op één plek: image-tag + lowercase GHCR-owner (GHCR eist lowercase).
#
# De PR-tag draagt de head-sha en is dus UNIEK per commit — dat is de kern van de
# preview-uitrol, geen cosmetica. De deploy zet de image-referentie in het door Operations
# Manager gerenderde k8s-manifest, en Argo CD rolt alleen uit bij een verschil in dát
# manifest. Met een vaste tag `pr-<n>` blijft het manifest bij elke volgende commit
# byte-identiek: de deploy-check wordt groen terwijl de pod op de image-laag van de eerste
# build blijft draaien. `imagePullPolicy: Always` vangt dat niet af — dat werkt pas bij een
# herstart, en die komt niet vanzelf. Op main speelde het niet: `main-<sha7>` wijzigt al
# per commit.
#
# Elke build krijgt zo zijn eigen tag; `cleanup-preview-images` ruimt ze bij PR-sluiten
# allemaal op — op prefix, plus de kale `pr-<n>` van vóór deze wijziging.
meta:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
tag: ${{ steps.m.outputs.tag }}
owner: ${{ steps.m.outputs.owner }}
steps:
- id: m
# Variabele waarden via env i.p.v. inline interpolatie (defense-in-depth injectie).
env:
EVENT: ${{ github.event_name }}
PR: ${{ github.event.number }}
# Op een pull_request-event is GITHUB_SHA de (efemere) merge-commit; de head-sha is
# wat in de PR-tijdlijn staat en waar een reviewer op kan matchen.
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
if [ "$EVENT" = "pull_request" ]; then
tag="pr-${PR}-${HEAD_SHA::7}"
# Een herdraai bouwt uit refs/pull/<n>/merge, dus met de main van dát moment. Is main
# inmiddels verder, dan levert dezelfde head-sha andere inhoud op en zou de tag
# verschuiven — precies de bevriezing die deze tagvorm moet voorkomen. Vanaf poging 2
# dus een eigen tag. Poging 1 (het normale geval) blijft kaal en leesbaar.
if [ "$GITHUB_RUN_ATTEMPT" -gt 1 ]; then
tag="${tag}-r${GITHUB_RUN_ATTEMPT}"
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
else
echo "tag=main-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
fi
echo "owner=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_OUTPUT"
# Bouw + push de service-images met jib (geen Dockerfile). Niet op PR-close, en niet wanneer
# `changes` de keten heeft uitgesloten: zo'n revisie deployt toch niet, dus twee volledige
# Maven/jib-builds + push kosten dan alleen rekentijd, netwerk en een ghcr-versie die nooit
# een pod bereikt.
build:
if: github.event_name == 'push' || (github.event.action != 'closed' && needs.changes.outputs.deploy == 'true')
needs: [meta, changes]
runs-on: ubuntu-latest
timeout-minutes: 20
# Een opvolgende push maakt deze build achterhaald: de preview rolt straks toch de nieuwere
# commit uit, dus doorbouwen levert alleen runnertijd en een ghcr-versie op die nooit een pod
# bereikt. Per matrix-service een eigen groep, anders blokkeren de twee parallelle builds van
# dezelfde run elkaar.
concurrency:
group: build-${{ matrix.service }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
packages: write
strategy:
matrix:
service: [berichtenuitvraag, berichtenmagazijn]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: temurin
java-version: '21'
# Cache de Maven-dependency-tree tussen runs; elke PR-push bouwt anders de
# volledige boom opnieuw (~/.m2 redownload) — onnodig netwerk/energie/CI-tijd.
cache: maven
- name: Build + push image (jib)
# Variabele waarden via env i.p.v. inline interpolatie (defense-in-depth injectie).
# Het GHCR-token gaat via de MicroProfile-env-vorm QUARKUS_CONTAINER_IMAGE_PASSWORD
# i.p.v. een -D-flag, zodat het secret niet in de proceslijst (ps) of build-output
# belandt. Quarkus mapt die env-var op quarkus.container-image.password.
env:
SERVICE: ${{ matrix.service }}
GROUP: ${{ needs.meta.outputs.owner }}
TAG: ${{ needs.meta.outputs.tag }}
GHCR_USER: ${{ github.actor }}
QUARKUS_CONTAINER_IMAGE_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
run: |
./mvnw -B package -DskipTests \
-pl "services/$SERVICE" -am \
-Dquarkus.container-image.build=true \
-Dquarkus.container-image.push=true \
-Dquarkus.container-image.registry="$REGISTRY" \
-Dquarkus.container-image.group="$GROUP" \
-Dquarkus.container-image.tag="$TAG" \
-Dquarkus.container-image.username="$GHCR_USER"
# Externe-stubs: één WireMock-image met de profiel- én notificatie-mappings erin gebakken
# (plain docker, geen jib). Wordt als twee losse componenten gedeployd (profiel + notificatie).
#
# BEWUST GEEN paths-filter, hoewel de inhoud zelden wijzigt: de deploy-jobs verwachten een
# image op de tag van déze run, en die tag draagt per commit de head-sha — precies wat de
# preview-uitrol laat werken. Overslaan bij een ongewijzigde stub-map zou een
# tag-hergebruikstrategie vergen die daarmee botst. De prijs is een herbouw per commit; de
# opbrengst van een filter weegt daar niet tegenop zolang de per-commit-tag de basis is.
build-externe-stubs:
if: github.event_name == 'push' || (github.event.action != 'closed' && needs.changes.outputs.deploy == 'true')
needs: [meta, changes]
runs-on: ubuntu-latest
timeout-minutes: 15
concurrency:
group: build-externe-stubs-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Build + push externe-stubs
env:
OWNER: ${{ needs.meta.outputs.owner }}
TAG: ${{ needs.meta.outputs.tag }}
GHCR_USER: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "$GHCR_TOKEN" | docker login "$REGISTRY" -u "$GHCR_USER" --password-stdin
IMG="$REGISTRY/$OWNER/fbs-externe-stubs:$TAG"
docker build -t "$IMG" wiremock/externe-stubs
docker push "$IMG"
# De contract-bootstrap draait op ZAD als component náást de manager van zijn eigen peer: de
# interne manager-API heeft daar geen route en de tenant-baseline-NetworkPolicy laat alleen
# verkeer binnen hetzelfde deployment toe. Eén image, twee rollen — welke, leest het entrypoint
# uit FSC_ROL in de component-env.
build-contract-bootstrap:
if: github.event_name == 'push' || (github.event.action != 'closed' && needs.changes.outputs.run == 'true')
needs: [meta, changes]
runs-on: ubuntu-latest
timeout-minutes: 15
concurrency:
group: build-contract-bootstrap-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Build + push contract-bootstrap
env:
OWNER: ${{ needs.meta.outputs.owner }}
TAG: ${{ needs.meta.outputs.tag }}
GHCR_USER: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "$GHCR_TOKEN" | docker login "$REGISTRY" -u "$GHCR_USER" --password-stdin
IMG="$REGISTRY/$OWNER/fbs-fsc-contract-bootstrap:$TAG"
# Context is demo/environment/ en niet de contracts-map: de scripts leunen op ../../lib.
docker build -f demo/environment/federatie/contracts/Dockerfile -t "$IMG" demo/environment
docker push "$IMG"
# De vier toetsende workflows draaien als aangeroepen (`workflow_call`) job ín deze workflow,
# zodat de deploy er met `needs:` aan kan hangen. Vóór #173 draaiden ze zelfstandig en wachtte
# een `gate`-job er in een poll-lus op: ~461 s per run een runner die niets deed dan `sleep 15`.
# Hun eigen `pull_request`-trigger staat nu op `branches-ignore: [main]` — het complement van de
# `branches: [main]` hierboven — zodat een gestapelde PR ze zelfstandig draait en een PR naar
# main ze precies één keer draait, hier.
#
# LET OP: door de aanroep krijgen de check-runs het caller-job-voorvoegsel: `checks-test / test`
# in plaats van `test`. Branch protection op main pint op die namen; wijzig je hier een job-id,
# dan moet de required context mee. Een required context die nooit meer verschijnt, blokkeert
# elke merge.
#
# `github.event.action != 'closed'`: de close-trigger is er voor de cleanup-jobs, daar valt
# niets te toetsen.
# De caller-jobs staan bewust ALTIJD aan; het overslaan gebeurt binnen de aangeroepen
# workflow. Een overgeslagen caller-job draait die workflow namelijk nooit, waardoor de
# geneste check-run (`checks-test / test`) niet bestaat — en een required context die niet
# verschijnt blokkeert de merge voorgoed. Anders dan een overgeslagen job ín deze workflow,
# die wél als 'skipped' (= succes) doortelt.
#
# `!cancelled()` zodat een mislukte detectie de checks niet meesleept: de uitkomst is dan
# leeg, en op een lege uitkomst zet de aangeroepen workflow zijn eigen detectie weer aan.
# De uitkomst is daarmee fail-safe — hij wordt opnieuw bepaald, niet aangenomen.
checks-test:
needs: changes
if: >-
!cancelled()
&& (github.event_name == 'push' || github.event.action != 'closed')
uses: ./.github/workflows/test.yml
with:
wijzigingen-relevant: ${{ needs.changes.outputs.run }}
demo-only: ${{ needs.changes.outputs.demo-only }}
# De aangeroepen workflow mag nooit meer rechten hebben dan de caller-job toekent;
# pull-requests: write is voor de JaCoCo-coverage-comment.
permissions:
contents: read
pull-requests: write
checks-detekt:
needs: changes
if: >-
!cancelled()
&& (github.event_name == 'push' || github.event.action != 'closed')
uses: ./.github/workflows/detekt.yml
with:
wijzigingen-relevant: ${{ needs.changes.outputs.run }}
permissions:
contents: read
pull-requests: read
security-events: write
checks-pins:
if: github.event_name == 'push' || github.event.action != 'closed'
uses: ./.github/workflows/pin-consistency.yml
# pull-requests: write voor de melding over een verouderde fuzz-basis-image-pin; een
# aangeroepen workflow kan nooit meer krijgen dan de caller-job toekent.
permissions:
contents: read
pull-requests: write
# ClusterFuzzLite fuzzt alleen PR's: op een push naar main is er geen basis om code-change-fuzzing
# tegen af te zetten. Deze job wordt daar dus overgeslagen, en de gate telt dat als OK.
checks-fuzz:
needs: changes
if: >-
!cancelled()
&& github.event_name == 'pull_request'
&& github.event.action != 'closed'
uses: ./.github/workflows/cflite_pr.yml
with:
fuzz-relevant: ${{ needs.changes.outputs.fuzz }}
permissions: read-all
# Kwaliteitspoort vóór élke ZAD-deploy: geen cluster-capaciteit (en geen review-ruis van een
# "geslaagde" preview) verspillen aan een revisie die de tests/kwaliteitsgates niet haalt.
#
# De poort zelf toetst niets — dat doen de checks-jobs hierboven. Hij aggregeert alleen hun
# resultaat op één plek, zodat de "overgeslagen telt als OK"-regel één keer bestaat in plaats van
# als `always() && ...`-formule op elk van de zes deploy-jobs, met zes kansen op drift.
#
# CodeQL en architecture bewust NIET in de set: CodeQL mag traag of tijdelijk rood zijn (bv.
# extractor-lag op een nieuwe Kotlin-versie) zonder de preview te blokkeren, en architecture
# triggert alleen op docs/architecture-wijzigingen.
gate:
# `!cancelled()` i.p.v. de impliciete success(): een overgeslagen `checks-fuzz` (push naar main)
# zou deze job anders meeslepen in 'skipped' en de deploy stilzwijgend blokkeren. Bij een
# geannuleerde run hoeft de poort juist niet meer te oordelen.
# Niet op PR-close (teardown, geen deploy) en niet wanneer `changes` de keten heeft
# uitgesloten (docs-only of bot-PR) — dan valt er niets te bewaken.
if: >-
!cancelled()
&& (github.event_name == 'push'
|| (github.event.action != 'closed' && needs.changes.outputs.deploy == 'true'))
needs: [changes, checks-test, checks-detekt, checks-pins, checks-fuzz]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Beoordeel de verplichte checks
env:
# Naam=resultaat per verplichte check. De namen zijn die van de check-runs zoals ze in
# de PR verschijnen, niet de job-id's — dit is wat een lezer van het logboek zoekt.
# De fuzz-check hoort er alleen bij op een pull_request; op een push naar main is hij
# per definitie afwezig en zou hij elke run een 'overgeslagen'-waarschuwing opleveren.
RESULTATEN: |
test=${{ needs.checks-test.result }}
detekt-gate=${{ needs.checks-detekt.result }}
infra-image-pins=${{ needs.checks-pins.result }}
${{ github.event_name == 'pull_request' && format('PR={0}', needs.checks-fuzz.result) || '' }}
run: |
set -euo pipefail
geblokkeerd=0
while IFS='=' read -r naam resultaat; do
[ -n "$naam" ] || continue
case "$resultaat" in
success)
echo "Verplichte check '$naam' geslaagd."
;;
skipped)
# Legitiem wanneer de check zichzelf heeft overgeslagen via zijn eigen
# relevantie-filter: de fuzz-`PR` bij een niet-fuzz-relevante wijziging of op een
# push naar main, of een docs-only wijziging. (Een docs-only PR bereikt deze poort
# niet eens — dan is de deploy zelf al overgeslagen.) Luid loggen zodat een
# onbedoelde overslag auditbaar is i.p.v. stil als 'groen' doortelt.
echo "::warning::Verplichte check '$naam' is overgeslagen — als OK geteld (check overgeslagen via eigen relevantie-filter)."
;;
*)
echo "::error::Verplichte check '$naam' eindigde als '$resultaat' — deploy geblokkeerd."
geblokkeerd=1
;;
esac
done <<< "$RESULTATEN"
if [ "$geblokkeerd" -ne 0 ]; then
exit 1
fi
echo "Alle verplichte checks groen — deploy vrijgegeven."
# PR-preview: één job PER project zodat ze PARALLEL draaien — bij een fout falen alle drie
# projecten tegelijk (geen fail-fast tussen losse jobs), dus alle fouten in één run
# zichtbaar i.p.v. één-voor-één. Config geërfd van `test`. wait-for-ready staat UIT: de
# zad-action doet geen k8s-readinessprobe maar curlt vanaf de runner ELKE component-URL op
# één health-endpoint (input `health-endpoint`, default '/'). De services bieden nu wél
# /q/health/ready (smallrye-health), maar deze deployments mengen niet-HTTP-componenten
# (redis) die op dat pad nooit 2xx geven → de wachtlus zou timen out. Aanzetten
# kan pas met een per-component health-endpoint of een Quarkus-only deployment; tot dan 'false'.
deploy-preview-uitvraag:
if: github.event_name == 'pull_request' && github.event.action != 'closed' && needs.changes.outputs.deploy == 'true'
needs: [meta, build, build-externe-stubs, gate, changes]
runs-on: ubuntu-latest
timeout-minutes: 20
# Eén ZAD-taak tegelijk op deze deployment; een nieuwe push wacht op de lopende i.p.v. die af
# te breken — een halverwege afgebroken ZAD-deploy laat de deployment in een inconsistente
# staat achter. De cleanup-job voor hetzelfde project + dezelfde PR deelt deze groep, zodat een
# PR-close een lopende deploy niet onder handen wegtrekt.
concurrency:
group: zad-uitvraag-pr-${{ github.event.pull_request.number }}
cancel-in-progress: false
permissions:
contents: read
pull-requests: write
# De GitHub-environment (één per PR) hangt aan déze job; de preview-URL komt uit de
# uitvraag-deploy (de frontend). De andere projecten dragen geen environment.
environment:
name: pr-${{ github.event.pull_request.number }}
url: ${{ steps.deploy.outputs.url }}
steps:
- name: Deploy uitvraag-project
id: deploy
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_UITVRAAG }}
project-id: ${{ env.PROJECT_UITVRAAG }}
deployment-name: pr-${{ github.event.pull_request.number }}
clone-from: test
comment-on-pr: 'true'
wait-for-ready: 'false'
task-timeout: ${{ env.PREVIEW_TASK_TIMEOUT }}
components: |
[
{"name": "redis", "image": "${{ env.REDIS_IMAGE }}"},
{"name": "uitvraag", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-berichtenuitvraag:${{ needs.meta.outputs.tag }}"}
]
deploy-preview-externe-stubs:
if: github.event_name == 'pull_request' && github.event.action != 'closed' && needs.changes.outputs.deploy == 'true'
needs: [meta, build, build-externe-stubs, gate, changes]
runs-on: ubuntu-latest
timeout-minutes: 20
concurrency:
group: zad-externe-stubs-pr-${{ github.event.pull_request.number }}
cancel-in-progress: false
permissions:
contents: read
steps:
# profiel + notificatie = zelfde image, losse componenten (eigen subdomein per stub).
- name: Deploy externe-stubs-project
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_PROFIEL }}
project-id: ${{ env.PROJECT_EXTERNE_STUBS }}
deployment-name: pr-${{ github.event.pull_request.number }}
clone-from: test
wait-for-ready: 'false'
task-timeout: ${{ env.PREVIEW_TASK_TIMEOUT }}
components: |
[
{"name": "profiel", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-externe-stubs:${{ needs.meta.outputs.tag }}"},
{"name": "notificatie", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-externe-stubs:${{ needs.meta.outputs.tag }}"}
]
deploy-preview-magazijnen:
if: github.event_name == 'pull_request' && github.event.action != 'closed' && needs.changes.outputs.deploy == 'true'
needs: [meta, build, build-externe-stubs, gate, changes]
runs-on: ubuntu-latest
timeout-minutes: 20
concurrency:
group: zad-magazijnen-pr-${{ github.event.pull_request.number }}
cancel-in-progress: false
permissions:
contents: read
steps:
- name: Deploy magazijnen-project
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_MAGAZIJNEN }}
project-id: ${{ env.PROJECT_MAGAZIJNEN }}
deployment-name: pr-${{ github.event.pull_request.number }}
clone-from: test
wait-for-ready: 'false'
task-timeout: ${{ env.PREVIEW_TASK_TIMEOUT }}
components: |
[
{"name": "magazijna", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-berichtenmagazijn:${{ needs.meta.outputs.tag }}"},
{"name": "magazijnb", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-berichtenmagazijn:${{ needs.meta.outputs.tag }}"}
]
# Opruimen bij PR-sluiten: per project een eigen (parallelle) job die zijn eigen deployment
# opruimt. De GitHub-environment (één per PR) ruimt alleen de uitvraag-job op; de andere
# zetten delete-github-env uit. De images gaan in één aparte job (cleanup-preview-images):
# de `delete-container`-stap van zad-actions verwijdert precies één exacte tag per package,
# en een PR heeft er sinds de unieke tags één per commit.
cleanup-preview-uitvraag:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
timeout-minutes: 15
# Zelfde groep als de deploy-job van dit project + deze PR: opruimen mag een lopende deploy
# niet onder handen wegtrekken.
concurrency:
group: zad-uitvraag-pr-${{ github.event.pull_request.number }}
cancel-in-progress: false
permissions:
deployments: write
pull-requests: write
steps:
# Pre-flight: een ontbrekende GH_ADMIN_TOKEN zou de env-/deployment-cleanup pas
# diep in de action laten falen (low-visibility moment bij PR-close). Faal hier luid.
- name: Controleer GH_ADMIN_TOKEN aanwezig
env:
GH_ADMIN_TOKEN: ${{ secrets.GH_ADMIN_TOKEN }}
run: |
if [ -z "$GH_ADMIN_TOKEN" ]; then
echo "::error::GH_ADMIN_TOKEN ontbreekt — env-/deployment-cleanup kan niet draaien. Zet de repo-secret (PAT met repo-admin)."
exit 1
fi
- name: Cleanup uitvraag-project
uses: RijksICTGilde/zad-actions/cleanup@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_UITVRAAG }}
project-id: ${{ env.PROJECT_UITVRAAG }}
deployment-name: pr-${{ github.event.pull_request.number }}
delete-github-env: 'true'
delete-github-deployments: 'true'
delete-container: 'false'
github-admin-token: ${{ secrets.GH_ADMIN_TOKEN }}
cleanup-preview-externe-stubs:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
timeout-minutes: 15
concurrency:
group: zad-externe-stubs-pr-${{ github.event.pull_request.number }}
cancel-in-progress: false
steps:
- name: Cleanup externe-stubs-project
uses: RijksICTGilde/zad-actions/cleanup@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_PROFIEL }}
project-id: ${{ env.PROJECT_EXTERNE_STUBS }}
deployment-name: pr-${{ github.event.pull_request.number }}
delete-github-env: 'false'
delete-container: 'false'
cleanup-preview-magazijnen:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
timeout-minutes: 15
concurrency:
group: zad-magazijnen-pr-${{ github.event.pull_request.number }}
cancel-in-progress: false
steps:
- name: Cleanup magazijnen-project
uses: RijksICTGilde/zad-actions/cleanup@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_MAGAZIJNEN }}
project-id: ${{ env.PROJECT_MAGAZIJNEN }}
deployment-name: pr-${{ github.event.pull_request.number }}
delete-github-env: 'false'
delete-container: 'false'
# Ruimt ALLE images van de PR op: één ghcr-versie per commit, niet alleen de laatste. De
# tags van deze PR zijn te herkennen aan de prefix `pr-<n>-`; het afsluitende koppelteken
# is essentieel, anders zou het sluiten van PR 16 de images van PR 168 meenemen.
#
# Bewust niet de `delete-container`-stap van zad-actions: die verwijdert één exacte tag, wat
# met unieke tags per commit alle tussenversies zou laten staan. Ook bewust géén
# package-brede fallback bij "cannot delete the last tagged version" (die de action wél
# heeft): dat zou een preview-cleanup het hele package laten verwijderen inclusief de
# main-images. De `main-<sha7>`-tags zorgen ervoor dat die situatie zich niet voordoet.
#
# RACE bij sluiten tijdens een lopende build (~85 s venster): sinds de workflow-brede
# concurrency naar job-niveau verhuisde (#173) wachten de jobs van een close-run niet meer op
# een nog draaiende build van een eerdere push. Sluit iemand de PR vlak na een push, dan kan
# deze sweep vóór die push af zijn en blijft één ghcr-versie achter. De build-jobs joinen niet
# in deze groep, want ze hebben er per service al één (anders zouden ze elkaar blokkeren).
# Gevolg is één weesversie, geen kapotte deploy; opruimen kan door deze job te herdraaien.
cleanup-preview-images:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
needs: meta
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
packages: write
steps:
- name: Verwijder de ghcr-versies van deze PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORG: ${{ needs.meta.outputs.owner }}
PREFIX: pr-${{ github.event.pull_request.number }}-
# Overgangsgeval: PR's die al liepen vóór de unieke tags bestonden, hebben nog een
# kale `pr-<n>`-versie in ghcr staan. Die valt niet onder de prefix, dus expliciet
# meenemen — anders blijft hij achter zodra zo'n PR sluit.
LEGACY_TAG: pr-${{ github.event.pull_request.number }}
run: |
set -euo pipefail
fail=0
# Expliciete lijst, bewust niet afgeleid uit alle org-packages: de prefix `pr-<n>-`
# is niet uniek binnen de organisatie, dus een brede sweep zou images van een
# gelijkgenummerde PR in een andere repo kunnen wissen. Houd deze lijst in sync met
# de `build`-matrix, `build-externe-stubs` en `build-contract-bootstrap`; een vergeten
# package laat weesversies achter.
for pkg in fbs-berichtenuitvraag fbs-berichtenmagazijn fbs-externe-stubs fbs-fsc-contract-bootstrap; do
if ! versions=$(gh api --paginate "orgs/$ORG/packages/container/$pkg/versions?per_page=100"); then
echo "::warning::Kon de versies van $pkg niet ophalen — images van deze PR blijven mogelijk staan."
fail=1
continue
fi
# --paginate levert per pagina een eigen array; jq verwerkt ze als losse inputs.
ids=$(printf '%s' "$versions" | jq -r --arg p "$PREFIX" --arg legacy "$LEGACY_TAG" \
'.[] | select(.metadata.container.tags | any(startswith($p) or . == $legacy)) | .id')
if [ -z "$ids" ]; then
echo "$pkg: geen versies met tag $LEGACY_TAG of prefix $PREFIX."
continue
fi
for id in $ids; do
if gh api "orgs/$ORG/packages/container/$pkg/versions/$id" -X DELETE; then
echo "$pkg: versie $id verwijderd."
else
echo "::warning::$pkg: versie $id niet verwijderd."
fail=1
fi
done
done
# Achterblijvende images zijn geen reden om de PR-afsluiting te blokkeren, maar het
# moet wel als rode job zichtbaar zijn — anders groeit de ghcr-berg ongemerkt door.
exit "$fail"
# Push naar main → per project de `test`-deployment (de baseline waarvan previews klonen;
# env/secrets configureer je daar in Operations Manager). Per project een eigen parallelle job.
deploy-test-uitvraag:
# Expliciete statusfunctie i.p.v. de impliciete success(): die kijkt niet alleen naar de vier
# directe needs hieronder, maar transitief door naar hún needs — en `checks-fuzz` (PR-only) is
# bij een push naar main altijd 'skipped', wat de impliciete success() over de hele keten laat
# falen. `gate` ontsnapt daar zelf al aan met `!cancelled()`, maar dat beschermt alleen `gate`
# zelf, niet de jobs die van `gate` afhangen. Vandaar hier dezelfde `!cancelled()`-vorm, plus
# expliciete per-need result-checks zodat een échte build-/gate-fout deze job wél overslaat.
if: >-
!cancelled()
&& needs.meta.result == 'success'
&& needs.build.result == 'success'
&& needs.build-externe-stubs.result == 'success'
&& needs.build-contract-bootstrap.result == 'success'
&& needs.gate.result == 'success'
&& github.event_name == 'push'
&& github.ref == 'refs/heads/main'
needs: [meta, build, build-externe-stubs, build-contract-bootstrap, gate]
runs-on: ubuntu-latest
timeout-minutes: 20
# Eén ZAD-taak tegelijk op de `test`-deployment van dit project; twee snel opeenvolgende merges
# naar main mogen elkaars deploy niet halverwege afbreken.
concurrency:
group: zad-uitvraag-test
cancel-in-progress: false
permissions:
contents: read
environment:
name: test
steps:
- name: Deploy uitvraag-project (test)
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_UITVRAAG }}
project-id: ${{ env.PROJECT_UITVRAAG }}
deployment-name: test
components: |
[
{"name": "redis", "image": "${{ env.REDIS_IMAGE }}"},
{"name": "uitvraag", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-berichtenuitvraag:${{ needs.meta.outputs.tag }}"}
]
# De FSC-peer draait in een EIGEN deployment `fsc-logius` binnen hetzelfde project, niet in
# `test`. Previews klonen met `clone-from: test`; een gekloonde peer zou zich met dezelfde
# federatie-OIN opnieuw aanmelden bij de gedeelde directory (en zonder de UI-only
# cert-attachments direct crashloopen). Wat niet in `test` staat, kan niet meegekloond worden.
# Deze stap doet alleen tag-updates; de eenmalige creatie (env/ports) loopt via
# demo/environment/logius/deploy/zad/upsert-peer.sh.
- name: Deploy uitvraag-project (fsc-logius — FSC-peer)
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_UITVRAAG }}
project-id: ${{ env.PROJECT_UITVRAAG }}
deployment-name: fsc-logius
components: |
[
{"name": "logius-fscpg", "image": "docker.io/library/postgres:17"},
{"name": "logius-fscmgr", "image": "ghcr.io/minbzk/moza-fsc-testnet-manager-migrate:v2.5.2"},
{"name": "logius-fscctl", "image": "ghcr.io/minbzk/moza-fsc-testnet-controller-migrate:v2.5.2"},
{"name": "logius-fscoutway", "image": "docker.io/federatedserviceconnectivity/outway:v2.5.2"},
{"name": "logius-fscinway", "image": "docker.io/federatedserviceconnectivity/inway:v2.5.2"},
{"name": "logius-fsctxlog", "image": "ghcr.io/minbzk/moza-fsc-testnet-txlog-migrate:v2.5.2"},
{"name": "logius-fscbootstrap", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-fsc-contract-bootstrap:${{ needs.meta.outputs.tag }}"}
]
deploy-test-externe-stubs:
# Zelfde reden als deploy-test-uitvraag hierboven: impliciete success() over de needs-keten
# wordt vergiftigd door het op push altijd-geskipte `checks-fuzz`, ook al is `gate` zelf groen.
if: >-
!cancelled()
&& needs.meta.result == 'success'
&& needs.build.result == 'success'
&& needs.build-externe-stubs.result == 'success'
&& needs.gate.result == 'success'
&& github.event_name == 'push'
&& github.ref == 'refs/heads/main'
needs: [meta, build, build-externe-stubs, gate]
runs-on: ubuntu-latest
timeout-minutes: 20
concurrency:
group: zad-externe-stubs-test
cancel-in-progress: false
permissions:
contents: read
steps:
- name: Deploy externe-stubs-project (test)
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_PROFIEL }}
project-id: ${{ env.PROJECT_EXTERNE_STUBS }}
deployment-name: test
components: |
[
{"name": "profiel", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-externe-stubs:${{ needs.meta.outputs.tag }}"},
{"name": "notificatie", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-externe-stubs:${{ needs.meta.outputs.tag }}"}
]
deploy-test-magazijnen:
# Zelfde reden als deploy-test-uitvraag hierboven: impliciete success() over de needs-keten
# wordt vergiftigd door het op push altijd-geskipte `checks-fuzz`, ook al is `gate` zelf groen.
if: >-
!cancelled()
&& needs.meta.result == 'success'
&& needs.build.result == 'success'
&& needs.build-externe-stubs.result == 'success'
&& needs.build-contract-bootstrap.result == 'success'
&& needs.gate.result == 'success'
&& github.event_name == 'push'
&& github.ref == 'refs/heads/main'
needs: [meta, build, build-externe-stubs, build-contract-bootstrap, gate]
runs-on: ubuntu-latest
timeout-minutes: 20
# Dekt ook de tweede stap (deployment `fsc-magazijna`) — die hoort bij hetzelfde project.
concurrency:
group: zad-magazijnen-test
cancel-in-progress: false
permissions:
contents: read
steps:
- name: Deploy magazijnen-project (test)
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_MAGAZIJNEN }}
project-id: ${{ env.PROJECT_MAGAZIJNEN }}
deployment-name: test
components: |
[
{"name": "magazijna", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-berichtenmagazijn:${{ needs.meta.outputs.tag }}"},
{"name": "magazijnb", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-berichtenmagazijn:${{ needs.meta.outputs.tag }}"}
]
# De FSC-peer draait in een EIGEN deployment `fsc-magazijna` binnen hetzelfde project, niet in
# `test`. Previews klonen met `clone-from: test`; een gekloonde peer zou zich met dezelfde
# federatie-OIN opnieuw aanmelden bij de gedeelde directory (en zonder de UI-only
# cert-attachments direct crashloopen). Wat niet in `test` staat, kan niet meegekloond worden.
# Deze stap doet alleen tag-updates; de eenmalige creatie (env/ports) loopt via
# demo/environment/magazijn-a/deploy/zad/upsert-peer.sh.
- name: Deploy magazijnen-project (fsc-magazijna — FSC-peer)
uses: RijksICTGilde/zad-actions/deploy@b844c76eba3502b40a19be868cdf0586e322f4b8 # v4
with:
api-key: ${{ secrets.ZAD_API_KEY_MAGAZIJNEN }}
project-id: ${{ env.PROJECT_MAGAZIJNEN }}
deployment-name: fsc-magazijna
components: |
[
{"name": "magazijna-fscpg", "image": "docker.io/library/postgres:17"},
{"name": "magazijna-fscmgr", "image": "ghcr.io/minbzk/moza-fsc-testnet-manager-migrate:v2.5.2"},
{"name": "magazijna-fscctl", "image": "ghcr.io/minbzk/moza-fsc-testnet-controller-migrate:v2.5.2"},
{"name": "magazijna-fscinway", "image": "docker.io/federatedserviceconnectivity/inway:v2.5.2"},
{"name": "magazijna-fsctxlog", "image": "ghcr.io/minbzk/moza-fsc-testnet-txlog-migrate:v2.5.2"},
{"name": "magazijna-fscbootstrap", "image": "${{ env.REGISTRY }}/${{ needs.meta.outputs.owner }}/fbs-fsc-contract-bootstrap:${{ needs.meta.outputs.tag }}"}
]