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


В завершение напомню про открытый урок по использованию gitlab-ci для работы с ansible, который пройдет 18 сентября.

На этом занятии вы узнаете, как применять GitLab CI для автоматизации процессов с помощью Ansible. Познакомитесь с основами работы с GitLab CI и Ansible, а также научитесь создавать пайплайны для тестирования плейбуков и управления инфраструктурой.

Записаться на урок бесплатно можно на странице курса «CI/CD на основе GitLab».

Комментарии (2)


  1. edw1n
    12.09.2024 01:49

    Вебинар в 0:00 MSK - т.е. вся остальная страна будет пытаться осилить материал среди ночи? Ну и по ссылке дата указана 19 сентября.


  1. randomsimplenumber
    12.09.2024 01:49
    +1

    последняя стадия — это очистка временных файлов. Она выполняется только для ветки master, чтобы не захламлять репозиторий временными артефактами.

    Вы так репозиторий не захламите. А рабочая директория и сама очищается, вы же cache не просто так придумали использовать?