Это цикл статей, посвященных построению и архитектуре KMP SDK. Содержание для удобства навигации:

  1. Построение KMP SDK: наш опыт, плюсы и минусы, и как это изменило разработку

  2. Построение KMP SDK: базовая архитектура для общей библиотеки

  3. Построение KMP SDK: проектирование архитектуры для feature-модулей

  4. Построение KMP SDK: единая дизайн-система и управление ресурсами

  5. Построение KMP SDK: инсайты и подводные камни из нашего опыта

Вот и время для заключительной статьи этого цикла. В предыдущих статьях мы рассмотрели нашу мотивацию, всю техническую информацию и поделились инсайтами при создании масштабируемого бизнес-решения в виде кроссплатформенного SDK. В этой небольшой статье хотелось уделить внимание иным аспектам, таким как адаптация процессов команды KMP и смежных команд, которые являются заказчиками, немного поговорить про подходы к тестированию и контролю качества, CI/CD и т.д.

Кратко напомним про контекст и продукт: Instories — мобильный видеоредактор для маркетологов, SMM-специалистов и блогеров. Контекст проекта: желание получить ряд SDK (мы называем их Kit-ами, по сути это разные сборки SDK для разных продуктов, со своими ресурсами, фичами и дизайн системой) для наших уже существующих приложений, которые содержали бы в себе коробочные фичи (и бизнес-логику, и UI), готовые к подключению, а также были бы легко расширяемыми и переиспользуемыми для разных приложений компании.

Про внедрение KMP в процессы команд и мотивацию

Когда мы только начинали внедрять KMP, iOS-разработчики относились к этой технологии довольно скептически. Это было ожидаемо - новые технологии часто вызывают настороженность, особенно когда речь идет о кроссплатформенной разработке. Нам потребовалось время, чтобы доказать эффективность этого подхода. Сейчас ситуация кардинально изменилась — команда iOS видит реальные преимущества и то, как наш SDK упрощает их работу.

После успешного теста технологии, мы выделили отдельную команду для разработки KMP с разработчиками, тестировщиком, продукт-менеджером и дизайнером, и организовали процесс следующим образом: работаем двухнедельными спринтами, где команда самостоятельно занимается продуктовой составляющей - собирает требования и приоритезирует задачи в беклоге. Такой подход позволяет нам быть более автономными и эффективными. Для более прозрачного отслеживания прогресса мы внедрили дополнительный статус в Jira для задач, которые уже реализованы в KMP, но еще не интегрированы в платформы. Это помогает всем участникам процесса четко видеть, где находится та или иная фича в процессе разработки.

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

Особое внимание мы уделяем архитектуре наших решений. Все фичи разрабатываются максимально независимыми, чтобы их можно было легко встраивать в различные продукты без необходимости привлекать ресурсы других команд. Это значительно ускоряет процесс интеграции и уменьшает зависимости между командами. Конечно, процесс code-review является очень важным в данном случае, поэтому мы дополнительно пользуемся ai-агентами для проведения ревью кода. Да, они платные, но все это снижает нам риски в таком критическом ресурсе, у которого с каждым спринтом становится все больше и больше зависимых продуктов.

Для удобства разработки и тестирования мы создали систему сэмплов. У каждого Kit-а есть свой семпл - это простой экран с набором кнопок, где каждая кнопка ведет на определенную KMP-фичу с mock-контрактами. Сэмплы легкие и компактные, что позволяет быстро проверять работу кода как на iOS, так и на Android. Более того, эти же сэмплы оказались очень удобными для дизайн-ревью - в них часто даже проще просматривать различные состояния экранов, чем в основном приложении.

Интересно, что наши успехи не остались незамеченными — некоторые iOS-разработчики, увидев скорость и эффективность нашей работы, проявили интерес к KMP. Сейчас мы прорабатываем план, как можно плавно вовлечь их в разработку, дать возможность поработать с проектом и реализовать несколько простых фич. С появлением AI-ассистентов этот процесс стал значительно доступнее — новичкам стало проще разобраться в кодовой базе и начать писать код.

