Урок 5-8: Advanced pipeline и production patterns
Часть 1: Rules и условное выполнение
Basic Rules
# Запустить только на main branch
deploy_prod:
stage: deploy
script:
- ./deploy.sh production
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
# Запустить на любом branch КРОМЕ main
test_job:
stage: test
script:
- npm test
rules:
- if: '$CI_COMMIT_BRANCH != "main"'
# Запустить только для merge request
review_job:
stage: test
script:
- echo "Code review..."
rules:
- if: '$CI_MERGE_REQUEST_IID'
Kompleksni rules
deploy_job:
stage: deploy
script:
- echo "Deploying..."
rules:
# На main запускаем deploy в production
- if: '$CI_COMMIT_BRANCH == "main"'
variables:
DEPLOY_ENV: "production"
# На develop запускаем deploy в staging
- if: '$CI_COMMIT_BRANCH == "develop"'
variables:
DEPLOY_ENV: "staging"
# На других branches не запускаем
- when: never
Часть 2: Predefined Variables (встроенные переменные)
Основные переменные
$CI_COMMIT_BRANCH # develop, main, test
$CI_COMMIT_SHA # c6435860...
$CI_COMMIT_SHORT_SHA # c6435860
$CI_PROJECT_NAME # my-project
$CI_PROJECT_ID # 12345
$CI_JOB_NAME # build_job
$CI_JOB_ID # 98765
$CI_PIPELINE_ID # 54321
$CI_MERGE_REQUEST_IID # 1 (если merge request)
Использование в scripts
default:
image: ubuntu:20.04
variables:
LOG_FILE: "logs/${CI_COMMIT_BRANCH}-${CI_COMMIT_SHORT_SHA}.log"
build_job:
stage: build
script:
- echo "Branch: $CI_COMMIT_BRANCH"
- echo "Commit: $CI_COMMIT_SHA"
- echo "Job: $CI_JOB_NAME"
- echo "Pipeline: $CI_PIPELINE_ID"
- mkdir -p logs
- echo "Build log" > $LOG_FILE
artifacts:
paths:
- logs/
Часть 3: Matrix (Множественное выполнение)
Параллельные выполнения с разными переменными
test_job:
stage: test
script:
- echo "Testing on $OS_NAME with $NODE_VERSION"
parallel:
matrix:
- OS_NAME: ["ubuntu", "debian", "centos"]
NODE_VERSION: ["14", "16", "18"]
# Создаст 9 jobs:
# test_job[ubuntu-14], test_job[ubuntu-16], ...
# test_job[debian-14], test_job[debian-16], ...
# test_job[centos-14], test_job[centos-16], ...
Часть 4: Environment и Deployment
Обозначение environments
deploy_staging:
stage: deploy
environment:
name: staging
url: https://staging.example.com
deployment_tier: staging
script:
- ./deploy.sh staging
deploy_production:
stage: deploy
environment:
name: production
url: https://example.com
deployment_tier: production
script:
- ./deploy.sh production
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
Protected environments
deploy_production:
stage: deploy
environment:
name: production
script:
- ./deploy.sh production
needs: ["test_job"] # Должны пройти тесты
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual # Ручной запуск только
Часть 5: Only/Except (старый синтаксис)
# Современный способ - Rules
deploy_job:
stage: deploy
script:
- ./deploy.sh
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
# Старый способ - Only/Except (не рекомендуется)
# deploy_job:
# stage: deploy
# script:
# - ./deploy.sh
# only:
# - main
Часть 6: Before/After scripts
Default before/after
default:
before_script:
- echo "Setting up..."
- npm install
after_script:
- echo "Cleaning up..."
build_job:
stage: build
script:
- npm run build
# before_script: npm install (выполнится автоматически)
# after_script: echo... (выполнится автоматически)
Job-specific before/after
deploy_job:
stage: deploy
before_script:
- apt-get update
- apt-get install -y aws-cli
script:
- aws s3 sync dist s3://my-bucket
after_script:
- echo "Deployment complete"
Часть 7: Retry и timeout
Retry - повторить job при ошибке
flaky_test:
stage: test
script:
- npm test
retry:
max: 2 # Повторить максимум 2 раза
when:
- api_failure # Если ошибка API
- runner_system_failure # Если проблема runner'а
# Job будет запущен максимум 3 раза (1 + 2 retry)
Timeout - ограничение времени
long_running_test:
stage: test
script:
- npm test
timeout: 1 hour # Максимум 1 час
Часть 8: Когда использовать when
Manual trigger
deploy_production:
stage: deploy
script:
- ./deploy.sh production
when: manual # Требует ручного запуска из UI
Delayed execution
scheduled_job:
stage: deploy
script:
- ./deploy.sh
when: delayed
start_in: 1 hour # Запустить через 1 час
Always run
cleanup_job:
stage: cleanup
script:
- rm -rf /tmp/*
when: always # Запустить в любом случае
Часть 9: Production-ready pipeline
Полный пример
stages:
- build
- test
- deploy_dev
- deploy_prod
variables:
DOCKER_IMAGE: registry.gitlab.com/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
default:
image: docker:latest
retry:
max: 2
when: api_failure
build:
stage: build
services:
- docker:dind
script:
- docker build -t ${DOCKER_IMAGE}:${CI_COMMIT_SHORT_SHA} .
- docker push ${DOCKER_IMAGE}:${CI_COMMIT_SHORT_SHA}
rules:
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"'
test_unit:
stage: test
image: node:16
script:
- npm install
- npm test
artifacts:
paths:
- coverage/
test_integration:
stage: test
script:
- docker run ${DOCKER_IMAGE}:${CI_COMMIT_SHORT_SHA} npm run test:integration
deploy_dev:
stage: deploy_dev
environment:
name: development
url: https://dev.example.com
script:
- ./scripts/deploy.sh development ${CI_COMMIT_SHORT_SHA}
rules:
- if: '$CI_COMMIT_BRANCH == "develop"'
deploy_staging:
stage: deploy_prod
environment:
name: staging
url: https://staging.example.com
script:
- ./scripts/deploy.sh staging ${CI_COMMIT_SHORT_SHA}
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
deploy_production:
stage: deploy_prod
environment:
name: production
url: https://example.com
script:
- ./scripts/deploy.sh production ${CI_COMMIT_SHORT_SHA}
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual # Требует ручного подтверждения
Проверочный список
- [ ] Используете rules для условного выполнения
- [ ] Знаете основные predefined variables
- [ ] Используете artifacts для передачи файлов
- [ ] Используете caching для ускорения
- [ ] Знаете матриц для параллельных выполнений
- [ ] Настроили environments
- [ ] Используете retry и timeout
- [ ] Пишете production-grade pipeline'ы
Готовы? Переходите к справочнику! 🚀