Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. YAML-паттерны и лучшие практики
yaml_patterns

YAML-паттерны и лучшие практики

Структурирование YAML-конфигураций, DRY-принципы, читаемость и поддержка.

YAML-паттерны и лучшие практики

Правильная организация YAML-конфигураций критична для поддерживаемости CI/CD пайплайнов. Изучите паттерны структурирования, DRY-принципы и читаемость.

#YAML-основы для CI/CD

#Базовый синтаксис

# Комментарии начинаются с # key: value # Строки могут быть без кавычек name: My Pipeline # Или в кавычках для специальных символов message: "Hello: World" # Числа и булевы значения count: 42 enabled: true # Списки (arrays) items: - first - second - third # Или inline синтаксис items: [first, second, third] # Объекты (mappings) config: key1: value1 key2: value2

#Многострочные строки

Literal block (|) — сохраняет переносы:

script: | npm ci npm run build npm test # Эквивалентно: "npm ci\nnpm run build\nnpm test\n"

Folded block (>) — объединяет строки:

description: > This is a long description that will be folded into a single line. # Эквивалентно: "This is a long description that will be folded into a single line."

Для скриптов CI/CD используйте | — сохраняет структуру команд.

#DRY-принципы в YAML

#YAML-якоря (Anchors)

Объявление и использование:

# Объявление якоря с & .base: &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

Merge key <<: объединяет поля якоря с текущим блоком.

#Переопределение полей якоря

.base: &base image: node:20-alpine variables: NODE_ENV: development LOG_LEVEL: info script: - echo "Base" child: <<: *base variables: NODE_ENV: production # Переопределяет DEBUG: true # Добавляет новое script: - echo "Child" # Переопределяет

Важно: При использовании <<: вложенные объекты (как variables) полностью переопределяются, а не merge.

#Именованные якоря для переиспользования

# Общие настройки для всех jobs .defaults: &defaults interruptible: true retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure # Специфичные якоря .node_defaults: &node_defaults <<: *defaults image: node:20-alpine before_script: - npm ci .python_defaults: &python_defaults <<: *defaults image: python:3.11-slim before_script: - pip install -r requirements.txt lint: <<: *node_defaults script: - npm run lint test: <<: *node_defaults script: - npm test build: <<: *python_defaults script: - python setup.py build

#Шаблоны в GitLab CI

#Скрытые jobs

Jobs с именами, начинающимися с ., не добавляются в пайплайн:

# Скрытый шаблон — не выполняется .base_job: image: node:20-alpine interruptible: true retry: 2 tags: - docker # Реальный job — выполняется test: extends: .base_job script: - npm test

#extends для наследования

# Базовый шаблон .test_template: image: node:20-alpine before_script: - npm ci script: - npm test artifacts: reports: junit: junit.xml # Конкретные тесты unit: extends: .test_template script: - npm run test:unit artifacts: reports: junit: unit-junit.xml integration: extends: .test_template script: - npm run test:integration artifacts: reports: junit: integration-junit.xml e2e: extends: .test_template script: - npm run test:e2e artifacts: reports: junit: e2e-junit.xml

#Множественное наследование

.base: interruptible: true tags: - docker .node: extends: .base image: node:20-alpine before_script: - npm ci .test: extends: .node script: - npm test # Множественное наследование unit-test: extends: [.test, .custom_rules] script: - npm run test:unit

При конфликтах последний в списке имеет приоритет.

#Организация структуры файлов

#Модульный подход с include

Структура проекта:

.gitlab-ci.yml
.gitlab/
├── templates/
│   ├── base.yml
│   ├── node.yml
│   └── python.yml
├── jobs/
│   ├── build.yml
│   ├── test.yml
│   └── deploy.yml
└── workflows/
    ├── feature-branch.yml
    └── main.yml

Основной файл:

include: - local: '.gitlab/templates/base.yml' - local: '.gitlab/templates/node.yml' - local: '.gitlab/jobs/build.yml' - local: '.gitlab/jobs/test.yml' - local: '.gitlab/jobs/deploy.yml' stages: - build - test - deploy workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH

Шаблон .gitlab/templates/node.yml:

.node_base: image: node:20-alpine before_script: - npm ci cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ interruptible: true

Job .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

#Управление переменными

#Иерархия переменных

