GitLab CI/CD
Каноническая схема delivery pipeline проекта. Pipeline оптимизирован под
быстрые итерации на main, но сохраняет fail-closed зависимости артефактов и
production deploy.
Платформа
- SCM и CI/CD: GitLab.
- Web-документация: GitLab Pages.
- Release notes: GitLab Release +
git-cliff. - Build runner:
ci-build. - Deploy runner:
ci-deploy. - E2E runner:
ci-e2e. - DB BuildKit runner:
ci-build-db, выключен по умолчанию черезCI_DB_BUILDER_ENABLED=0.
Критический путь default pipeline
flowchart LR HB["disk-hygiene-build"] HD["disk-hygiene-deploy<br/>needs: []"] HE["disk-hygiene-e2e<br/>needs: []"] subgraph verify["verify"] DOCS["docs gates"] COMPOSE["compose-validate"] BACKEND["backend-checks<br/>ordinary go test"] ARCH["backend-archlint"] PROVIDERS["backend-provider-contract"] FRONT["frontend / landing gates"] end subgraph build["build"] PAGES["pages / docs-build"] WORKER["build-workers"] AUTH["build-auth"] UI["build-frontends"] end subgraph deploy["deploy"] DB["deploy-db-vps<br/>migrations unchanged"] APP["deploy-production"] EDGE["edge-deploy"] end RACE["backend-race<br/>hygiene, non-blocking"] QA["qa:e2e<br/>manual"] HB --> DOCS HB --> BACKEND DOCS --> PAGES COMPOSE --> WORKER BACKEND --> WORKER ARCH --> WORKER PROVIDERS --> WORKER WORKER --> AUTH --> UI FRONT --> UI HD --> DB WORKER --> DB HD --> APP PAGES --> APP UI --> APP DB --> APP HD --> EDGE UI --> EDGE HE --> QA APP -. "не блокирует deploy" .-> RACE
needs заменяет общий stage barrier только там, где зависимости доказаны.
Падение существующего relevant gate по-прежнему блокирует его artifact
consumer. optional: true означает только, что path-based job может
отсутствовать; если такой job создан и упал, consumer не стартует.
Стадии
| Стадия | Назначение |
|---|---|
prepare | Hygiene только build-runner перед его verify/build jobs. |
verify | Форматирование, lint, compose, быстрые backend и frontend gates. |
test | Ручные integration/E2E jobs и независимый hygiene E2E-runner. |
build | Docs и production images; docs могут идти параллельно с worker path. |
deploy | Независимый deploy hygiene, DB-VPS deploy, App-VPS и edge deploy. |
release | Release notes и GitLab Release для semver tags. |
hygiene | Post-deploy cleanup и полный non-blocking backend race. |
Тяжёлые Docker builds не запускаются параллельно: worker, auth и frontend
сохраняют общий resource_group: ci-build-docker. Параллельность используется
для docs, проверок и runner-specific hygiene, которые не конкурируют за этот
Docker daemon.
Backend gates
Blocking backend-checks
Обязательный backend gate выполняет:
gofmtcheck;go vet ./...;errorlint,layerlint,openapilint;go test -p 3 ./....
vet и ordinary tests используют один job-local GOCACHE. Между ними нельзя
добавлять go clean -cache -testcache: это уничтожит уже оплаченный compile
cache. Значение -p 3 использует половину 6-core runner и оставляет запас для
параллельного verify job; на production runner при таком профиле доступно около
4 GiB RAM. GOCACHE не переносится между jobs, потому что race artifacts ранее
занимали несколько гигабайт и заполняли runner disk.
Non-blocking backend-race
Полный прогон выполняет:
go test -race -p 2 ./... -coverprofile=coverage.out
go tool cover -func=coverage.out | tail -n 1На main, в MR и scheduled pipeline job доступен вручную с
allow_failure: true и interruptible: true. Поэтому обычный push не занимает
один из двух слотов build-runner ещё на 7–9 минут. Перед ручным запуском
ci-main-freshness.sh завершает устаревший pipeline без компиляции.
Не включайте automatic GitLab schedule на main только ради race: production
build и deploy rules тоже совпадут с default branch, поэтому такой schedule
может повторно выкатить production. Пока schedule не изолирован отдельным
pipeline config, запускайте backend-race вручную из нужного pipeline.
Параллельные docs и build
pages и docs-build находятся в стадии build и ждут только:
disk-hygiene-build;markdownlint;docs-governance;docs-mermaid;plans-lint.
Worker producer независимо ждёт compose, backend-checks, architecture и
provider-contract gates. Поэтому Quartz build больше не создаёт минутный
барьер перед worker image build. При этом deploy-production явно ждёт
pages, и сломанная документация не попадает в production deploy.
Runner-specific disk hygiene
Один hidden template .disk-hygiene содержит прежние prune-команды и пороги.
Его используют три именованных job:
| Job | Runner | Поведение |
|---|---|---|
disk-hygiene-build | ci-build | prepare; gate для build-runner jobs. |
disk-hygiene-deploy | ci-deploy | deploy, needs: []; gate только deploy consumers. |
disk-hygiene-e2e | ci-e2e | test, needs: []; gate только qa:e2e. |
Очередь или длинная job на ci-deploy больше не держит backend checks, docs и
worker build в created. Prune policy не стала агрессивнее: изменены только
DAG edges.
Auth image reuse
build-auth клонирует AUTH_REF и вычисляет точный commit внешнего
репозитория. Source cache tag имеет вид:
auth-source-v1-<AUTH_COMMIT>-<UTC_YEAR>-W<UTC_WEEK>Если tag существует в 192.168.1.85:5001/tracium/auth, helper
scripts/ci-registry-retag.sh читает schema-2/OCI manifest через Registry V2
API и записывает тот же manifest в $CI_COMMIT_SHA и latest. Слои не
скачиваются, DinD не делает docker pull, Go toolchain не собирается.
При 404, сетевой ошибке, неизвестном Content-Type или failed target PUT job
переходит к полному Docker build. Fallback публикует immutable Tracium SHA,
source cache tag и только затем latest. Недельный epoch принудительно
обновляет mutable base images хотя бы раз в неделю.
Next.js image reuse
landing-ui и admin-ui нельзя переиспользовать только по git diff:
NEXT_PUBLIC_* встраиваются в browser bundle и могут быть переопределены
GitLab variables. scripts/ci-frontend-source-tag.sh поэтому вычисляет
content-addressed tag из Git object ID всех Docker inputs, хэшей фактических
build args и недельного UTC epoch.
При совпадении build-frontends копирует manifest source-tag в текущий SHA и
latest через Registry V2, не скачивая слои и не выполняя next build. Cache
miss или любая ошибка registry остаётся fail-safe fallback: полный Docker
build публикует SHA, source-tag и затем latest. Значения build args в лог не
выводятся.
Миграции и большая production DB
Эта оптимизация не изменяет migration image, команды, timeout или порядок.
deploy-db-vps по-прежнему:
- ждёт готовый worker image и hygiene
ci-deploy; - применяет миграции на DB-VPS;
- завершает worker rollout;
- только после успеха разрешает
deploy-production.
Длинная миграция остаётся fail-closed и не прерывается ради ускорения. Тяжёлые production health queries также не распараллеливаются, чтобы не увеличивать I/O contention большой базы.
Триггеры
Merge Request
Path-based verify jobs запускаются для изменённых компонентов. Full race, integration и E2E доступны вручную и не блокируют обычную итерацию.
Default branch
Relevant verify gates, production images, Pages и deploy запускаются автоматически. Stale checks не дают старому pipeline перезаписать более новый release.
Tag
Semver tags vX.Y.Z валидируют VERSION, создают release notes и GitLab
Release. Production image builders сохраняют immutable tag/commit artifacts.
Требования к runners
ci-build: Docker/DinD и доступ к LAN registry192.168.1.85:5001.ci-deploy: Docker socket, host mounts production runtime и SSH-доступ к DB-VPS черезRUNNER_DEPLOY_SSH_KEY.ci-e2e: изолированный DinD для compose/Playwright.- Git history без shallow limit (
GIT_DEPTH=0) для freshness/release checks. gitиcurlв auth/deploy jobs.
Rollback
Один revert CI-коммитов возвращает прежние race rules и stage barriers. Immutable SHA images в LAN registry остаются доступны; rollback CI не требует rollback production runtime или базы. Миграции нельзя откатывать как часть этого CI rollback.