Пример готового .gitlab-ci.yml
Структура пайплайна
Includes
Подключаем шаблоны из generic/common-ci:
include:
- project: 'generic/common-ci'
file: '/common-security-scan.yaml'
- project: 'generic/common-ci'
file: '/universal-pipeline.yaml'
ref: apps-business
Примечание: ref: apps-business — ветка с актуальной версией шаблона. После стабилизации можно убрать.
Глобальные переменные
variables:
SERVICE_NAME: bi-backend
DOCKERFILE_PATH: ./docker/Dockerfile
BUILD_ARGS: ""
CI_TRIGGER_SOURCE: app
SERVICE_NAME— имя сервиса, используется дляRELEASE_NAMEиCHART_NAMEDOCKERFILE_PATH— путь к DockerfileBUILD_ARGS— дополнительные аргументы для docker buildCI_TRIGGER_SOURCE— источник триггера (app/infra)
Workflow.rules и переменные
Workflow определяет переменные для каждой ветки/тега:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
# Stage environment
- if: '$CI_COMMIT_BRANCH == "stage"'
variables:
STAND: stage
NAMESPACE: planning
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-stage"
K8S_HUSTLER_BRANCH: universal-chart-stage
HELM_SET_ARGS: >-
--set universal-chart.services.main.image.name.stage=${IMAGE_NAME}
--set universal-chart.global.env=stage
--set universal-chart.services.main.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.main.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.main.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.main.owner=${CI_PROJECT_NAMESPACE}
# Preprod environment
- if: '$CI_COMMIT_BRANCH == "master"'
variables:
STAND: preprod
NAMESPACE: bi-preprod
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-preprod"
K8S_HUSTLER_BRANCH: universal-chart-preprod
HELM_SET_ARGS: >-
--set universal-chart.services.main.image.name.preprod=${IMAGE_NAME}
--set universal-chart.global.env=preprod
--set universal-chart.services.main.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.main.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.main.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.main.owner=${CI_PROJECT_NAMESPACE}
# Production environment
- if: '$CI_COMMIT_TAG'
variables:
STAND: production
NAMESPACE: bi-prod
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-prod"
K8S_HUSTLER_BRANCH: universal-chart-production
HELM_SET_ARGS: >-
--set universal-chart.services.main.image.name.production=${IMAGE_NAME}
--set universal-chart.global.env=production
--set universal-chart.services.main.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.main.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.main.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.main.owner=${CI_PROJECT_NAMESPACE}
- when: never
Ключевые моменты
- Путь к образу:
universal-chart.services.<service>.image.name.<env> - Для backend:
universal-chart.services.main.image.name.stage -
Для frontend:
universal-chart.services.frontend.image.name.stage -
Метаданные: передаются для каждого сервиса
commitSha— SHA коммитаgitlabUri— URL репозиторияgitlabJobUrl— URL джобы-
owner— namespace проекта -
global.env: обязательно устанавливать для выбора значений через
pluckEnv
Кастомные джобы
После includes можно добавить свои джобы:
# =============================================================================
# LINT & TESTS AND OTHER CUSTOM JOBS
# =============================================================================
lint:
stage: lint
image: ghcr.io/astral-sh/uv:0.7.3-python3.13-bookworm-slim
script:
- uv sync --locked
- uv run ruff check src
- uv run ruff format src --check
rules:
- if: '$CI_COMMIT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
typecheck:
stage: lint
image: ghcr.io/astral-sh/uv:0.7.3-python3.13-bookworm-slim
script:
- uv sync --locked
- uv run mypy src
rules:
- if: '$CI_COMMIT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
allow_failure: true
Полный пример для backend
include:
- project: 'generic/common-ci'
file: '/common-security-scan.yaml'
- project: 'generic/common-ci'
file: '/universal-pipeline.yaml'
ref: apps-business
variables:
SERVICE_NAME: bi-backend
DOCKERFILE_PATH: ./docker/Dockerfile
BUILD_ARGS: ""
CI_TRIGGER_SOURCE: app
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == "stage"'
variables:
STAND: stage
NAMESPACE: planning
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-stage"
K8S_HUSTLER_BRANCH: universal-chart-stage
HELM_SET_ARGS: >-
--set universal-chart.services.main.image.name.stage=${IMAGE_NAME}
--set universal-chart.global.env=stage
--set universal-chart.services.main.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.main.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.main.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.main.owner=${CI_PROJECT_NAMESPACE}
- if: '$CI_COMMIT_BRANCH == "master"'
variables:
STAND: preprod
NAMESPACE: bi-preprod
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-preprod"
K8S_HUSTLER_BRANCH: universal-chart-preprod
HELM_SET_ARGS: >-
--set universal-chart.services.main.image.name.preprod=${IMAGE_NAME}
--set universal-chart.global.env=preprod
--set universal-chart.services.main.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.main.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.main.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.main.owner=${CI_PROJECT_NAMESPACE}
- if: '$CI_COMMIT_TAG'
variables:
STAND: production
NAMESPACE: bi-prod
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-prod"
K8S_HUSTLER_BRANCH: universal-chart-production
HELM_SET_ARGS: >-
--set universal-chart.services.main.image.name.production=${IMAGE_NAME}
--set universal-chart.global.env=production
--set universal-chart.services.main.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.main.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.main.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.main.owner=${CI_PROJECT_NAMESPACE}
- when: never
lint:
stage: lint
image: ghcr.io/astral-sh/uv:0.7.3-python3.13-bookworm-slim
script:
- uv sync --locked
- uv run ruff check src
- uv run ruff format src --check
rules:
- if: '$CI_COMMIT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
Полный пример для frontend
include:
- project: 'generic/common-ci'
file: '/common-security-scan.yaml'
- project: 'generic/common-ci'
file: '/universal-pipeline.yaml'
ref: apps-business
variables:
SERVICE_NAME: bi-frontend
DOCKERFILE_PATH: ./Dockerfile
BUILD_ARGS: ""
CI_TRIGGER_SOURCE: app
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == "stage"'
variables:
STAND: stage
NAMESPACE: planning
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-stage"
K8S_HUSTLER_BRANCH: universal-chart-stage
BUILD_ARGS: "--build-arg ENDPOINT=stage --build-arg NPM_NEXUS_TOKEN=${NPM_NEXUS_TOKEN}"
HELM_SET_ARGS: >-
--set universal-chart.services.frontend.image.name.stage=${IMAGE_NAME}
--set universal-chart.global.env=stage
--set universal-chart.services.frontend.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.frontend.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.frontend.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.frontend.owner=${CI_PROJECT_NAMESPACE}
- if: '$CI_COMMIT_BRANCH == "master"'
variables:
STAND: preprod
NAMESPACE: bi-preprod
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-preprod"
K8S_HUSTLER_BRANCH: universal-chart-preprod
BUILD_ARGS: "--build-arg ENDPOINT=preprod --build-arg NPM_NEXUS_TOKEN=${NPM_NEXUS_TOKEN}"
HELM_SET_ARGS: >-
--set universal-chart.services.frontend.image.name.preprod=${IMAGE_NAME}
--set universal-chart.global.env=preprod
--set universal-chart.services.frontend.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.frontend.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.frontend.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.frontend.owner=${CI_PROJECT_NAMESPACE}
- if: '$CI_COMMIT_TAG'
variables:
STAND: production
NAMESPACE: bi-prod
RELEASE_NAME: ${SERVICE_NAME}
CHART_NAME: ${SERVICE_NAME}
CHART_VERSION: "0.0.1-prod"
K8S_HUSTLER_BRANCH: universal-chart-production
BUILD_ARGS: "--build-arg ENDPOINT=prod --build-arg NPM_NEXUS_TOKEN=${NPM_NEXUS_TOKEN}"
HELM_SET_ARGS: >-
--set universal-chart.services.frontend.image.name.production=${IMAGE_NAME}
--set universal-chart.global.env=production
--set universal-chart.services.frontend.commitSha=${CI_COMMIT_SHA}
--set universal-chart.services.frontend.gitlabUri=${CI_PROJECT_URL}
--set universal-chart.services.frontend.gitlabJobUrl=${CI_JOB_URL}
--set universal-chart.services.frontend.owner=${CI_PROJECT_NAMESPACE}
- when: never
Обратите внимание: для frontend используется services.frontend, а не services.main.