Про тестирование и автотесты

Часть продуктов в нашей компании тестировщики проверяют вручную, другую часть тестируют UI-автотестами на Appium+Python. Когда появилась наша библиотека, мы, очевидно, также стали тестировать ее вручную. Также зафиксировали, что необходимо покрывать unit-тестами слой domain (usecases и scenarios) и view-модели. Для unit-тестов выбрали стандартный стек на базе JUnit5.

Про автотесты заговорили чуть позже, когда стало понятно, насколько это теперь важная часть продуктов и компании в целом. Самый главный вопрос, который мы пытались решить: а нужно ли бросаться на автотесты. Да, это модно, интересно для QA-инженеров, однако автотесты — довольно дорогостоящее для компании занятие. Более того, UI-автотесты рекомендуется применять для уже устоявшихся продуктов, где мало изменений и плавная разработка. Данный проект точно не такой, поэтому вопрос с автотестами сейчас отложен для нас на неопределенное время. Однако, если вы сталкиваетесь с похожей задачей, советует исходить из ситуации и количества ресурсов вашей компании.

Про CI/CD

В качестве CI/CD мы используем Github Actions. В целом настройка была очень похожа на настройку окружения под сборку Android приложений, однако были нюансы (куда же без них).

Начнем с Android. Во-первых, благодаря тому, что проект многомодульный, на выходе получалось много артефактов. Это не плохо, и даже хорошо, но занимает место в хранилище Github. Поэтому мы решили сделать пайплайн сборки артефактов ручным для сборки по необходимости.

Другой неприятный момент обнаружился, когда мы захотели публиковать артефакты, скомпилированные под разные Kit-ы. Было сразу очевидно, что в один репозиторий публиковать артефакты с одинаковыми названиями не выйдет, поэтому мы создали по репозиторию-пустышке под каждый Kit. Но и так тоже не вышло: оказывается, Github вообще не позволяет публиковать артефакты с одинаковыми названиями внутри компании даже в разные репозитории. Гневный тред про это ограничение существует в их багтрекере уже более 7 лет, но приходится адаптироваться. Таким образом, концепция разных репозиториев себя не оправдала, и мы решили выкручиваться версионированием: при сборке Kit-а, он пубиликуется в хранилище с версией “${SdkVersion}-${KitName}”. Таким образом, в Android приложениях невозможно ошибиться, и сразу понятно, к какому Kit-у относится артефакт.

В iOS все тоже не очень радостно: сам проект из-за Compose Multiplatform в релизной конфигурации собирается достаточно долго (около 40 минут, при этом мы пробовали собирать Hello World и ситуация аналогичная). Это очень большие траты на виртуалки MacOs, поэтому решено было собирать на локальных машинах, и собранные артефакты уже публиковать в Github. Для этого разработчики из iOS команды написали ряд bash-скриптов, так что их процесс стал не таким уж и болезненным. При этом стоит отметить что дебажная локальная сборка учитывает кеш KMP и при разработке собирается 1-2 минуты.

Для того, чтобы не путаться в версионировании, на каждый коммит у нас есть пайплайн, в котором мы Python-скриптом обновляем версию SDK (patch из паттерна major.minor.patch), инкрементируя ее. Также мы прикрутили нотификации в Slack: при каждом обновлении develop, будь то вливание MR или просто коммит, в специальный канал приходит сообщение от бота с диффом относительно предыдущего сообщения и новой версией SDK. В итоге получилась довольно удобная система с минимальными рисками ошибок, где каждый может четко видеть что было изменено и в какой именно версии SDK.

Про документацию

Когда другие команды начали активно интересоваться и использовать наши фичи, стало ясно, что нужна хорошая документация. Специального человека для её написания у нас нет, поэтому мы с командой договорились о простых правилах: разработчики описывают технические моменты, а продуктовый менеджер занимается продуктовой документацией отдельно.

