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

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

Сегодня встречайте Виталия Волкова из компании 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 можно получить существенный прирост производительности.

Читайте так же:

  • Помните Samsung Galaxy Note7? Целая партия смартфонов Vivo самопроизвольно сгорелаПомните Samsung Galaxy Note7? Целая партия смартфонов Vivo самопроизвольно сгорела Авиакомпания Hong Kong Airlines запретила перевозки на своих самолётах любых мобильных телефонов Vivo после того. Как несколько дней назад в аэропорту Гонконга загорелась партия смартфонов Vivo Y20. Гонконгский авиаперевозчик опубликовал соответствующее заявление только вчера. В нём […]
  • IPS-экран, Helio G90, 5100 мА•ч, 48 Мп, 8/128 ГБ и разъём 3,5 мм. Представлен Gionee M15IPS-экран, Helio G90, 5100 мА•ч, 48 Мп, 8/128 ГБ и разъём 3,5 мм. Представлен Gionee M15 Компания Gionee представила новый недорогой смартфон под названием Gionee M15, который построен на базе однокристальной системы MediaTek Helio G90 и оснащён до 8 ГБ оперативной и 128 флеш-памяти. Gionee M15 оборудован 6,67-дюймовой панелью IPS разрешением 1080 x 2400 пикселей. На задней […]
  • В 2022 году на Netflix появятся видеоигрыВ 2022 году на Netflix появятся видеоигры Netflix планирует в течение 2022 года добавить на свою платформу видеоигры. Брать дополнительную плату за новые контент сервис пока не собирается. Как сообщают источники на рынке. В ближайшие месяцы Netflix будет набирать команду для игрового направления и уже начал размещать […]
  • Успейте подготовить свой сайт к повышению нагрузки в Чёрную пятницуУспейте подготовить свой сайт к повышению нагрузки в Чёрную пятницу 5 ноября в 12:00 на вебинаре  команда Yandex.Cloud расскажет, как подготовить свой сайт и базы данных к пиковым нагрузкам в преддверии «черной пятницы». Как могут помочь в этом облачные решения и как быстро перенести инфраструктуру […]