За пределами GitHub: Универсальные клиенты, Code Quality и ловушки Bitbucket

 · 3 min read

Наше ядро работало отлично, а SaaS-облако было готово принимать запросы. Но чтобы сторонние разработчики могли легко начать пользоваться Flude, им нужны удобные точки входа — интеграции с их CI/CD пайплайнами.

CI Thin Clients

Сначала мы написали плагин исключительно под GitHub Actions. Однако огромное количество проектов и коммерческих команд предпочитают GitLab и Bitbucket. Стало очевидно, что нам нужно выделить логику в универсальный “тонкий клиент”, который будет одинаково хорошо работать на “большой тройке” платформ.

Философия тонкого клиента

Мы вынесли всю базовую логику в чистые независимые JavaScript-файлы (control-plane-client.js, poll.js, download.js). Никаких тяжелых сборок и папок node_modules.

Наш CI-клиент стал максимально глупым: он просто архивирует исходники, отправляет их по API в наше SaaS-облако, с заданным интервалом пингует статус задачи и скачивает итоговый ZIP-архив с готовой документацией. Вся вычислительная магия, парсинг и рендеринг происходят исключительно на бэкенде.

GitLab и архитектура отчетов (Code Quality)

Ci Thin Clients Gitlab Bitbucket Part 2

Интеграция с GitLab принесла интересную архитектурную задачу.

В GitHub Actions предупреждения парсера (например, о недокументированных методах) легко выводятся в UI через GITHUB_STEP_SUMMARY и магические строки вида ::notice::. GitLab такого не понимает — он требует подкладывать специальный JSON-артефакт в формате CodeClimate.

Важный архитектурный момент: мы принципиально не стали перегружать наш легковесный клиент логикой конвертации форматов. Вся эта работа зашита в самое сердце ядра (engine/ude/reporting.py).

Во время сборки движок собирает все ошибки в единое внутреннее представление (Finding), а затем сам транслирует его во все нужные внешние форматы: и в SARIF (для GitHub), и в CodeClimate (для GitLab). Клиентскому скрипту в GitLab остается лишь достать уже сгенерированный codequality.json из скачанного архива и отдать его раннеру. Благодаря этому в Merge Request появляется нативный, удобный виджет “Code Quality scans found N new findings”.

Bitbucket Pipe и ловушка Docker

Интеграции в экосистеме Bitbucket работают через так называемые “Трубы” (Pipes), которые исполняются строго внутри изолированных Docker-контейнеров. Чтобы поддержать эту платформу, мы обернули наши JS-скрипты в Dockerfile и добавили манифест pipe.yml.

И именно здесь мы поймали классическую сетевую ловушку. При локальном написании E2E-тестов наш контейнерный клиент, естественно, пытался достучаться до локального мок-сервера по адресу localhost:29418. Но мы забыли о базе: внутри Docker localhost — это сам контейнер, а не хостовая машина! Запросы уходили в пустоту, а тесты падали по таймауту.

Нам пришлось изрядно повозиться с настройками bridge-сетей Docker’а и пробросом портов, чтобы заставить Pipe видеть хостовую машину и успешно проходить локальное тестирование.

Итог

Мы успешно покрыли “большую тройку” CI/CD-платформ. Экосистема замкнулась: C++ код летит из любого популярного CI-раннера в наше облако и возвращается обратно в виде эталонной документации и отчетов о качестве.

Но открыв ворота в SaaS для всех желающих, мы столкнулись с новой угрозой. Зависшие процессы Doxygen и git clone начали бесконтрольно пожирать облачные ресурсы. О том, как мы строили систему сторожевых таймеров и почему самому Watchdog’у понадобился Watchdog — читайте в следующем эпизоде.