Особенно внимательно мы относимся к документированию изменений в контрактах между модулями. Тут действует простое правило - даже если вам кажется, что из названия метода все понятно, все равно нужно добавить описание. Практика показывает, что разработчики все равно будут задавать вопросы, и это нормально. Поэтому мы всегда следим за тем, чтобы:

  • Названия классов и методов были понятными

  • В коде были полезные комментарии

  • В Notion была документация по общему шаблону

Такой подход здорово экономит время - вместо долгих созвонов и переписок с коллегами по поводу интеграции, мы просто отправляем ссылку на документацию, где все уже описано.

Мы также нашли интересное решение для упрощения процесса документирования. Так как все наши фичи построены по одинаковой структуре и не зависят друг от друга, мы начали использовать Cursor для создания базовой документации. AI-помощник отлично справляется с описанием того, как интегрировать фичи в приложения. Нам остается только проверить, что все описано правильно, и добавить специфические детали если нужно.

В общем, хотя поддержка документации — задача не самая простая, мы нашли способы сделать этот процесс менее трудоемким. Четкие правила и современные инструменты помогают нам держать документацию в актуальном состоянии, не тратя на это слишком много времени.

Заключение

Подводя итоги нашего опыта работы с Kotlin Multiplatform и Compose Multiplatform, можно с уверенностью сказать, что технология - это только часть успеха. Не менее важными оказались правильно выстроенные процессы, эффективная коммуникация между командами и постоянное внимание к качеству продукта.

Мы прошли большой путь от первых экспериментов с KMP до создания полноценной системы разработки и доставки кроссплатформенных решений. За это время изменилось не только наше техническое понимание, но и подход к организации работы. Мы научились лучше взаимодействовать с платформенными командами, оптимизировали процессы разработки и тестирования, создали эффективную систему документации.

Особенно приятно видеть, как изменилось отношение к технологии со стороны iOS-разработчиков - от первоначального скептицизма до активного интереса и желания участвовать в разработке. Это лучшее подтверждение того, что мы движемся в правильном направлении.

Надеемся, что наш опыт поможет другим командам, которые стоят перед похожими вызовами. Главное — помнить, что успех кроссплатформенной разработки зависит не только от выбранной технологии, но и от ваших задач, от того, как грамотно вы будете использовать эту технологию и как выстроите процессы вокруг неё.

Пара слов про любовь

Дорогие читатели! Спасибо, что были с нами в этом путешествии и нашли время прочитать данный цикл статей! Несмотря на то, что многая техническая информация под NDA, мы очень старались максимально полно и подробно рассказывать про свой опыт и делиться важными и полезными инсайтами, которые мы зафиксировали для себя во время разработки. Сейчас этот проект с кроссплатформенным SDK уже достиг стадии стабильного продукта, при этом технический долг практически не копится, а новая функциональность внедряется очень быстро и качественно за счет хорошо проложенных рельсов. Пожалуйста, поддержите нас: скачивайте Instories и Vids приложения и пробуйте самостоятельно найти фичи, которые сделаны на KMP! ? Ждем ваши предположения в комментариях.

Также, конечно, хотелось бы сказать спасибо любимой команде NP состава декабря 2024 (расшифровку, с вашего позволения, оставим при себе), которая не боится экспериментировать и работать в духе стартапа! Если бы не вы, такой крутой проект точно бы не смог появиться на свет. Горжусь работать с вами! <3

Предыдущая статья: Построение KMP SDK: единая дизайн-система и управление ресурсами

Комментарии (2)


  1. ivanopulos
    03.10.2025 19:52

    продажи подросли?


  1. blik13
    03.10.2025 19:52

    Вот и время для заключительной статьи этого цикла.

    Все так долго ждали выхода этой заключительной статьи...