Corepack может hang в CI runner на integrity-check либо non-TTY prompt
при первом activate. Заменяем на прямой npm install с pinned version
9.15.4 (latest stable v9, lockfile compat: lockfileVersion '9.0').
Изменения:
- ordinis-admin-ui/Dockerfile: corepack → npm install -g pnpm@9.15.4
- docs/Dockerfile: same swap
- .gitlab-ci.yml build-docs: same swap
Verified locally: docker build ordinis-admin-ui за 23 sec, no hang.
ordinis-app/pom.xml:
- surefire excludes **/e2e/*E2ETest.java по умолчанию (быстрые unit без Docker)
- profile `e2e`: combine.self override снимает excludes + includes только e2e
.gitlab-ci.yml: новый job maven-e2e:
- maven image + docker:29.1.2-dind service (тот же что docker-* jobs)
- DOCKER_HOST=tcp://docker:2375, TESTCONTAINERS_HOST_OVERRIDE=docker, RYUK_DISABLED=true
- mvn -pl ordinis-app -am -P e2e test
- artifact: junit reports
- rules: backend-changes (как maven-test)
Локально:
mvn -pl ordinis-app -am test # быстро, без Docker
mvn -pl ordinis-app -am -P e2e test # с Docker, ~23 sec для 12 тестов
В CI оба job'а параллельно после path-filter. e2e будет ловить регрессии типа
audit_log INET/scope filter gap которые мы уже нашли через эти тесты.
Path-filter (rules: changes: frontend) пропускал docker-admin-ui когда менялся
только backend. Но resolve-tag всегда отдавал общий UPSTREAM_IMAGE_TAG, и
helm в infra тащил admin-ui:<commit>, которого нет в registry → ErrImagePull.
Layer-cache BuildKit делает повторную сборку идентичных слоёв ~30 sec.
Стоимость незначительная, конфигурация надёжнее.
(Backend docker jobs уже собираются всегда — для тех же причин.)
Tests (Vitest):
- src/lib/dates.ts (вынесено из SchemaDrivenForm + dictionaries.$name): parseFormDate,
formatIsoDate, formatIsoDateTime, extractTime, combineDateTime, localTzOffset, nowIsoLocal
- src/lib/dates.test.ts (20 tests): TZ-safety, pure-date local midnight, far-future filter,
round-trip parse/format, time extraction в local TZ, clear-button (null Date → '')
- src/components/schema/types.test.ts (31 tests): buildSchemaJson всех 9 kinds + x-unique +
x-id-source, parseSchemaJson roundtrip, diffSchemas (8 breaking detection cases),
suggestVersionBump (major/minor/patch + breaking-wins-mix)
CI:
- Откатил dual resolve-tag (BACKEND/FRONTEND) на single resolve-tag.
GitLab variable interpolation в trigger jobs не подхватывает dotenv от needs-job
→ admin-ui-only push не доезжал до infra. Now backwards compat path работает
как раньше с UPSTREAM_IMAGE_TAG.
- Backend docker jobs (maven-package + 4 docker-*) теперь без rules:changes —
catch ImagePullBackOff если frontend push шёл без backend rebuild. BuildKit cache
делает повторный билд идентичных layers ~30 sec.
- Path-filter оставлен на maven-test (тесты не запускаются на frontend-only PR
— они бэкендовые) и на docker-admin-ui (frontend-only).
Run: pnpm test → 51 passed.
CI: path-filtering (наконец-то)
- Backend jobs (maven-test, maven-package, docker-app/read-api/projection-writer/migrations,
resolve-backend-tag) запускаются только при backend-changes (Java модули, pom.xml, CI yml).
- Frontend (docker-admin-ui, resolve-frontend-tag) — только при ordinis-admin-ui/**.
- Trigger downstream передаёт BACKEND_IMAGE_TAG и/или FRONTEND_IMAGE_TAG. Backwards
compat для старого UPSTREAM_IMAGE_TAG сохранён в infra pipeline.
- Frontend-only PR теперь не катит backend rolling update (raньше каждый push
тегал ВСЕ сервисы новым sha и роллил).
Edit dialog UX (bitemporal):
- При Edit validFrom default = now() (а не historical validFrom существующей записи).
Раньше юзер сдвигал validFrom назад → backend не находил активной версии в этот
момент → 'record_not_active'. Теперь по умолчанию 'новая версия с этого момента'.
- nowIsoLocal() в timezone браузера (с offset).
- validTo default пустой = бессрочно.
Backend: понятное сообщение для record_not_active с инструкцией.
Build только при изменениях ordinis-admin-ui/** или каждом push в main.
Использует тот же DinD pattern, push в repo.nstart.cloud/terravault/ordinis-admin-ui.
- ci: resolve UPSTREAM_IMAGE_TAG via dotenv artifact (resolve-tag job)
GitLab quirk — $IMAGE_TAG в trigger.variables не интерполируется
напрямую от upstream global vars; dotenv делает значение job-local,
тогда interpolation работает.
- projection-writer: management.server.port=8082 + web-application-type=none
Возврат actuator/health probes — Spring Boot non-web app не имеет
HTTP сервера; вынесли actuator на отдельный management server.
- docker-compose.yml: локальный dev-стек (PG + Kafka + Redis + 3 services)
через repo.nstart.cloud/terravault images. Включается профилем 'dev'.
Switch to the working pattern provided by infra team:
- image: repo.nstart.cloud/nstart/docker-cli-buildx:1.0.0 (corp-built
client with proper Harbor credentials baked in / runner-friendly)
- service: docker:29.1.2-dind (matches runner-tested version)
- explicit --tls=false + DOCKER_HOST=tcp://docker:2375 + DOCKER_TLS_CERTDIR=''
The earlier docker:26 + custom TLS attempts hit shared-volume issues
specific to this runner setup.
GitLab CI YAML <<: doesn't deep-merge — per-job 'variables:' overwrites
the anchor's variables block, so DOCKER_HOST/DOCKER_TLS_CERTDIR were
lost and the docker client fell back to default tcp://docker:2375 (no
TLS). 'extends:' merges variables key-by-key, so per-job SVC/DOCKERFILE
add to the base instead of replacing it.
Non-TLS DinD on tcp://docker:2375 had a race where docker login succeeded
but the next command got 'Cannot connect to the Docker daemon'. Switch
to the documented TLS pattern with DOCKER_TLS_CERTDIR=/certs and
DOCKER_HOST=tcp://docker:2376 — both client and DinD share /certs via
the implicit volume.
Single registry for all clusters — staging (161), prod (142), local dev.
- Removed registry.k8s.265.nstart.local (no longer needed)
- Removed --insecure-registry flag from DinD service
- Wait-loop for DinD readiness before docker login (fixes race that
caused 'Cannot connect to the Docker daemon' on first build command)
- Inlined docker login into the publish_script (kept tied to the build,
not a separate before_script that ran before DinD was ready)
Prod cluster (192.168.100.142) cannot reach the local staging registry
registry.k8s.265.nstart.local. The corp Harbor at repo.nstart.cloud is
the shared image source — push there in addition to the staging-internal
registry so both clusters can pull.
- Added EXTERNAL_REGISTRY=repo.nstart.cloud
- before_script does docker login $EXTERNAL_REGISTRY (REGISTRY_USER /
REGISTRY_PASSWORD already set as group-level CI variables)
- Refactored 4 nearly identical docker-* jobs into a shared
.dual_push_script anchor; per-job vars (SVC, DOCKERFILE, BUILD_CONTEXT)
- Build once with both registry tags, push to both
- 0001-extensions.xml: переставил <preConditions> перед <comment> (XSD требует
preConditions первым в changeSet)
- master.xml: include paths сделаны relative к самому master.xml (changes/...
вместо db/changelog/changes/...) — CWD inside Docker image это /liquibase,
Liquibase searchPath = /liquibase/changelog где master.xml лежит, includes
должны идти от него
CI: insecure-registry: registry.k8s.265.nstart.local (HTTP без auth для
internal cluster), REGISTRY_USER/PASSWORD optional (skip docker login если
не заданы)