В GitLab CI пайплайны выполняют основную роль в автоматизации процессов CI/CD. Они позволяют разбить весь процесс сборки, тестирования и деплоя на отдельные, логически связанные задачи — или "джобы". Эти джобы структурируются в стадии, каждая из которых представляет собой определенный этап работы, например, сборка, тестирование или развертывание. Такое разделение позволяет ускорить разработку и минимизировать ошибки при доставке кода на продакшн.
В этой статье рассмотрим, как настроить пайплайн с разделением на стадии в GitLab CI.
Настройка пайплайна
Файл .gitlab-ci.yml
— это то, где работа GitLab CI начинается. В нем мы описываем стадии, джобы и их зависимости. Этот файл не просто конфигурационный, это сущность, которая определяет поведение всех ваших CI/CD процессов.
Каждый файл .gitlab-ci.yml
начинается с определения стадий, затем определяются джобы, которые будут выполнены на этих стадиях. Минимальный пример:
stages:
- build
- test
- deploy
Этот код определяет три стадии — сборку, тестирование и деплой. Звучит просто, но как только начинаем добавлять джобы, становится интересней.
После того как стадии определены, нужно привязать к ним задачи. Каждая задача выполняет набор команд:
build-job:
stage: build
script:
- echo "Building the project..."
- make build
test-job:
stage: test
script:
- echo "Running tests..."
- make test
deploy-job:
stage: deploy
script:
- echo "Deploying to production..."
- make deploy
В этом примере у нас три джобы: одна для каждой стадии. Каждая джоба выполняет свою команду на этапе, к которому она привязана. Каждая джоба выполняется независимо и может иметь свои переменные окружения, зависимости и условия запуска.
Основная фича разделения пайплайна на стадии — это возможность выполнять разные этапы в зависимости от статуса предыдущих. Например, тестирование не начнется, пока сборка не завершится, а деплой произойдет только после успешного тестирования.
Пример более сложной конфигурации пайплайна:
stages:
- build
- test
- deploy
- cleanup
# Джоба для сборки
build-job:
stage: build
script:
- echo "Building project..."
- make build
artifacts:
paths:
- build/
# Джоба для тестирования
test-job:
stage: test
script:
- echo "Running tests..."
- make test
dependencies:
- build-job
artifacts:
paths:
- test-results/
# Джоба для деплоя
deploy-job:
stage: deploy
script:
- echo "Deploying to production..."
- make deploy
when: manual
environment: production
# Джоба для очистки временных файлов
cleanup-job:
stage: cleanup
script:
- echo "Cleaning up..."
- rm -rf build/ test-results/
only:
- master
Этот пайплайн уже сложнее и интереснее. Вот что в нем важно:
Артефакты: сохраняем артефакты сборки и тестов для последующих стадий. Это делает пайплайн независимым от повторного выполнения предыдущих этапов.
Зависимости: указывая зависимости
dependencies
, мы гарантируем, что задачаtest-job
использует результаты сборки.Manual deploy: деплой настроен на ручной запуск
when: manual
.Очистка: последняя стадия — это очистка временных файлов. Она выполняется только для ветки
master
, чтобы не захламлять репозиторий временными артефактами.
Представим, что нужно собрать Docker-контейнер, протестировать его, а затем задеплоить на продакшн. Как это может выглядеть:
stages:
- build
- test
- deploy
build-job:
stage: build
image: docker:stable
services:
- docker:dind
script:
- docker build -t myapp:$CI_COMMIT_SHA .
- docker save myapp:$CI_COMMIT_SHA | gzip > myapp.tar.gz
artifacts:
paths:
- myapp.tar.gz
test-job:
stage: test
script:
- docker load -i myapp.tar.gz
- docker run myapp:$CI_COMMIT_SHA ./run-tests.sh
dependencies:
- build-job
deploy-job:
stage: deploy
script:
- echo "Deploying to production..."
- docker load -i myapp.tar.gz
- docker tag myapp:$CI_COMMIT_SHA myrepo/myapp:latest
- docker push myrepo/myapp:latest
when: manual
environment: production
Этот пайплайн выполняет следующие шаги:
Сборка Docker-образа на стадии
build
.Тестирование образа на стадии
test
.Деплой на продакшн при ручном запуске на стадии
deploy
.
Параллельное выполнение стадий
Когда задачи в пайплайне не зависят друг от друга или требуют выполнения после других заданий, директива needs
становится отличным решением для ускорения. Она позволяет запускать задачи не последовательно по стадиям, а параллельно, как только необходимые задания будут завершены, что значительно снижает общее время выполнения.
Пример конфигурации с использованием директивы needs
:
stages:
- build
- test
- deploy
build-job:
stage: build
script:
- make build
test-job:
stage: test
needs: ["build-job"]
script:
- make test
deploy-job:
stage: deploy
needs: ["test-job"]
script:
- make deploy
Здесь задачи test-job
и deploy-job
начнут выполняться сразу после успешного завершения своих зависимостей, что ускоряет выполнение по сравнению с классическим последовательным запуском стадий.
В GitLab CI также доступна директива dependencies
, которая контролирует, какие артефакты могут быть переданы между задачами на разных стадиях. Это мастхев, когда одна задача нуждается в результатах другой.
Пример:
stages:
- build
- test
- deploy
build-job:
stage: build
script:
- make build
artifacts:
paths:
- build/
test-job:
stage: test
script:
- make test
dependencies:
- build-job
deploy-job:
stage: deploy
script:
- make deploy
dependencies:
- test-job
Здесь артефакты, созданные на стадии build
, передаются в задачу test-job
, а затем в deploy-job
.
Один из эффективных методов ускорения пайплайнов – кэширование. GitLab позволяет кешировать зависимости, такие как библиотеки и пакеты, чтобы не загружать их заново при каждом запуске пайплайна. Например:
build-job:
stage: build
cache:
paths:
- node_modules/
script:
- npm install
- npm run build
Здесь кэшируются node_modules
, что позволяет не устанавливать их заново на каждом шаге сборки.
Директива parallel
позволяет запускать несколько экземпляров одной и той же задачи параллельно.
Пример параллельного тестирования с разными версиями Python:
test-job:
stage: test
image: python:$VERSION
script:
- pytest
parallel:
matrix:
- VERSION: ['3.8', '3.9', '3.10', '3.12']
Этот пайплайн запустит четыре задачи параллельно, каждая с различной версией Python.
В завершение напомню про открытый урок по использованию gitlab-ci для работы с ansible, который пройдет 18 сентября.
На этом занятии вы узнаете, как применять GitLab CI для автоматизации процессов с помощью Ansible. Познакомитесь с основами работы с GitLab CI и Ansible, а также научитесь создавать пайплайны для тестирования плейбуков и управления инфраструктурой.
Записаться на урок бесплатно можно на странице курса «CI/CD на основе GitLab».