Как стать автором
Поиск
Написать публикацию
Обновить

Три способа реализовать кросспроектный триггер джобы с поправкой на права

Уровень сложностиСредний
Время на прочтение2 мин
Количество просмотров285

Привет, Хабр! Меня зовут Женя, я SDET в «Островке». Каждый день я помогаю командам внедрять автотесты — от сетапа проекта до код-ревью. Сегодня хочу рассказать, как мы бились над кросспроектными джобами и что из этого вышло.

Спойлер: финальное решение оказалось элегантным, но давайте по порядку.

Нативный тригер - просто, но не гибко

Для начала обратимся к нативному тригеру gitlab, который выглядит довольно просто:

trigger_autotests:
  stage: autotests
  trigger:
    project: $PROJECT_RELATIVE_URL
    branch: $AUTOTESTS_BRANCH
  variables: 
    BASE_HOST: https://$CI_COMMIT_REF_SLUG-$CI_PROJECT_NAME.p.ostrovok.ru # любая значимая переменная

Скорее всего при запуске пайплайна с такой джобой вы увидите ошибку 403 Forbidden, причем причина падения видна только при наведении курсора тк в джобу провалиться нельзя

Наводим курсор на джобу, чтобы увидеть ошибку
Наводим курсор на джобу, чтобы увидеть ошибку

Чтобы решить проблему, необходимо добавить каждого разработчика в Members целевого проекта с ролью Developer, но если команда большая, это превращается в рутину. Групповые права не работают — CI_JOB_TOKEN привязан к конкретному пользователю. Прокинуть системный токен тоже не получится — этот функционал пока в обсуждении (ссылка).

Api-тригер - обходим ограничения

Более гибкий вариант:

  1. Берём токен из Settings → CI/CD → Pipeline triggers в проекте с тестами

  2. Сохраняем его в переменные основного проекта как DOWNSTREAM_TOKEN

  3. Используем в джобе:

trigger_autotests:
  stage: autotests
  tags: 
    - runner-type:shell
  script:
    - >
      curl -X POST
      -F token=$DOWNSTREAM_TOKEN
      -F ref=$AUTOTESTS_BRANCH
      -F "variables[BASE_HOST]=https://$CI_COMMIT_REF_SLUG-$CI_PROJECT_NAME.p.ostrovok.ru" # любая значимая переменная
      "https://gitlab.ostrovok.ru/api/v4/projects/$DOWNSTREAM_PROJECT_ID/trigger/pipeline"

Запускаем и радуемся, что джоба не упала из-за отсутствия прав. Но такая джоба не упадет, даже если упадут тесты, ведь для GitLab главное — что POST-запрос отработал. Никакой визуализации дочернего пайплайна не будет, так что тестировщикам приходится вручную отслеживать результаты.

Вот и получается дилемма: либо раздавать права, либо мириться с невидимыми тестами. Либо...

Наше решение - тесты в Docker-образе

autotests:
  stage: autotests
  image: $AUTOTESTS_IMAGE
  tags:
    - runner-type:qa-selenium-docker
  script:
    - cd /opt 
    - pytest ... # любая ваша команда с тестами

Казалось бы, решение идеальное — но и здесь есть два подводных камня, о которых лучше знать заранее:

1) GitLab по умолчанию монтирует проект в /builds/<namespace>/<project>, полностью игнорируя WORKDIR из Dockerfile. Если не сделать cd в нужную директорию (у нас это /opt/tests), pytest просто не найдёт тесты, и вы получите загадочное "No tests found".

2) Права доступа — снова они! Стандартный раннер отказывался удалять pycache после тестов, поэтому все новые джобы падали с ошибками. Решили переключением на qa-runner, который работает в привилегированном режиме (privileged: true) — это даёт ему права на удаление системных файлов вроде pycache.

Выводы: какой способ выбрать

  • Нативный триггер — если команды маленькие и права не проблема

  • API-триггер — когда важно обойти ограничения, а мониторить тесты вручную — норма

  • Docker-образ — универсальное решение, которое подходит почти для всех случаев

Всем зеленых пайплайнов!

Теги:
Хабы:
Рейтинг0
Комментарии0

Публикации

Ближайшие события