Gitlab CI — использование label для управления пайплайнами в небольших командах

от автора

Итак, вы — лид в команде из, скажем, 5-6 разработчиков и 2-3 тестировщика, возникает проблема — как тестировать задачи, запускать тесты по веткам, желательно не толкаясь локтями на одном стенде и не потратив недели на настройку и поддержку инфраструктуры. Сегодня расскажу о подходе, к которому сам пришел, оказавшись в такой ситуации.

Первым делом рассмотрим опции:

  1. Использование заранее созданных веток для разных целей, скажем, master, dev и test. Этот подход самый простой в реализации, но его минус — он плохо масштабируется. Тестировщикам придется делить один стенд для работы, кроме того, вливать больше одной ветки для тестирования в dev — чревато конфликтами и беспорядком в git. Создавать же еще больше технических веток — еще больший хаос в гите.

  2. Собирать каждую ветку в свой полноценный стенд, qa-xxx.dev.xxx.com . Это самый зрелый и удобный для использования вариант, вот только для маленьких команд он непосильно сложен, особенно если среди вас нет девопса. Вам нужно будет разобраться с автоматизацией выдачи SSL сертификатов, настройкой DNS, nginx, подчисткой старых веток и так далее.

  3. Компромиссный вариант. Собирать каждую ветку по отдельности, но по запросу и на заранее созданные инстансы, test-1, test-2 и так далее. При необходимости масштабирования, создавать новые стенды руками. Кажется, это то, что нужно, вот только как это реализовать? Об этом и пойдет речь ниже.

Для «маршрутизации» веток на инстансы мы используем labels. Выглядит это следующим образом:

Назначение label на ветку автоматически запускает пайплайн с нужными параметрами. Но есть нюанс — оказывается, gitlab не позволяет запускать пайплайны по триггеру на добавление / удаление лейбла. Все, что позволяет gitlab — это выставить ограничение на запуск пайплайна при создании MR, что не совсем подходит — обычно сборка ветки происходит не сразу после его создания.

Хорошая новость в том, что это все-таки возможно — с помощью pipeline triggers и webhooks. Мы просто слушаем события merge request events и триггерим пайплайн в двух случаях: добавление label к ветке и добавление новых коммитов к ветке с нужными label.

Первым делом создаем pipeline trigger token в Settings > CI/CD > Pipeline triggers.

Наш pipeline trigger — по сути микросервис, который принимает вебхуки и по необходимости запускает пайплайны.

Вот его код
const axios = require('axios') var express = require('express'); var router = express.Router();  router.post('/', async function (req, res) {     const requestBody = req.body     const labelRegex = /^test-\d+$/      let label      // If MR is open     if (!['opened', 'locked'].includes(requestBody.object_attributes.state)) {         res.send({             'message': 'invalid status',             'status': requestBody.object_attributes.state         })          return;     }          if (!requestBody.changes.labels) {         // No changes in labels or new commits         if (!requestBody.changes.updated_at && Object.keys(requestBody.changes).length > 0) {             res.send({                 'message': 'The change is empty',             })              return;         }          label = requestBody.labels             .filter(label => label.title.match(labelRegex))             .map(label => label.title)[0]     } else {         // Find a changed label         label = requestBody.changes.labels.current             .filter(label => label.title.match(labelRegex))             .filter(label => !requestBody.changes.labels.previous.find(lbl => lbl.id === label.id))             .map(label => label.title)[0]     }      if (!label) {         res.send({             message: 'label not found'         })          return;     }      await axios.post(`https://gitlab.com/api/v4/projects/${process.env.PROJECT_ID}/trigger/pipeline`, {         token: process.env.ACCESS_TOKEN,         ref: requestBody.object_attributes.source_branch,         variables: {             TEST_INSTANCE: label,             CI_MERGE_REQUEST_LABELS: requestBody.labels?.map(label => label.title).join(',') ?? ''         }     })              res.send({         'message': 'success'     }) });  module.exports = router;

Осталось только добавить вебхук в гитлабе в Settings > Webhooks:

Gitlab предоставляет доступ к логам, так что в случае проблем их можно довольно легко отладить:

Все! Теперь просто присвойте label test-N вашей ветке и вебхук запустит пайплайн. Из приятных бонусов: скрипт также передает все остальные назначенные label-ы через запятую, что позволяет дополнительно задавать на лету переменные окружения, например, вы можете через label управлять, пересоздавать ли БД с нуля или использовать сохраненные данные, и так далее.

Заключение

Конечно, этот способ не идеален и масштабируется лишь ограниченно. Если вам не хватает пяти стендов для тестирования, возможно, вам стоит задуматься о более продвинутой схеме. Однако, для небольших команд подход обеспечивает неплохой development experience, позволяет полноценно тестировать в независимых окружениях и не накладывает ограничений на разработку.


ссылка на оригинал статьи https://habr.com/ru/post/674932/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *