Как стать автором
Обновить
Selectel
IT-инфраструктура для бизнеса

Техническая экспертиза: настраиваем CI на М1 с командой Welps

Время на прочтение 7 мин
Количество просмотров 3K

Привет, Хабр! Мы начинаем серию статей, в которых наши партнеры рассказывают о разных нюансах сетевых технологий.

Сегодня встречайте Виталия Волкова, тимлида разработки в Welps (компания создает wellness-приложения). Виталий расскажет, как поднять Cl на М1 с использованием инфраструктуры Selectel. Поехали!

Просто о сложном


Что такое Cl? Это подход к программированию, где разработка ведется итерациями. В этом случае отводятся фича-ветки, которые в дальнейшем мерджатся с главной веткой. На каждой итерации необходимо производить автоматические проверки. Это помогает добиться стабильности продукта.

Как это работает на практике? Сначала разработчики пушат изменения в репозиторий. Последний отрабатывает триггер с последующим запуском проверок. Они выполняются либо в облаке, либо на локальных офисных машинах. Ну а по результатам сборки команда принимает решение о валидности изменений.


Вопросом автоматизации задались уже давно, за это время было написано много различных решений. Среди них: Gitlab CI, Circle CI, Jenkins и другие. Для решения наших задач мы использовали Github Actions и Fastlane. Fastlane – это набор Ruby-библиотек, которые автоматизируют взаимодействие с проектом.

Настраиваем автоматизацию проверок


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

В рамках этого проекта мы автоматизируем проверку кода и выпуск релизов. Что нам нужно от проверки кода? Проводить unit и ui тесты, а также проверять код линтером на опечатки. Релиз в идеале должен отправляться по нажатию на магическую кнопку с последующей отсылкой уведомления в slack.


Проверка кода выполняется по такому алгоритму:
  • Разработчик пушит изменения в GitHub.
  • GitHub уведомляет экшены о том, что есть изменения.
  • Actions отправляет команду на Worker — конечно, в зависимости от того, срабатывают ли триггеры.
  • Ну а Worker выполняет заданные разработчиками манипуляции с проектом.
  • Fastlane показывает в обратном порядке весь аутпут из командной строки.
  • Разработчик видит простой бинарный ответ — «ок» или «не ок».

Плюс алгоритма в том, что если возникли проблемы на пути внедрения изменений, то можно посмотреть, на каком этапе возникли проблемы, что является причиной, а потом при помощи Shell получить уже детальную информацию.

Но это то, что касается изменений. С релизами все чуть сложнее, здесь иной алгоритм:
  • Разработчик релизит приложение и мерджит изменения в главную ветку репо.
  • GitHub сообщает об этом экшнам.
  • Последние создают уже ручной триггер — это нечто вроде кнопки, которая висит в интерфейсе GitHub и ждет, когда на нее нажмут.


Когда потребуется зарелизить проект, разработчик этой кнопкой запускает всю цепочку процессов. Единственная разница по сравнению с предыдущим моментом — Fastlane отправляет еще и отбивку в FAQ, помогая сотрудникам быть в курсе загрузки новой версии.

Подготовка проекта


Ну а теперь о самом интересном — подготовке проекта. Главный момент — наличие Fastlane, это можно проверить при помощи Homebrew, менеджера зависимостей. Написав в папке с проектом fastlane init получаем набор конфигфайлов. Их, правда, нужно отредактировать для того, чтобы все работало, как нужно.


Для редактирования конфигов требуется перейти в папку Fastlane, где открыть основной конфигурационный файл с названием Fastfile. Здесь прописываем два публичный лейна — первый отвечает за тесты, второй — за линтер. Соответственно, если система обнаружит внесенные изменения, то запустится и тест, и линтер.

После редактирования конфигурационных файлов нужно прописать в папке с проектом (из командной строки) Fastlane test и lint. Таким образом выполняется запуск набора команд, а также тестов и линтера с отображением результатов тестирования.


