# ============================================================= # Ordinis — build & push images. # Path-aware CI: backend и frontend jobs запускаются только когда меняются # соответствующие пути. Trigger downstream передаёт BACKEND_IMAGE_TAG и/или # FRONTEND_IMAGE_TAG; infra-pipeline применяет helm upgrade с per-service # overrides — сервисы которые не пересобирались не катятся. # ============================================================= stages: - test - build - publish - trigger-deploy - release variables: MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn" MAVEN_CLI_OPTS: "-B -ntp --batch-mode" IMAGE_TAG: $CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA REGISTRY: repo.nstart.cloud IMAGE_REPO: nstart/terravault DOCKER_BUILDKIT: "1" cache: key: files: ["pom.xml"] paths: - .m2/repository default: # Pin builds to nstart-tagged runners. Без тегов job'ы попадали в shared # pool и в часы пик висели по 20+ мин в waiting_for_resource (см. # pipeline 6553 docker-app — 1464s до cancel). Tag nstart берёт наши # выделенные runners. tags: - nstart retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure - script_failure # Backend changes триггерят maven + docker для всех Java-сервисов + миграции. .backend-changes: &backend-changes - "ordinis-app/**/*" - "ordinis-read-api/**/*" - "ordinis-projection-writer/**/*" - "ordinis-rest-api/**/*" - "ordinis-domain/**/*" - "ordinis-validation/**/*" - "ordinis-events-api/**/*" - "ordinis-outbox/**/*" - "ordinis-auth/**/*" - "ordinis-cuod-bundle/**/*" - "ordinis-migrations/**/*" - "pom.xml" - ".gitlab-ci.yml" # Frontend changes — только admin-ui. .frontend-changes: &frontend-changes - "ordinis-admin-ui/**/*" # Documentation changes — Diplodoc-built integrator guide. # docs-internal/ исключено явно: оно НЕ build'ится Diplodoc'ом и не должно # триггерить docs job. .docs-changes: &docs-changes - "docs/**/*" # ─── LINT ────────────────────────────────────── # Commit-message lint: ловит literal `[skip ci]` в subject/body. # # Контекст trap'ы: # 1. semantic-release auto-генерирует release notes из commit'ов с момента # последнего tag'а — включает subject + body всех commit'ов. # 2. Если хотя бы один из этих commit'ов содержит литеральное `[skip ci]` # (даже описывая что фиксят его, e.g. 'fix: remove [skip ci] из...'), # эта строка попадает в release commit body. # 3. Release commit body содержит `[skip ci]` → GitLab матчит → пропускает # tag pipeline (semantic-release/gitlab plugin создаёт tag, но pipeline # на этот tag-ref скипается). # 4. Без tag pipeline нет images → нет commit-prod-image-bump → нет # bump'а в infra → manual escape потребуется. # # Реальный случай: v2.16.1 (2026-05-12) — fix(release): 'remove [skip ci] из # semantic-release commit message'. Auto-changelog содержал эту строку → # v2.16.1 tag pipeline skipped → пришлось trigger вручную через API. # # Защита: fail CI на любом commit'е (subject ИЛИ body) который содержит # substring `[skip ci]`. Когда нужно реально skip — использовать иные # формулировки: `skip-ci marker`, `the skip-ci directive`, etc. # # Не блокирует chore(release) commit'ы semantic-release'а потому что # .releaserc.json message template уже не содержит `[skip ci]` (MR !154). # # Skipping этот job сам: rules ниже исключают chore(release) commit'ы # (subject matches 'chore(release):' regex), потому что body этих commit'ов # содержит весь changelog со всеми историческими commit'ами — false positive. commit-msg-lint: stage: test # alpine/git: git + grep (busybox) + ca-certs pre-installed, никакого # `apk add` не нужно. Раньше использовали alpine:3.20 + apk install, но # Nexus alpine mirror (`repo.nstart.cloud/repository/alpine/...`) даёт # IO ERROR на v3.20 APKINDEX (см. pipeline 14917). До починки mirror'а # — используем pre-baked image. entrypoint: [""] сбрасывает ENTRYPOINT=["git"] # этого image — иначе runner выполняет `git