# Глобальные переменные (все jobs) variables: PROJECT_NAME: "my-app" NODE_VERSION: "20" job1: # Переменные job (переопределяют глобальные) variables: NODE_VERSION: "18" script: - echo $PROJECT_NAME # my-app - echo $NODE_VERSION # 18 job2: script: - echo $PROJECT_NAME # my-app - echo $NODE_VERSION # 20

#Переменные для окружений

variables: DOCKER_REGISTRY: registry.example.com deploy_staging: stage: deploy variables: ENVIRONMENT: staging DEPLOY_URL: https://staging.example.com script: - ./deploy.sh $ENVIRONMENT deploy_production: stage: deploy variables: ENVIRONMENT: production DEPLOY_URL: https://example.com script: - ./deploy.sh $ENVIRONMENT

#Переменные через rules

deploy: stage: deploy variables: ENVIRONMENT: development # Default script: - ./deploy.sh $ENVIRONMENT rules: - if: $CI_COMMIT_BRANCH == "develop" variables: ENVIRONMENT: staging - if: $CI_COMMIT_BRANCH == "main" variables: ENVIRONMENT: production

#Читаемость и стиль

#Именование jobs

Хорошо:

lint: script: - npm run lint test-unit: script: - npm run test:unit test-integration: script: - npm run test:integration build-frontend: script: - npm run build:frontend deploy-staging: script: - ./deploy.sh staging

Плохо:

job1: script: - npm run lint test2: script: - npm run test:unit build_job_final_v2: script: - npm run build

#Группировка related jobs

# === Build Jobs === build-frontend: stage: build script: - cd frontend && npm run build build-backend: stage: build script: - cd backend && npm run build # === Test Jobs === test-frontend: stage: test script: - cd frontend && npm test test-backend: stage: test script: - cd backend && npm test # === Deploy Jobs === deploy-staging: stage: deploy script: - ./deploy.sh staging deploy-production: stage: deploy script: - ./deploy.sh production

#Комментарии для документации

# Pipeline для сборки и деплоя приложения # Автор: DevOps Team # Последнее обновление: 2026-03-20 stages: - build # Сборка артефактов - test # Запуск тестов - deploy # Деплой на окружения # === Build Stage === build: stage: build # Используем Node.js 20 для совместимости image: node:20-alpine script: - npm ci - npm run build artifacts: # Сохраняем dist для последующих stages paths: - dist/ expire_in: 1 week

#Оптимизация и производительность

#Кэширование

# Глобальный cache для всех jobs cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ - .npm/ build: script: - npm ci # Использует кэш cache: policy: pull-push # По умолчанию test: script: - npm test cache: policy: pull # Только чтение кэша

#Параллелизация

# Параллельный запуск тестов test: stage: test script: - npm test parallel: matrix: - NODE_VERSION: [18, 20, 22] - OS: [ubuntu-latest, windows-latest]

#Timeout и interruptible

.defaults: interruptible: true # Можно прервать новый пайплайн timeout: 30m # Максимальное время job long-test: extends: .defaults script: - npm run test:slow

#Практический пример: полный шаблон

# === Templates === .base_job: &base_job interruptible: true retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure tags: - docker .node_job: &node_job <<: *base_job image: node:20-alpine before_script: - npm ci cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ .test_job: &test_job <<: *node_job script: - npm test artifacts: reports: junit: junit.xml expire_in: 1 week # === Stages === stages: - lint - build - test - deploy # === Jobs === lint: <<: *node_job stage: lint script: - npm run lint rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH build: <<: *node_job stage: build script: - npm run build artifacts: paths: - dist/ expire_in: 1 week rules: - if: $CI_COMMIT_BRANCH test-unit: <<: *test_job stage: test script: - npm run test:unit artifacts: reports: junit: unit-junit.xml needs: - build test-integration: <<: *test_job stage: test script: - npm run test:integration artifacts: reports: junit: integration-junit.xml needs: - build deploy-staging: <<: *base_job stage: deploy image: alpine:latest script: - apk add --no-cache curl - ./deploy.sh staging environment: name: staging url: https://staging.example.com needs: - test-unit - test-integration rules: - if: $CI_COMMIT_BRANCH == "develop" deploy-production: <<: *base_job stage: deploy image: alpine:latest script: - apk add --no-cache curl - ./deploy.sh production environment: name: production url: https://example.com needs: - test-unit - test-integration rules: - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ when: manual # === Workflow Rules === workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH - if: $CI_COMMIT_TAG

Далее: Триггеры, расписания, webhooks