Переиспользование конфигураций, шаблоны, DAG pipelines, parent-child.
Продвинутые возможности GitLab CI позволяют создавать модульные и эффективные пайплайны. Изучите переиспользование конфигураций, шаблоны и DAG-пайплайны.
include позволяет импортировать внешние конфигурации для переиспользования кода.
# 1. Локальный файл
include:
- local: '/templates/build.yml'
# 2. Файл в другом проекте
include:
- project: 'group/shared-templates'
file: '/templates/build.yml'
ref: main # Ветка, тег или commit SHA
# 3. Удалённый файл по URL
include:
- remote: 'https://example.com/gitlab-ci-templates/build.yml'
# 4. Template (встроенные шаблоны GitLab)
include:
- template: Auto-DevOps.gitlab-ci.yml
# 5. Inline конфигурация
include:
- local: '.gitlab-ci-base.yml'
# 6. Несколько включений
include:
- local: '/templates/build.yml'
- local: '/templates/test.yml'
- project: 'group/shared-templates'
file: '/templates/deploy.yml'
ref: v1.0.0include:
- local: '/templates/base.yml'
- local: '/templates/overrides.yml'
# Конфигурации обрабатываются сверху вниз
# Поздние include могут переопределять ранниеВажно:
Структура проекта:
.gitlab-ci.yml
.gitlab/
├── build.yml
├── test.yml
└── deploy.yml
Основной файл .gitlab-ci.yml:
include:
- local: '.gitlab/build.yml'
- local: '.gitlab/test.yml'
- local: '.gitlab/deploy.yml'
variables:
PROJECT_NAME: "my-app"Файл .gitlab/build.yml:
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/Стандартный YAML синтаксис для переиспользования:
.base_config: &base_config
image: node:20-alpine
before_script:
- npm ci
tags:
- docker
lint:
<<: *base_config
script:
- npm run lint
test:
<<: *base_config
script:
- npm test
build:
<<: *base_config
script:
- npm run build
artifacts:
paths:
- dist/GitLab игнорирует jobs, начинающиеся с точки:
.base_job:
image: node:20-alpine
before_script:
- npm ci
tags:
- docker
interruptible: true
lint:
extends: .base_job
script:
- npm run lint
test:
extends: .base_job
script:
- npm testextends наследует конфигурацию из другого job:
.base_test:
image: node:20-alpine
before_script:
- npm ci
script:
- npm test
artifacts:
reports:
junit: junit.xml
unit-test:
extends: .base_test
script:
- npm run test:unit
artifacts:
reports:
junit: unit-junit.xml
integration-test:
extends: .base_test
script:
- npm run test:integration
artifacts:
reports:
junit: integration-junit.xml.base:
image: node:20-alpine
tags:
- docker
interruptible: true
.node_template:
extends: .base
before_script:
- npm ci
.test_template:
extends: .node_template
script:
- npm test
artifacts:
reports:
junit: junit.xml
unit-test:
extends: .test_template
script:
- npm run test:unitПорядок наследования:
.base → базовая конфигурация.node_template → наследует .base + добавляет before_script.test_template → наследует .node_template + добавляет script и artifactsunit-test → наследует .test_template + переопределяет script.base:
image: node:20-alpine
variables:
NODE_ENV: development
LOG_LEVEL: info
script:
- echo "Base script"
after_script:
- echo "Cleanup"
child:
extends: .base
variables:
NODE_ENV: production # Переопределяет
DEBUG: true # Добавляет новую
script:
- echo "Child script" # Полностью переопределяет
# after_script наследуетсяDAG позволяет jobs запускаться сразу после завершения зависимостей, а не ждать весь stage.
stages:
- build
- test
- deploy
build-frontend:
stage: build
script:
- npm run build:frontend
build-backend:
stage: build
script:
- npm run build:backend
test-frontend:
stage: test
script:
- npm run test:frontend
needs:
- build-frontend
test-backend:
stage: test
script:
- npm run test:backend
needs:
- build-backend
deploy:
stage: deploy
script:
- ./deploy.sh
needs:
- test-frontend
- test-backendБез DAG: deploy ждёт завершения всех test jobs С DAG: deploy запускается сразу после test-frontend и test-backend
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
test:
stage: test
script:
- npm test
needs:
- job: build
artifacts: true # Скачать артефакты
deploy:
stage: deploy
script:
- ./deploy.sh
needs:
- job: build
artifacts: true
- job: test
artifacts: false # Не нужны артефакты из testdeploy:
stage: deploy
script:
- ./deploy.sh
needs:
- job: test-optional
optional: true # Продолжить даже если test-optional failed
- job: test-required
optional: false # Требуется успех (по умолчанию)stages:
- prepare
- build
- test
- deploy
prepare:
stage: prepare
script:
- echo "Preparing..."
build-a:
stage: build
script:
- echo "Building A"
needs:
- prepare
build-b:
stage: build
script:
- echo "Building B"
needs:
- prepare
test-a:
stage: test
script:
- echo "Testing A"
needs:
- build-a
test-b:
stage: test
script:
- echo "Testing B"
needs:
- build-b
test-integration:
stage: test
script:
- echo "Integration testing"
needs:
- build-a
- build-b
deploy:
stage: deploy
script:
- ./deploy.sh
needs:
- test-a
- test-b
- test-integrationtrigger запускает отдельный pipeline в другом проекте или том же проекте.
# Parent pipeline
trigger_child:
stage: deploy
trigger:
project: group/child-project
branch: maindeploy:
stage: deploy
trigger:
project: group/deployment-pipeline
branch: main
variables:
ENVIRONMENT: production
VERSION: $CI_COMMIT_TAG# Запуск другого .gitlab-ci.yml в том же проекте
deploy_pipeline:
stage: deploy
trigger:
project: $CI_PROJECT_PATH
branch: $CI_COMMIT_BRANCH
variables:
DEPLOY_TARGET: production# Ждать завершения child pipeline
deploy:
stage: deploy
trigger:
project: group/deploy-pipeline
strategy: depend # Parent ждёт child
# Не ждать завершения
deploy_async:
stage: deploy
trigger:
project: group/deploy-pipeline
strategy: none # Parent не ждёт childdeploy_staging:
stage: deploy
trigger:
project: group/deploy-pipeline
branch: main
variables:
ENVIRONMENT: staging
rules:
- if: $CI_COMMIT_BRANCH == "develop"
deploy_production:
stage: deploy
trigger:
project: group/deploy-pipeline
branch: main
variables:
ENVIRONMENT: production
rules:
- if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/
when: manualParent Pipeline (.gitlab-ci.yml)
├── build_job
├── test_job
└── trigger: child_pipeline
└── Child Pipeline (.gitlab/deploy.yml)
├── deploy_staging
└── deploy_production
Parent: .gitlab-ci.yml (CI часть):
stages:
- build
- test
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
test:
stage: test
script:
- npm test
needs:
- build
# Запуск CD pipeline только для main
cd_pipeline:
stage: test
trigger:
project: $CI_PROJECT_PATH
branch: $CI_COMMIT_BRANCH
strategy: depend
rules:
- if: $CI_COMMIT_BRANCH == "main"Child: .gitlab/cd.yml (CD часть):
stages:
- deploy
deploy_staging:
stage: deploy
script:
- ./deploy.sh staging
environment:
name: staging
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual# Parent
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
trigger_child:
stage: deploy
trigger:
project: $CI_PROJECT_PATH
file: .gitlab/cd.yml
variables:
PARENT_PIPELINE_ID: $CI_PIPELINE_IDВ child pipeline артефакты parent не доступны напрямую. Для передачи используйте:
Структура:
.gitlab-ci.yml
.gitlab/
├── templates/
│ ├── base.yml
│ ├── node.yml
│ └── test.yml
├── jobs/
│ ├── build.yml
│ ├── test.yml
│ └── deploy.yml
.gitlab/templates/base.yml:
.base_job:
interruptible: true
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure.gitlab/templates/node.yml:
include:
- local: '.gitlab/templates/base.yml'
.node_base:
extends: .base_job
image: node:20-alpine
before_script:
- npm ci
cache:
paths:
- node_modules/.gitlab/jobs/build.yml:
include:
- local: '.gitlab/templates/node.yml'
build:
extends: .node_base
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 weekОсновной .gitlab-ci.yml:
stages:
- build
- test
- deploy
include:
- local: '.gitlab/jobs/build.yml'
- local: '.gitlab/jobs/test.yml'
- local: '.gitlab/jobs/deploy.yml'
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCHstages:
- prepare
- build
- test
- security
- deploy
prepare:
stage: prepare
script:
- echo "Setting up..."
artifacts:
paths:
- .npmrc
build-frontend:
stage: build
script:
- cd frontend && npm run build
needs:
- prepare
artifacts:
paths:
- frontend/dist/
build-backend:
stage: build
script:
- cd backend && npm run build
needs:
- prepare
artifacts:
paths:
- backend/dist/
build-mobile:
stage: build
script:
- cd mobile && npm run build
needs:
- prepare
artifacts:
paths:
- mobile/build/
test-frontend:
stage: test
script:
- cd frontend && npm test
needs:
- job: build-frontend
artifacts: false
test-backend:
stage: test
script:
- cd backend && npm test
needs:
- job: build-backend
artifacts: false
test-e2e:
stage: test
script:
- npm run test:e2e
needs:
- build-frontend
- build-backend
security-scan:
stage: security
script:
- npm audit
- npm run security:check
needs:
- build-backend
allow_failure: true
deploy-staging:
stage: deploy
script:
- ./deploy.sh staging
needs:
- test-frontend
- test-backend
- test-e2e
environment:
name: staging
rules:
- if: $CI_COMMIT_BRANCH == "develop"
deploy-production:
stage: deploy
script:
- ./deploy.sh production
needs:
- test-frontend
- test-backend
- test-e2e
- security-scan
environment:
name: production
rules:
- if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/
when: manual.name: игнорируются GitLabneeds для параллелизацииВопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.