Ну а теперь добавляем еще и отбивку в Slack, для чего потребуется создание приватного лейна, который можно будет использовать в рамках других публичных лейнов. Собственно, нам нужен «лейн-универсал», который сможет принимать схему приложения, получать актуальные версии билдов и отправлять в Slack сообщения о загрузке.

Как только все будет готово, можно переходить к загрузке в Appstore — здесь потребуется написать универсальную функцию, которая будет состоять из нескольких этапов:

  • Вызов match — готовый скрипт, который отвечает за получение сертификатов, провайдинг-профайлов и т.п. Если их нет, он установит их на рабочую машину, с тем, чтобы можно было собрать и отправить все необходимое в AppStore. Скрипт tell_uploaded_to_slack отправит в зависимости от схемы нужное сообщение в Slack. Важный нюанс — Fastlane в своем скрипте match предлагает хранить сертификаты в репозитории.


  • Создание приватного репозитория, добавив все машины, которым нужен доступ к сертификату и их SSH-ключи. Это нужно для того, чтобы все Cl смогли получать актуальные и новые сертификаты.
  • Открываем три конфига: Matchfile, Deliverfile и Appfile. Они находятся в той же папке, где и Fastfile. Matchfile нужен для сздания URL репозитория с сертификатами. Deliverfile для указания App ID, для которого будет совершаться загрузка. Appfile нужен для использования актуального сертификата. Не забудьте уточнить apple_id и team_id, после чего все заработает.
  • Теперь пишем публичные лейны, обработчик ошибок (отбивает ошибки из консоли в Slack) и, при необходимости, автоматическую загрузку dsym. Последнее — символы отладки, которые используют аналитики, крэшлитики для расшифровки логов падения приложений. Первый лейн загружает dsym для Live-версии в Appstore, то есть для актуальной на текущий момент времени. А dsym_all просто загружает все dsym подряд начиная с установленной даты.


Учим GitHub командовать нашей машиной


Для того, чтобы это сделать, требуется перейти к папке с проектом в скрытой директорию .github, где выбираем директорию workflows. Здесь нужно создать несколько yml-файлов, описывающих определенные скрипты, которые запускаются при наступлении определенных условий.


Первым делом нужно создать дефолтный yml-файл, который будет запускать все проверки, которые мы описывали в самом начале – это линтер и тесты. В структуре файла нужно объяснить значение ряда элементов:

  • Name декларирует имя текущего workflow. Он указывает на условия, при которых будет срабатывать этот workflow.
  • Дальше у нас идет перечисление job со своими шагами. Любой элемент job должен начинаться с шага actions/checkout. Он указывает на то, что мы сейчас тянем актуальные изменения из репозитория. Причем мы готовы к запусканию обычного shell-скрипта, то есть fastlane ios lint запустит линтер и faslane ios tests запустит тесты.
  • Upload_prod и upload-dsym будут устроены несколько сложнее. Здесь появляется другое условие – on: [workflow_dispatch]. Оно говорит нам о том, что данный workflow может быть запущен только вручную.

Для того, чтобы Fastline корректно взаимодействовал с iTunes Connect, нужно хранить и каким-то образом шерить сессию, особенно, если есть больше одной Cl-машины. Чтобы обеспечить корректную работу можно предлагаю хранить кукисы от spaceship внутри вашего репозитория. Да, это достаточно опасно с точки зрения ИБ, но главное — понять механику, а потом уже можно придумать собственный механизм передачи кукисов.


Для решения проблемы запускаем команду Fastlane Spaceship с указанием юзера для создания папки .fastlane, внутри нее папочка spaceship с e-mail вашего аккаунта. Ну а здесь уже и размещается куки-файл. Его можно брать и помещать в папку репо, после чего научить GitHub обновлять токен. Т.е. доставать из репозитория актуальные куки и копировать ее в соответствующую папку Fastlane, Spaceship и класть на конкретную машину, на которой будет запускаться CI.

