# Developer + CI entrypoints. # # These targets are the single source of truth for the checks. The Gitea # Actions workflow (.gitea/workflows/ci.yaml) invokes the SAME targets, so # `make ci` locally runs exactly what the pipeline runs — no drift. Until a # self-hosted runner is registered, `make ci` is the gate (see docs/runbooks/ci.md). SLN := register-referentie.slnx COMPOSE := infra/docker-compose.yml # Long-running services with a healthcheck — the smoke polls these for readiness # (infra/wait-healthy.sh). One-shot init jobs (oz-init, nrc-init, flowable-init) # are not polled; they only need to have run. See docs/runbooks/gitea-actions-gotchas.md. WAIT_SVCS := openzaak nrc-web acl bff # Config files (OpenZaak data.yaml, Keycloak realms, Flowable BPMN) are streamed # into external named volumes via `docker cp` (infra/seed-config.sh) instead of # bind-mounted, because bind mounts don't reach sibling containers on the # containerized CI runner. SEED populates them; run it before every `up`. The # volumes are `external`, so compose won't remove them — CFG_VOLS lists them for # explicit teardown. See docs/runbooks/gitea-actions-gotchas.md. SEED := bash infra/seed-config.sh CFG_VOLS := rr-oz-config rr-kc-realms rr-fl-bpmn # Local-only stack: same services but config is bind-mounted (no seed step), so a # plain `docker compose -f infra/docker-compose.local.yml up` works on any local # engine. This is the no-make / Windows-friendly path. See that file's header. LOCAL_COMPOSE := infra/docker-compose.local.yml OZ_COMPOSE := infra/openzaak/docker-compose.yml OZ_BASE := http://localhost:8000 NRC_COMPOSE := infra/opennotificaties/docker-compose.yml NRC_BASE := http://localhost:8001 KC_COMPOSE := infra/keycloak/docker-compose.yml KC_BASE := http://localhost:8180 FL_COMPOSE := infra/flowable/docker-compose.yml FL_BASE := http://localhost:8090/flowable-rest/service STACK_FILES := -f $(OZ_COMPOSE) -f $(NRC_COMPOSE) # On a rootless Podman dev box, point Docker CLI/Compose at the Podman socket — # but only if that socket exists and DOCKER_HOST isn't already set, so real # Docker hosts and CI runners are left untouched. PODMAN_SOCK := /run/user/$(shell id -u)/podman/podman.sock ifeq ($(wildcard $(PODMAN_SOCK)),$(PODMAN_SOCK)) ifeq ($(origin DOCKER_HOST),undefined) export DOCKER_HOST := unix://$(PODMAN_SOCK) endif endif .PHONY: ci lint build unit smoke up down local local-down changelog openzaak-up openzaak-smoke openzaak-seed openzaak-down stack-up stack-smoke stack-down keycloak-up keycloak-smoke keycloak-down flowable-up flowable-smoke flowable-down help ## ci: run the full pipeline — lint, build, unit, smoke (mirrors Gitea Actions) ci: lint build unit smoke ## lint: verify formatting (no changes) lint: dotnet format $(SLN) --verify-no-changes ## build: release build build: dotnet build $(SLN) -c Release ## unit: run unit tests unit: dotnet test $(SLN) -c Release ## smoke: seed config, bring the whole stack up, wait for health-checked services, tear down # SEED populates the external config volumes first (upstream images used verbatim; # only our acl/bff are built). `up -d --build` starts EVERYTHING. Readiness is # checked by infra/wait-healthy.sh polling the durable, health-checked services # ($(WAIT_SVCS)) via `docker inspect` — portable across docker compose and # podman-compose, and needing no `--wait` flag or host port access. The one-shots # (oz-init, flowable-init) aren't polled; they just need to have run. smoke: $(SEED) oz kc fl docker compose -f $(COMPOSE) up -d --build bash -c 'WAIT_TIMEOUT=420 bash infra/wait-healthy.sh $(WAIT_SVCS); rc=$$?; docker compose -f $(COMPOSE) down --volumes; docker volume rm -f $(CFG_VOLS) >/dev/null 2>&1; exit $$rc' ## up: seed config volumes and start the full stack (use instead of bare ## `docker compose up`, which can't self-seed the external config volumes) up: $(SEED) oz kc fl docker compose -f $(COMPOSE) up -d --build ## down: stop and remove the local stack (incl. the external config volumes) down: docker compose -f $(COMPOSE) down --volumes -docker volume rm -f $(CFG_VOLS) ## local: bring up the bind-mount stack (no seed step) and wait for health ## (Windows / no-make users: run `docker compose -f infra/docker-compose.local.yml up -d --build` directly) local: docker compose -f $(LOCAL_COMPOSE) up -d --build WAIT_TIMEOUT=420 bash infra/wait-healthy.sh $(WAIT_SVCS) ## local-down: stop and remove the bind-mount stack local-down: docker compose -f $(LOCAL_COMPOSE) down --volumes ## changelog: regenerate CHANGELOG.md from Conventional Commits (git-cliff) changelog: git-cliff --output CHANGELOG.md ## openzaak-up: start the OpenZaak stack (migrations run on first start) openzaak-up: $(SEED) oz docker compose -f $(OZ_COMPOSE) up -d ## openzaak-smoke: start OpenZaak, then assert it is up with auth enforced openzaak-smoke: openzaak-up @bash -c 'set -e; \ echo "waiting for OpenZaak to respond..."; \ for i in $$(seq 1 60); do \ code=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/zaken/api/v1/zaken || true); \ [ -n "$$code" ] && [ "$$code" != "000" ] && break; sleep 3; \ done; \ echo "GET /zaken/api/v1/zaken (unauth) -> $$code (expect 403, auth enforced)"; test "$$code" = "403"; \ admin=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/admin/); \ echo "GET /admin/ -> $$admin (expect 302)"; test "$$admin" = "302"; \ root=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/zaken/api/v1/); \ echo "GET /zaken/api/v1/ -> $$root (expect 200)"; test "$$root" = "200"; \ echo "OpenZaak smoke OK"' ## openzaak-seed: bring OpenZaak up and seed the BIG catalogus (idempotent) openzaak-seed: openzaak-up @bash -c 'for i in $$(seq 1 50); do \ c=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/catalogi/api/v1/ || true); \ [ "$$c" = "200" ] && break; sleep 3; done; echo "OpenZaak ready ($$c)"' python3 infra/openzaak/seed_catalogus.py ## openzaak-down: stop and remove the OpenZaak stack (wipes data) openzaak-down: docker compose -f $(OZ_COMPOSE) down --volumes -docker volume rm -f rr-oz-config ## stack-up: start OpenZaak + Open Notificaties together (shared network) stack-up: $(SEED) oz docker compose $(STACK_FILES) up -d ## stack-smoke: start both, assert OpenZaak (403/302/200) and NRC (302) are reachable stack-smoke: stack-up @bash -c 'set -e; \ echo "waiting for OpenZaak + Open Notificaties..."; \ for i in $$(seq 1 60); do \ oz=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/admin/ || true); \ nrc=$$(curl -s -o /dev/null -w "%{http_code}" $(NRC_BASE)/admin/ || true); \ [ "$$oz" = "302" ] && [ "$$nrc" = "302" ] && break; sleep 3; done; \ z=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/zaken/api/v1/zaken); \ echo "OpenZaak /zaken (unauth) -> $$z (expect 403)"; test "$$z" = "403"; \ echo "OpenZaak /admin/ -> $$oz (expect 302)"; test "$$oz" = "302"; \ echo "Open Notificaties /admin/-> $$nrc (expect 302)"; test "$$nrc" = "302"; \ echo "stack smoke OK"' ## stack-down: stop and remove both stacks (wipes data) stack-down: docker compose $(STACK_FILES) down --volumes -docker volume rm -f rr-oz-config ## keycloak-up: start Keycloak with the four imported realms keycloak-up: $(SEED) kc docker compose -f $(KC_COMPOSE) up -d ## keycloak-smoke: start Keycloak, then verify each realm logs in + returns its claim keycloak-smoke: keycloak-up @bash -c 'for i in $$(seq 1 60); do \ c=$$(curl -s -o /dev/null -w "%{http_code}" $(KC_BASE)/realms/digid/.well-known/openid-configuration || true); \ [ "$$c" = "200" ] && break; sleep 3; done; echo "Keycloak ready ($$c)"' python3 infra/keycloak/check_realms.py ## keycloak-down: stop and remove Keycloak keycloak-down: docker compose -f $(KC_COMPOSE) down --volumes -docker volume rm -f rr-kc-realms ## flowable-up: start Flowable (deploys registratie.bpmn on boot) flowable-up: $(SEED) fl docker compose -f $(FL_COMPOSE) up -d ## flowable-smoke: start Flowable, then verify a started instance waits on the external task flowable-smoke: flowable-up @bash -c 'for i in $$(seq 1 80); do \ c=$$(curl -s -o /dev/null -w "%{http_code}" -u rest-admin:test $(FL_BASE)/repository/process-definitions?key=registratie || true); \ [ "$$c" = "200" ] && break; sleep 3; done; echo "Flowable ready ($$c)"' python3 infra/flowable/verify.py ## flowable-down: stop and remove Flowable flowable-down: docker compose -f $(FL_COMPOSE) down --volumes -docker volume rm -f rr-fl-bpmn ## help: list available targets help: @grep -E '^## ' $(MAKEFILE_LIST) | sed 's/^## //'