Всех приветствую. Это третья заметка про мой небольшой Android-проект - интервальный таймер для тренировок.
Кратко напомню контекст: в качестве небольшой практики я пишу приложение для интервальных тренировок, с гибкими интервалами, поддержкой пульсометров, выбором звуков, настройкой ритма и историей тренировок. Приложение бесплатное, без подписок, навязчивой рекламы и ограничений по функционалу. Ссылка на приложение в русторе - в конце статьи.
На текущий момент уже вышла версия 0.4.0. В этой статье кроме изменений в самом приложении, хочу немного рассказать о самой разработке, а именно об автоматизации релизной рутины при помощи скриптов. Т.к. с развитием проекта появляется все больше обязательных действий, которые напрямую не связаны с написанием кода, но все равно нужны: тестовые данные, миграции, скриншоты для релиза, сборки, подпись APK и т.д., то появляются мысли эти процесс оптимизировать/автоматизировать.
Что появилось в версии 0.4.0
Главное изменение с прошлой версии - история завершенных тренировок. Теперь завершенные тренировки можно посмотреть в отдельном разделе в формате календаря по дням.
Для каждой записи есть подробности:
Также в новой версии переработан "Ритм" - бывший "Темп". В 0.3.0 в приложении можно было задать темп в BPM. Теперь ритм можно задать либо напрямую в BPM, либо через количество повторов за интервал и приложение само посчитает нужный темп, исходя из количества повторов и длительности рабочего интервала. Для звука ритма можно выбрать стандартный тик или одну из сохраненных голосовых записей.
Почему скрипты, если ИИ "может делать все сам"?
В первых версиях многое из рутины делалось руками: ввод команд для сборки APK, перекидывание файла на телефон, установка, скриншоты и т.д. Но с развитием проекта эти процессы стали занимать все больше времени. Особенно когда надо протестировать на телефоне очередные небольшие изменения.
Следующий этап был через промпты для агента. Я уже не вводил все команды руками, а писал агенту: собери приложение, установи на телефон, сделай набор скриншотов и т.д. Это уже было удобнее, но все равно оставалось больше ручным процессом, чем автоматизацией. И при этом периодически случались косяки, особенно на сложных операциях вроде подготовки скриншотов для релиза.
Очевидным следующим шагом стали скрипты. Действия, которые можно полностью или почти полностью автоматизировать, лучше четко описать один раз в скрипте, а агента потом просить запускать уже готовые команды.
Какие скрипты сейчас используются
Сейчас скрипты помогают автоматизировать часть релизной рутины, а именно:
заливают тестовые данные в debug-версию приложения: тренировки, интервалы, настройки пульса, ритм и историю тренировок;
проверяют обновление с предыдущей версии на новую. Для 0.4.0 это был сценарий 0.3.0 -> 0.4.0: поставить старую версию, заполнить ее данными, обновить поверх и убедиться, что ничего не потерялось;
собирают список UI-элементов из Compose-кода и обновляют карту координат на реальном телефоне, чтобы сценарии скриншотов не зависели от ручных нажатий;
снимают скриншоты по заранее описанному плану: открывают нужные экраны, проверяют ожидаемый текст, делают исходный скриншот и готовят копию для RuStore;
собирают release APK, проверяют подпись, архивируют файл, считают SHA256 и сохраняют build-info.md и checksums.txt в релизный пакет.
Самый важный сценарий для 0.4.0 - проверка обновления с предыдущей публичной версии. Для этого скрипт устанавливает специальную debug-сборку 0.3.0, заливает в нее тестовые данные, а потом ставит 0.4.0 поверх старой версии без очистки данных.
Задача простая: убедиться, что после обновления у пользователя ничего не пропадет и не сломается.
После обновления скрипт проверяет, что приложение запускается, тренировки видны и открываются, а новые поля базы получили безопасные значения по умолчанию.
И только после этого добавляются данные, которые появились уже в 0.4.0: история завершенных тренировок за разные дни, подробности истории и т.д. То есть скрипт не просто заливает демо-данные, а прогоняет почти весь релизный сценарий обновления.
Один из самых муторных процессов перед релизом - скриншоты. Для стора нужны скриншоты конкретных экранов с нормальными данными: главный экран, редактор тренировок, активный таймер, история и т.д.
Раньше это делалось руками: открыл экран, сделал скриншот, перешел дальше, снова сделал скриншот, потом перекинул файлы на комп.
Потом процесс стал полуавтоматическим: я просил агента подготовить план и сделать скриншоты. Сначала в режиме подтверждения - я подтверждал, что нужный экран открыт, после чего он делал скриншот. А потом пытался сразу промптом попросить его сделать план и пройти по нему полностью автоматически. Но без скрипта это выглядело грустно: медленно и с косяками.
Третий этап (сейчас) это уже делается скриптами.
После того, как debug-версия получает тестовые данные через adb run-as, происходит следующий этап - собирается карта интерфейса. Один скрипт проходит по Compose-коду и формирует список UI-элементов, которые могут понадобиться для сценариев съемки. Затем другой скрипт через uiautomator dump читает текущий экран на реальном телефоне, находит нужные элементы, снимает их точные координаты и собирает итоговую карту интерфейса.
список возможных UI-элементов
выбранные элементы для съемки
реальные координаты на устройстве
сценарий скриншотов
Дальше используется сам план съемки. В нем указываются не координаты, куда нужно нажать, а более глобально: "на экране main нажать control history, дождаться заголовка История тренировок, сделать скриншот 04-workout-history-calendar.png". Координаты подставляются уже из карты.
Дальше скрипт проверяет, что на экране появился ожидаемый текст, делает screencap, сохраняет исходный PNG в screenshots/raw, а затем готовит копию для RuStore.
Если интерфейс поменялся, сначала нужно обновить карту элементов. Когда карта актуальна, сам процесс снятия скриншотов проходит автоматически: данные подготовлены, переходы описаны, проверки заданы, файлы складываются в нужные папки.
Во-первых, стало существенно меньше ручной рутины. Перед релизом есть понятная цепочка: подготовить данные, проверить миграцию, снять скриншоты, собрать release, проверить подпись, архивировать APK, сохранить checksum и build info.
Во-вторых, стало проще работать с ИИ-агентом. Когда действие описано словами вроде "подготовь релиз", агент может угадать не все шаги, сделать их в неудобном порядке или вообще накосячить. А когда есть конкретные скрипты, задача становится гораздо точнее: запусти такой-то сценарий, проверь такой-то файл, обнови такой-то пакет.
В ближайших планах по развитию приложения:
показывать во время тренировки не только пульс, но и пульсовую зону;
добавить в историю тренировок график пульса с зонами, наложенный на интервалы;
сделать полный бэкап и восстановление данных, потому что сейчас импорт/экспорт покрывает только тренировки, а голосовые напоминания и историю сохранить пока нельзя.
Ссылка на RuStore Интервальный Таймер.