Для того, чтобы сделать процесс менее опасным, можно для текущего workflow включить ручную передачу какого-то параметра, которым будет как раз эта сессия. То есть, через интерфейс GitHub передавать в конкретный момент времени актуальную сессию.

Ну а теперь — о выборе места запуска Cl


Здесь может быть несколько вариантов.

Использование GitHub раннеров. Это проблема, поскольку раннеры шареные, значит, ими пользуются команды по всему миру. Машины же универсальные и не заточены под конкретный проект. Все это означает увеличение времени на проверки, плюс может понадобится ждать, когда освободится машина.

Локальное размещение — дома или в офисе. Если нет опыта, лучше так не делать, поскольку обеспечить бесперебойную работу для раннеров крайне сложно. А перезагрузки будут влиять на работу системы. Кроме того, Mac Mini и MacOS – это не совсем серверные операционные системы. Возможно, придется чуть-чуть допиливать систему, то есть отключать автоматические обновления, возможно, какие-то лишние службы. И конечно же, нужно будет иметь удаленный доступ к машине, и он должен быть безопасным.

Третий вариант — это как раз хостинг с macOS® на M1 от Selectel. О нем подробнее, поскольку мы воспользовались именно им.

Подробности настройки хостинга от Selectel



Здесь все просто — мы воспользовались конфигуратором в панели управления Selectel, где выбрали нужный сервер и подходящий тарифный план — 5 ТБ в месяц.


После подтверждения выбора выполняется конфигурация сервера, которая занимает 15 минут, и заказчик получает доступы. Все необходимые пакеты, включая Ruby, Homebrew, уже установлены.


Рекомендация — обновить Homebrew, а затем Aria2, это умный загрузчик.

Благодаря тому, что проект размещается на хостинге, скорость работы ускоряется в разы. Проект качается в считанные минуты. Ну а когда XIP уже на жестком диске, нужно разархивировать проект, переместить его в папку с приложениями, затем указать адрес Xcode. Ну и после этого — установить Fastlane и скопировать SSH-ключ для доступа к репозиторию сертификатам, потому что нам необходим будет доступ с этой машины, чтобы match мог подтянуть все сертификаты.


Следующий этап — запуск GitHub раннера при помощи форка, который поддерживает новую версию .NET Framework. В седьмой версии есть поддержка сборки под ARM. Все, что нужно сделать — перейти в папку с исходниками и запустить dev.sh. После этого в папке _layout будут артефакты от сборки, то есть готовый бинарь, который будет собран именно под arm-архитектуру. И вот после этого шага все можно делать уже по инструкции с GitHub. Последний шах — запуск раннера.

Важный нюанс — проблем с софтом на М1 практически нет. Почему? Все просто:
  • Ruby прекрасно работает нативно. Homebrew также работает нативно, потому что он под капотом использует Ruby.
  • JVM работает нативно на Arm.
  • И естественно, Fastlane тоже работает нативно, потому что это набор Ruby-скриптов.
  • Даже CocoaPods тоже работает нативно.

Рай, да и только.


Проблема может возникнуть лишь с Unit и UI-тестами. Причину проблемы в этом случае можно найти благодаря поиску по проекту.

В качестве вывода


Что касается нашей компании, то используем М1 не только мы, iOS-разработчики, но и Android-команда.


Результаты впечатляют — в случае со сборкой iOS-проекта под тесты мы получили плюс 40%, а в случае со сборкой Android – 45%. Это clean build, поэтому разрыв весьма впечатляющий.

В целом, M1 бояться не стоит. Наоборот, если изначально казалось, что это один большой костыль, то потом, разобравшись, стало понятно, что очень много всего поддерживается нативно. Соответственно, при переезде на М1 можно получить существенный прирост производительности.

Теги:
Хабы:
+40
Комментарии 2
Комментарии Комментарии 2

Публикации

Информация

Сайт
selectel.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Влад Ефименко