Тестирование конвейера релизов с помощью Fastlane

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Пару недель назад я выступил с докладом о том, как обрести уверенность в процессе релиза, на Mobile Devops Summit, дистанционном мероприятии, организованном Bitrise. В конце концов, я подумал, что было бы неплохо написать статью с описанием специфики выступления и мотивов, стоящих за ним.

Если вы пропустили выступление и хотели бы его посмотреть, я выложил запись на моём канале Youtube.

Мотивация

Для разработчика iOS есть определённые конвейеры CI (continuous integration – непрерывная интеграция), которые имеют решающее значение для доставки приложения, но из-за своей природы они не запускаются часто. Отличным примером этого является конвейер релиза, который автоматизирует архивирование приложения, его подписание и отправку в App Store Connect и запускается только тогда, когда приложение готово к релизу.

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

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

Ошибки архивации

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

Давайте рассмотрим модульное приложение для iOS, которое определяет iOS 15 как минимальную версию для развёртывания. Мы хотим представить новую функцию, полностью созданную с помощью SwiftUI, поэтому мы создаём новый модуль Schedule (как Swift package):

Package.swift

// swift-tools-version: 5.6
import PackageDescription

let package = Package(
    name: "Schedule",
    products: [
        .library(
            name: "Schedule",
            targets: ["Schedule"]
        )
    ],
    dependencies: [],
    targets: [
        .target(
            name: "Schedule",
            dependencies: []
        ),
        .testTarget(
            name: "ScheduleTests",
            dependencies: ["Schedule"]
        )
    ]
)

Затем новый модуль импортируется целевым приложением и отображается при необходимости. Приложение можно собрать, тесты проходят нормально, новое view (представление, вью, вьюшка) выглядит великолепно, теперь приложение использует SwiftUI!

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

Смотрим на журнал сборки выше: похоже, что приложение архивируется для armv7. Проблема здесь в том, что SwiftUI недоступен в SDK armv7, из-за чего компилятор не может найти символы SwiftUI. Посмотрев на некоторые связанные ветки форума разработчиков Apple, пришёл к выводу, что если приложение имеет минимальную версию развертывания iOS 11 или выше, его не следует создавать для этой архитектуры.

Так что же происходит? Что ж, после многократных попыток исправить ошибку выясняется, что даже несмотря на то, что новый пакет импортируется target с минимальной версией развертывания iOS 15, минимальная версия iOS должна быть установлена под platforms (платформами) в Package.swift для того, чтобы ошибка исчезла:

Package.swift

// swift-tools-version: 5.6
import PackageDescription

let package = Package(
    name: "Schedule",
    platforms: [
        .iOS(.v15)
    ],
    products: [
        .library(
            name: "Schedule",
            targets: ["Schedule"]
        )
    ],
    dependencies: [],
    targets: [
        .target(
            name: "Schedule",
            dependencies: []
        ),
        .testTarget(
            name: "ScheduleTests",
            dependencies: ["Schedule"]
        )
    ]
)

Обратите внимание, что эта ошибка характерна для Xcode 13 и не является проблемой для Xcode 14.

Ошибки загрузки

Теперь, когда мы увидели ошибку архивирования, давайте рассмотрим пример ошибки загрузки. Давайте теперь рассмотрим, что новый модуль SwiftUI вместо этого является фреймворком (в проекте Xcode) и используется разными target. Каждый из них встраивает и подписывает фреймворк.

Приложение собирается, запускается и архивируется без проблем, но как только оно загружается в App Store Connect, возникает ошибка:

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

Раннее обнаружение этих ошибок

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

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

Идея, стоящая за ними, заключается в том, что вы можете запланировать повторный запуск вашего конвейера в определенную дату и время, используя cron expressions. В следующих разделах я создам Github Action, которое заархивирует приложение, подпишет его для App Store, а затем проверит двоичный файл с помощью App Store Connect с помощью fastlane.

Реализация nightly Github Action

Создание nightly lane

Давайте начнём с просмотра того, как выглядит lane релиза в Fastfile:

Fastfile

lane :release do
  # Let's make some magic happen 						
Источник: https://habr.com/ru/post/718540/


Интересные статьи

Интересные статьи

Многие компании используют контейнеры в качестве фундаментальной технологии для управления своими приложениями и их выполнения. Если вы уже имеете опыт работы с контейнерами, то понимаете их мотивац...
К старту флагманского курса по Data Science рассказываем о суперпикселях, которые улучшают сегментацию данных, и знакомим читателей с платформой Kili Technologies, в инструментах которой они реализова...
В последние несколько лет я часто задумывалась о том, что означает качество. У меня были и лекции на эту тему, и дискуссии с различными людьми. Недавнее обсуждение в Link...
Меня зовут Иванов Александр, я тестирую приемники цифрового телевидения. В статье расскажу о том, как наша команда GS Labs набралась смелости и сменила неудобный и д...
Helmfile — обёртка для helm, которая позволяет в одном месте описывать множество helm релизов, параметризовать их чарты для нескольких окружений, а также задавать порядок их деплоя. О самом helm...