Обзор GitLab CI
GitLab CI/CD встроен непосредственно в GitLab — без плагинов, без отдельного сервиса, без дополнительной настройки. Каждый репозиторий GitLab может использовать CI/CD, добавив файл .gitlab-ci.yml в корень репозитория. GitLab обнаруживает этот файл автоматически и запускает пайплайн.
Для QA-инженеров GitLab CI предлагает ряд преимуществ: нативные тестовые отчёты в merge requests, встроенный реестр контейнеров, управление окружениями и review apps для тестирования деплоев.
Структура .gitlab-ci.yml
Базовый пайплайн
stages:
- build
- test
- deploy
install:
stage: build
image: node:20
script:
- npm ci
artifacts:
paths:
- node_modules/
expire_in: 1 hour
unit-tests:
stage: test
image: node:20
script:
- npm run test:unit -- --ci --coverage
artifacts:
reports:
junit: junit-results.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
e2e-tests:
stage: test
image: mcr.microsoft.com/playwright:v1.40.0-focal
script:
- npm ci
- npx playwright test
artifacts:
when: always
paths:
- playwright-report/
- test-results/
reports:
junit: test-results/junit.xml
expire_in: 7 days
Ключевые концепции
| Концепция | Описание |
|---|---|
| stages | Упорядоченный список фаз пайплайна; jobs на одном этапе выполняются параллельно |
| image | Docker-образ для окружения job |
| script | Shell-команды для выполнения |
| artifacts | Файлы для сохранения между этапами или после пайплайна |
| rules | Условия, управляющие запуском job |
| needs | Прямые зависимости между jobs (пропуск порядка этапов) |
| services | Дополнительные Docker-контейнеры (БД, API) для job |
Services: зависимости для тестов
Services GitLab CI запускают Docker-контейнеры рядом с вашим job. Это идеально для интеграционного тестирования:
integration-tests:
stage: test
image: node:20
services:
- name: postgres:15
alias: db
- name: redis:7
alias: cache
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_pass
DATABASE_URL: "postgresql://test_user:test_pass@db:5432/test_db"
REDIS_URL: "redis://cache:6379"
script:
- npm ci
- npm run test:integration
Контейнеры сервисов доступны по именам-алиасам (db, cache) как хостнеймы внутри job.
Пайплайны для Merge Request
GitLab может запускать пайплайны специально для merge requests, отображая результаты прямо в MR:
e2e-tests:
stage: test
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
script:
- npx playwright test
artifacts:
reports:
junit: test-results/junit.xml
Результаты тестов из JUnit-отчётов отображаются как вкладка «Tests» в merge request, показывая количество успешных/упавших и детали отдельных тестов.
Параллельные и matrix jobs
Ключевое слово parallel
Разделите job между несколькими runners автоматически:
e2e-tests:
stage: test
parallel: 4
script:
- npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
GitLab автоматически устанавливает CI_NODE_INDEX (1-4) и CI_NODE_TOTAL (4), что позволяет шардировать тесты без ручной настройки.
Matrix-стратегия
e2e-tests:
stage: test
parallel:
matrix:
- BROWSER: [chromium, firefox, webkit]
image: mcr.microsoft.com/playwright:v1.40.0-focal
script:
- npx playwright test --project=$BROWSER
Кэширование
Кэшируйте зависимости между запусками пайплайна для ускорения сборок:
default:
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
policy: pull-push
Управление окружениями
Окружения GitLab позволяют отслеживать деплои и связывать их с тестированием:
deploy-staging:
stage: deploy
script:
- ./deploy.sh staging
environment:
name: staging
url: https://staging.example.com
smoke-tests:
stage: test
needs: [deploy-staging]
script:
- npx playwright test --config=smoke.config.ts
environment:
name: staging
action: verify
Упражнение: Спроектируйте пайплайн GitLab CI
Создайте .gitlab-ci.yml для веб-приложения с:
- Этапом build с установкой зависимостей
- Этапом test с unit, интеграционными (нужен PostgreSQL) и E2E-тестами параллельно
- Деплоем в staging на ветке main
- Smoke-тестами после деплоя в staging
- Тестовыми отчётами, видимыми в merge requests
Решение
stages:
- build
- test
- deploy
- verify
default:
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
install:
stage: build
image: node:20
script:
- npm ci
artifacts:
paths:
- node_modules/
expire_in: 1 hour
unit-tests:
stage: test
image: node:20
needs: [install]
script:
- npm run test:unit -- --ci --coverage
artifacts:
reports:
junit: junit-results.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
integration-tests:
stage: test
image: node:20
needs: [install]
services:
- name: postgres:15
alias: db
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test
POSTGRES_PASSWORD: test
DATABASE_URL: "postgresql://test:test@db:5432/test_db"
script:
- npm run test:integration
artifacts:
reports:
junit: integration-results.xml
e2e-tests:
stage: test
image: mcr.microsoft.com/playwright:v1.40.0-focal
needs: [install]
parallel:
matrix:
- BROWSER: [chromium, firefox, webkit]
script:
- npm ci
- npx playwright test --project=$BROWSER
artifacts:
when: always
paths:
- playwright-report/
- test-results/
reports:
junit: test-results/junit.xml
expire_in: 7 days
deploy-staging:
stage: deploy
image: alpine:latest
needs: [unit-tests, integration-tests, e2e-tests]
script:
- ./scripts/deploy-staging.sh
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
smoke-tests:
stage: verify
image: mcr.microsoft.com/playwright:v1.40.0-focal
needs: [deploy-staging]
script:
- npm ci
- npx playwright test --config=smoke.config.ts
environment:
name: staging
action: verify
rules:
- if: $CI_COMMIT_BRANCH == "main"
GitLab CI vs GitHub Actions vs Jenkins
| Возможность | GitLab CI | GitHub Actions | Jenkins |
|---|---|---|---|
| Конфигурационный файл | .gitlab-ci.yml | .github/workflows/*.yml | Jenkinsfile |
| Отчёты о тестах | Нативные в MR | Через сторонние actions | Через плагины |
| Реестр контейнеров | Встроенный | GitHub Packages | Внешний |
| Services | Нативные Docker services | Service containers | Плагин Docker |
| Parallel/Matrix | parallel + matrix | strategy.matrix | Scripted pipeline |
| Окружения | Встроенные с трекингом | Feature Environments | Ручная настройка |
| Review Apps | Встроенные | Через custom actions | Ручная настройка |
| Self-hosted | GitLab Runner | Self-hosted runners | Основная функциональность |
Лучшие практики для QA
Всегда используйте
artifacts:reports:junitдля получения результатов тестов в merge requests. Это одна из сильнейших функций GitLab CI для видимости QA.Используйте
needsвместо порядка этапов где возможно. Ключевое словоneedsпозволяет jobs начинаться сразу после завершения их зависимостей.Устанавливайте
artifacts: when: alwaysна тестовых jobs. Без этого отчёты тестов и скриншоты теряются при падении тестов.Используйте
parallelдля больших тестовых наборов. Встроенное ключевое слово parallel сCI_NODE_INDEX/CI_NODE_TOTALделает шардинг тривиальным.Используйте services для интеграционных тестов. Запуск PostgreSQL, Redis или других зависимостей как services проще и быстрее, чем их установка в job.
Используйте rules вместо only/except. Ключевое слово
rulesмощнее и является рекомендованным подходом для управления запуском jobs.