ADG Оставить заявку
Блог DevOps 4 мин чтения

GitHub Actions: переводим проекты с Jenkins на self-hosted runners

Переносим несколько проектов с Jenkins на GitHub Actions: self-hosted runner на собственном сервере, secrets, environments и матричные сборки на практике.

Контекст момента

GitHub Actions наращивает экосистему и инструменты для enterprise: self-hosted runners, environments с защитными правилами, матричные стратегии в production-пайплайнах

Несколько месяцев мы откладывали переезд с Jenkins на GitHub Actions - всё ждали, когда экосистема устаканится. В конце июня решили: хватит ждать, берём три проекта и переносим. Что получилось - расскажем честно.

Проблема с Jenkins у нас была одна, но принципиальная. Сам Jenkins работал нормально - Pipeline DSL мы освоили ещё в 2016-м, Jenkinsfile жил рядом с кодом, всё культурно. Но доступ к внутренним сервисам (Nexus, внутренний реестр Docker, legacy-API одного из заказчиков) требовал либо поднимать Jenkins-мастер в той же сети, либо городить VPN-туннели. Мы городили. Поддерживать этот зоопарк из туннелей становилось всё неприятнее.

GitHub Actions self-hosted runner решает это иначе: агент сам выходит наружу через HTTPS, а не ждёт входящих подключений. Запускаешь runner на сервере в нужной сети - и он сам регистрируется в репозитории. Никаких входящих портов, никаких туннелей. Для нашего сценария это принципиально.

Как разворачивали runner

Процедура несложная: качаешь тарбол с GitHub, запускаешь ./config.sh с токеном репозитория, потом ./svc.sh install && ./svc.sh start - и runner живёт как systemd-сервис. На Ubuntu 20.04 всё встало без сюрпризов. Runner сразу подхватил переменные окружения сервера, видит внутренний DNS, ходит на Nexus напрямую.

В workflow указываешь его через runs-on: self-hosted или метки, которые сам назначаешь при регистрации:

jobs:
  build:
    runs-on: [self-hosted, linux, internal-net]

Метки - удобно. Можно зарегистрировать несколько runner-ов с разными метками и направлять конкретные jobs туда, где нужный доступ.

Secrets и environments

Здесь GitHub Actions сделал аккуратнее, чем мы ожидали. Secrets хранятся на уровне репозитория или организации, в логах автоматически маскируются. Это не rocket science, но работает.

Интереснее - environments. Можно завести окружение production, назначить ему reviewers и правило: деплой запускается только после ручного подтверждения. В workflow это выглядит как environment: production на конкретном job. Jenkins это умеет через плагины, но из коробки такого нет.

Одна оговорка: environments с защитными правилами на момент написания доступны только в публичных репозиториях или при платном плане GitHub. Для приватных репов в бесплатном тире - нет. У нас GitHub Team, поэтому работает, но надо иметь в виду.

Матричные сборки

Это то, за что GitHub Actions получает заслуженные баллы. Матрица позволяет прогонять один и тот же job с разными параметрами параллельно:

strategy:
  matrix:
    python-version: [3.6, 3.7, 3.8]
    os: [ubuntu-20.04, ubuntu-18.04]

Получаешь 6 параллельных jobs без написания шести отдельных блоков. В Jenkins это делается через Declarative Pipeline с parallel - работает, но многословнее. Матрица в Actions читается чище.

Для одного из проектов мы добавили сборку под несколько версий Node.js - то, что раньше занимало 30 строк Jenkinsfile, уложилось в 10 строк YAML.

Что не понравилось

Кэш зависимостей требует явного описания через actions/cache. В GitLab CI кэш настраивается одной директивой, здесь нужно прописывать пути и ключи руками. Не катастрофа, но при первом переносе поймали незакэшированные сборки и удивились, почему npm install занимает 3 минуты на каждом прогоне.

Debugging сложнее, чем в Jenkins. Там можно зайти на master, смотреть логи в реальном времени, переподключиться. В Actions логи только через веб-интерфейс с задержкой - пока пайплайн живой, UI иногда подвисает при быстрых job-ах. SSH-доступ к runner-у при проблемах тоже надо организовывать отдельно, хотя сам сервер у нас свой, это несложно.

Маркетплейс action-ов - оба берега. Много готовых блоков, не надо писать с нуля. Но качество разное: часть action-ов заброшена, часть - тонкие обёртки над curl. Для managed-проектов мы выработали правило: action от вендора или из GitHub-организации принимаем, остальное - смотрим исходники перед использованием.

Итог после первых недель

Три проекта перенесли. Один оставили на Jenkins - там специфичная конфигурация агента с аппаратным ключом, self-hosted runner туда тоже можно посадить, но руки не дошли.

Общее ощущение: GitHub Actions удобнее там, где код уже живёт на GitHub и не нужна сложная оркестрация. Jenkinsfile мощнее для нестандартных сценариев, но требует поддерживать мастер-сервер и думать о его доступности. Self-hosted runner убирает главную боль - возню с сетевым доступом - и это стоит потраченного времени на переезд.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.