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

Ответ

GitLab CI/CD запускается автоматически при наличии файла .gitlab-ci.yml в корне репозитория. Настройка сводится к правильному определению триггеров в этом файле.

Базовый пример: Пайплайн, который запускает сборку и тесты для каждого коммита в любую ветку.

# .gitlab-ci.yml
stages:
  - build
  - test

build-job:
  stage: build
  script:
    - echo "Building the application..."
    - mvn clean compile # Для Java Maven проекта

test-job:
  stage: test
  script:
    - echo "Running tests..."
    - mvn test

Контроль триггеров с помощью rules (предпочтительный современный способ): Я использую rules для тонкой настройки условий запуска.

build-job:
  stage: build
  script:
    - mvn clean compile
  rules:
    # Запускать для всех коммитов, кроме merge request
    - if: $CI_PIPELINE_SOURCE == "push"

test-job:
  stage: test
  script:
    - mvn test
  rules:
    # Запускать тесты всегда для main и develop веток
    - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
    # Или запускать для merge request в main
    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"

deploy-job:
  stage: deploy
  script:
    - echo "Deploying to staging..."
  rules:
    # Запускать деплой ТОЛЬКО для коммитов в main ветку
    - if: $CI_COMMIT_BRANCH == "main"

Использование changes для оптимизации: Чтобы не запускать весь пайплайн при изменении, например, только документации, можно использовать правило changes.

backend-tests:
  stage: test
  script:
    - cd backend && npm test
  rules:
    - changes:
        - backend/**/*
        - package-lock.json

frontend-tests:
  stage: test
  script:
    - cd frontend && npm test
  rules:
    - changes:
        - frontend/**/*
        - package-lock.json

Ключевые переменные GitLab CI, которые я часто использую:

  • $CI_COMMIT_BRANCH: Имя ветки, для которой запущен пайплайн.
  • $CI_MERGE_REQUEST_TARGET_BRANCH_NAME: Целевая ветка Merge Request.
  • $CI_PIPELINE_SOURCE: Источник пайплайна (push, web, schedule, merge_request_event).
  • $CI_COMMIT_TAG: Имя тега, если пайплайн запущен для тега.

Ответ 18+ 🔞

А, ну вот, опять про эти ваши CI/CD! Слушай, тут всё просто, как три копейки, но если накосячить — будет тебе хиросима и нигерсраки в одном флаконе.

В общем, смотри. GitLab, этот хитрожопый, как только видит в корне твоего репа файлик .gitlab-ci.yml, он сразу такой: «О, ебушки-воробушки, сейчас я тут всё запущу!». И начинает городить пайплайны. А вся настройка — это просто правильно написать в этом файле, когда и что ему делать.

Вот самый простой пример, чтобы мозги не взорвались: Пайплайн, который на каждый чих — на каждый коммит в любую ветку — собирает проект и гоняет тесты.

# .gitlab-ci.yml
stages:
  - build
  - test

build-job:
  stage: build
  script:
    - echo "Building the application..."
    - mvn clean compile # Это если у тебя Java-проект на Maven, например

test-job:
  stage: test
  script:
    - echo "Running tests..."
    - mvn test

Но это же, блядь, примитив! Он будет бегать как угорелый на каждый пушачок в какую-нибудь временную ветку. Надо умнее. И для этого есть rules — это твой главный инструмент, чтобы не тратить ресурсы зря.

Вот как я обычно настраиваю триггеры через rules (это сейчас модно и правильно): Тут уже можно поизголяться.

build-job:
  stage: build
  script:
    - mvn clean compile
  rules:
    # Собираем на каждый обычный пуш в репу, но не на мерж-реквесты
    - if: $CI_PIPELINE_SOURCE == "push"

test-job:
  stage: test
  script:
    - mvn test
  rules:
    # Тесты гоняем всегда для главных веток main и develop
    - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
    # ...ИЛИ если это мерж-реквест в main — тоже надо проверить
    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"

deploy-job:
  stage: deploy
  script:
    - echo "Deploying to staging..."
  rules:
    # А вот деплой — это святое. Только коммиты прямо в main!
    - if: $CI_COMMIT_BRANCH == "main"

Чувствуешь разницу? Уже не тупая лопата, а хирургический инструмент.

Ещё есть крутая штука changes для ленивых (в хорошем смысле): Чтобы не грузить всю инфраструктуру, если ты, допустим, только README.md поправил. Ядрёна вошь, зачем тогда тесты-то все запускать?

backend-tests:
  stage: test
  script:
    - cd backend && npm test
  rules:
    - changes:
        - backend/**/*  # Запускаемся, только если что-то поменялось в бэкенде
        - package-lock.json # Или если зависимости обновились

frontend-tests:
  stage: test
  script:
    - cd frontend && npm test
  rules:
    - changes:
        - frontend/**/* # А тут — только если фронтенд тронули
        - package-lock.json

Ну и напоследок, запомни эти переменные, они тебе ещё овердохуища раз пригодятся:

  • $CI_COMMIT_BRANCH — из какой ветки приплыл коммит. Без неё никуда.
  • $CI_MERGE_REQUEST_TARGET_BRANCH_NAME — куда мержим. Очень важно для реквестов.
  • $CI_PIPELINE_SOURCE — откуда ноги растут у пайплайна: обычный пуш, веб-интерфейс, расписание или событие мерж-реквеста.
  • $CI_COMMIT_TAG — если всё это безобразие запустилось из-за тега. Для релизов нужно.

Вот и вся магия. Главное — не перемудрить, а то получится такая пиздопроебибна, в которой сам через неделю не разберёшься.