Как настроить пайплайн с разделением на стадии в GitLab CI

Kate

Administrator
Команда форума
В 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
Этот пайплайн уже сложнее и интереснее. Вот что в нем важно:

  1. Артефакты: сохраняем артефакты сборки и тестов для последующих стадий. Это делает пайплайн независимым от повторного выполнения предыдущих этапов.
  2. Зависимости: указывая зависимости dependencies, мы гарантируем, что задача test-job использует результаты сборки.
  3. Manual deploy: деплой настроен на ручной запуск when: manual.
  4. Очистка: последняя стадия — это очистка временных файлов. Она выполняется только для ветки 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.

 
Сверху