Непрерывная интеграция (CI, англ. Continuous Integration) — практика разработки программного обеспечения, которая заключается в постоянном слиянии рабочих копий в общую основную ветвь разработки (до нескольких раз в день) и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем. В обычном проекте, где над разными частями системы разработчики трудятся независимо, стадия интеграции является заключительной. Она может непредсказуемо задержать окончание работ. Переход к непрерывной интеграции позволяет снизить трудоёмкость интеграции и сделать её более предсказуемой за счёт наиболее раннего обнаружения и устранения ошибок и противоречий, но основным преимуществом является сокращение стоимости исправления дефекта, за счёт раннего его выявления.
Впервые концептуализирована и предложена Гради Бучем в 1991 году. Является одним из основных элементов практики экстремального программирования.
У нас есть такие проекты, на которых мы успели попробовать следующие три CI:
- Circle CI
- Cirrus CI
- Travis-CI
И так, в порядке убывания, мы расскажем о каждой из CI в списке. Расскажем о скорости работы, сложностях настройки и о различиях. И так, приступим! Осторожно: Много картинок! :warn_frontend_gods_emoji:
Circle CI
Кстати, хотелось бы сходу сказать, что Circle CI, самая шустрая и быстрая из всех выше перечисленных — первое место (на самом деле второе, как окажется далее по таймингу, Cirrus CI быстрее на 22 секунды и получается, как бы отбирает первое место Circle CI). Один и тот же билд, с одной и той же целью - запустить интеграционные тесты, проходит очень быстро и ты наблюдаешь результат, для твоего PR первее всех. Это очень круто, так как время на прогон тестов очень ценно для разработчика, чем быстрее проходят тесты на CI, тем быстрее разработчик сможет выкатить новый функционал.
Тайминг шагов билда Circle CI
Тайминг запуска интеграционных тестов на Circle CI следующий:
На все про все, ушло 57 секунд, очень классно!
- Spin up Environment — 2 секунды
- Checkout code — 0 секунд, очень круто!
- Restoring Cache — 9 секунд
- Install dependencies — 12 секунд (установка зависимостей для google-chrome-stable)
- Install Chromedriver latest version — 7 секунд (установка самого google-chrome-stable)
- PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm i — 5 секунд (установка зависимостей через node package manager c ключом, указывающим puppeteer о том, что не нужно скачивать хромиум.
- Saving Cache — 4 секунды сохранение в кэш содержимое папки node_modules
- npm run test:integration — 14 секунд (сам запуск интеграционных тестов посредством puppeteer)
Итого: 53 секунды
Очередь на запуск билда ~ 4 секунды
Конфигурация Circle CI для запуска тестов на puppeteer
Все начинается с написания файла конфигурации под названием config.yml в папке .circleci что должна находиться в корне проекта.
Файл конфигурации очень классно структурирован, что позволяет сразу увидеть моменты, связанные с Jobs. Тут сразу бросается в глаза, что всего одна Job будет запущена и все настройки для этой Job находятся ниже.
- Очень удобно указать какой образ докера нужен для вашего проекта.
- Обязательно нужно указывать папку с названием вашего репозитория в ключе working_directory относительно корневой папки /.
- Сразу видно какие шаги будут задействованы в билде на CI в ключе steps
- Классно реализована возможность кешировать содержимое папки node_modules, ведь в ней “весь интернет” :).
- Каждый run шаг можно обозвать так, чтобы было попонятнее и указать команду в ключе command.
Пожалуй настройку для Circle CI можно назвать очень комфортной и беспроблемной.
Cirrus CI — модная и кросс-платформенная CI от Cirrus Labs
Пожалуй самая крутая реализация CI ввиду ее поддержки Linux, Windows и macOS. И все в одной коробке! Если твой проект — кросс-платформенный, то лучшей CI тебе не найти. На сайте Cirrus CI, можно более подробно прочитать про ee возможности.
Эта CI, пожалуй занимает первое место, по скорости прохождения билда.
Настройка билда на Cirrus CI
- Далее нужно выбрать план
- К счастью, не нужно ничего платить за публичные репозитории, и спасибо за это Cirrus Labs! Для общедоступных репозиториев нет ограничения по времени, за исключением следующих лимитов https://cirrus-ci.org/faq/#are-there-any-limits.
- Для приватных репозиториев, стоимость составляет 10 долларов в месяц, с теми же лимитами. Для частных проектов организации вы можете либо подключить свою собственную инфраструктуру, либо использовать выставление счетов по-секундно, без ограничений параллелизма. Каждая организация также получает 200 процессорных часов, чтобы попробовать свои силы.
Страница настройки приложения Cirrus CI в вашем репо или организации
Тут тоже все очень удобно! Можно выбрать на какие репозитории будет распространяться трекинг изменений и запуск билдов со стороны Cirrus CI. За это респект CirrusLabs.
Немного об интерфейсе приложения Cirrus CI
Он доступен прям в вашем репо. Это очень удобно, на скрине ниже видно кол-во шагов и тайминг по ним.
Тайминг Cirrus CI
Судя по таймингу, наблюдаем 31 секунду, что намного меньше, чем на Circle CI. И это очень круто!
Как видим задача Prebuild не выполняется, так как ничего не поменялось в докер файле для тестового окружения.
Клонирование репо, запуск xvfb на будущее для не хеадлесс тестов + установка зависимостей через npm и запуск тестов, все вместе занимают 31 секунду! Очень даже неплохо! Cirrus CI по таймингу быстрее чем Circle CI! Еще одну копеечку в карму Cirrus Labs!
Конфигурация Cirrus CI для запуска тестов на puppeteer
Вся конфигурация так же основана на yml и описывается в файле .cirrus.yml, который должен находиться в корне вашего проекта.
Считаю, что это самый близко приближенный конфиг, к тому, что используется для VSCode и это великолепно!
Самая главная фишка Cirrus CI— это возможность указать свой собственный Dockerfile, для нужной мне операционной системы. Чем я и поспешил воспользоваться!
За исключением выделения отдельного пользователя, для того, чтобы включить режим песочницы, установка google-chrome-stable полностью повторяет то, что указано в .devcontainer/Dockerfile. И как оказывается, по сравнению с Circle CI и Travis-CI — это прям зачетная возможность! Не нужно уходить от привычного способа установки браузера и использовать какие-то мистические плагины или неочевидные скрипты установки, которые с трудом находишь в ветках обсуждения проблем на GitHub и запуска тестов на той или иной CI связанных с Puppeteer.
Travis-CI
Это пожалуй самый долго выполняющийся билд по сравнению с Circle CI и Cirrus-CI. И по этой причине Travis-CI в конце списка.
Тайминг выполнения билда на Travis-CI
Как видно из интерфейса общее время выполнения составило 1 минута 11 секунд. Это в 2 раза больше времени чем на Circle-CI и в ~3 раза больше чем на Cirrus-CI.
- Клонирование репо — 4.48 секунды
- Установка node.js 10.15.3 — 2.79 секунды
- Старт xvfb — 0.01 секунды
- Установка зависимостей через npm — 7.16 секунды
- Прогон интеграционных тестов — 17.58 секунд
Итого: 32.02 секунды! Стоп! Откуда 1 минута 11 секунд?
Судя по RAW логу, вижу что остальное время ушло на создание окружения, для прогона тестов (на что не тратится время на Circle-CI и на Cirrus-CI), получается каждый раз по-новой. Этот фактор, либо от настройки зависит, либо от концепции “новый билд — все соберем по новой, а вдруг на какой нибудь новой библиотеке все навернется?“. В общем вот тут было горячее обсуждение задач с докером внутри. В ней, люди жаловались на то, что их билд проходит 9 минут на Travis-CI, тогда как локально, из-за кеширования образов докера, билд собирается за минуту.
Неочевидности, с которыми можно столкнуться на Travis-CI
- Это переменные окружения в ключе env: файла настройки. Вроде бы все казалось очевидным, просто указываешь по одной переменно окружения в строке, с его значением и все ок. Но нет! Как оказалось каждая строка в этом случае — означает установку каждой из переменных на одну задачу. Таким образом, установив 2 переменные окружения, мы получили две задачи!
- Как этот момент фиксится? Очень просто! Оказывается есть global: подраздел в env: для того, чтобы объявить глобальный для всех задач, список переменных окружения. Теперь секция env:, выглядит таким образом:
В этом случае, сколько бы переменных ни было установлено, все они, будут установлены для всех задач и порождение новых задач (по кол-ву переменных), происходить не будет.
- Так же очень мало информации о том, как же запускать и устанавливать браузер google-chrome-stable для запуска тестов на puppeteer. Многие утверждали в github issue, что в trusty уже все есть, но вот названия браузеров отличаются видимо и старт браузера (по умолчанию хром 67 версии в системе), не происходил, запуск тестов валился с таймаутом. Кто-то предлагал на шаге before_install запускать браузер.
- google-chrome-stable — headless — disable-gpu — remote-debugging-port=9222 http://localhost &
Но зачем? Ведь мы и сами можем запустить в puppeteer. И после нескольких неудачных попыток, найти как ставить браузер самим, нашли в обсуждениях на GitHub, информацию о том, что браузер можно поставить через аддоны.
Вот таким образом, мы добились установки такого же браузера для билда на Travis-CI (устанавливается версия 75), что мы использовали локально. Можно почитать тут о том, как писать конфигурацию для GUI и headless браузеров.
Конфигурация Travis CI для запуска тестов на puppeteer
Конфигурация для Travis-CI заключается в написании файла .travis.yml, который должен находиться в корневой директории проекта.
Заключение
В итоге, после визуального замера скорости отрабатывания запуска билдов на CI и реальных замеров по таймингу шагов, лидеров среди всех трех CI — оказался Cirrus CI. На лице докер-ориентированнось Cirrus CI, так как в сети и даже у того же puppeteer проекта можно обнаружить в примерах использование докер файлов, что позволяет нивелировать время повторных запусков билдов и ускорить их прохождение. Travis-CI такими примерами не блещет с самого начала и этот факт не дает написать базовую конфигурацию с использованием докер образов или принципов кеширования.
Так что вывод такой: Используйте CI, где интеграция докер образа, уже используется изначально. Так вы сэкономите время на прохождении билдов на CI. Ведь уже собранный однажды образ докера, переиспользуется многократно, если он не был изменен.
Спасибо за то, что дочитали эту статью до конца! Надеюсь собранный материал пойдет на пользу каждому, кто начинает сталкиваться с миром CI окружающим нас вокруг!
Ранее статья была опубликована тут.