Осип Фаткуллин

Осип Фаткуллин

Неделя
Feb 7, 2022 → Feb 13, 2022
Темы

Архив недели @osiphd

Понедельник


Привет! Меня зовут Осип, работаю андроидом в @REDMADROBOT, люблю Open Source, изредка пишу в t.me/rareilly. Поговорим про: - Разработку для Minecraft (ага) - Open Source - Написание библиотек - Тулинг - Ещё что-нибудь (Ссылки на все треды буду закидывать в этот тред)

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

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

Чтобы поддержать моё стремление, мне купили книжку "Как ребята программировали игру "Африка" на языке Паскаль". Я не понимал ничего, что там объяснялось про "переменные", "процедуры" и "функции", поэтому просто открывал главу в конце и переписывал код к себе.

Если код работал, я радовался, если не работал - ждал папу с работы, чтобы он исправил ошибки компиляции. И каждый раз он говорил: "посмотри, тут же красным написано где у тебя ошибка". Так я научился важному навыку - читать и понимать ошибки компилятора :)

Я не понимал Pascal и мне не нравилось программировать, но всё поменялось в 9-м классе, в 2011 году, когда друг позвал меня играть в Minecraft :) Сначала мы играли на публичных серверах, но потом загорелись идеей сделать свой сервер, где сделаем всё так как нам нравится.

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

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

Чтобы решить проблему с железом, решили арендовать машинку. Выбор пал на "дедик" в Hetzner. Стоило это около 2000р. по курсу того времени. Мы с друзьями скидывались и несколько месяцев нам удавалось платить за аренду.

Началось познание мной Linux'а. После нескольких "окирпичиваний" сервера и писем в службу поддержки, чтобы они помогли мне всё починить, я научился не доводить сервер до состояния когда до него невозможно достучаться по SSH.

Где-то месяц я настраивал машинку чтобы на ней можно было запустить наш сайт и сервер. Благодаря этому периоду, я научился не бояться консоли и Linux'а. Ещё один навык, который был мне не раз полезен.

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

Тогда я решил, что стоит попробовать написать плагин самому. Я начал читать "Head First Java" и так увлёкся, что проторчал за компьютером всю ночь. Учить Java было безумно интересно и тогда я понял, что мне нравится программировать.

Кстати, сервер мы пытались запустить несколько раз, но ни разу не дошли до релиза. И этому опыту я тоже благодарен. Многие задачи были как во "взрослых" проектах. Например мы начали использовать Redmine и Asana потому что нужно было как-то отслеживать задачки.

Тогда же я проводил свои первые "собеседования", которые обычно ограничивались парой вопросов типа "покажи скрины карты которые ты строил?", "сможешь если будет нужно скинуться на аренду сервера?" :D

От постоянных неудач я перегорел и решил, что больше ну буду пытаться делать свой сервер. Но зато могу писать плагины, тем более что это мне нравится.

Так я написал свой первый большой проект - RPGInventory и опубликовал его на площадке для продажи плагинов по цене 7.5 USD за копию.

А потом я прочитал "Clean Code" дядюшки Боба и понял как же плохо написан мой плагин. Любая попытка внести изменения подтверждала это. Изменяю код в одном месте - ломается в четырёх других. Обилие статики, неявные зависимости и сильная связанность не давали развивать плагин.

Что в этом случае делать? Конечно же всё снести и написать заново! Так я решил в 2015 году. Превью нового плагина я выпустил в январе этого года :D Писать без знаний об архитектуре и тестах оказалось гораздо проще. RPGInventory я написал за пару недель.

Что-ж. Я затянул тред, поэтому теперь кратко. Как-то я попробовал писать на Groovy. Мне понравились Closure и лаконичность (после Java), но не понравилось, что многое в Groovy неявно. Тогда мой выбор пал на Kotlin, который сохраняет и краткость, и явность.

Я знал, что теперь хочу писать на Kotlin, поэтому сразу искал вакансии, которые предлагают Kotlin. И так вышло, все предложения были связаны с разработкой под Android. Спустя пару неудачных мест работы, я наконец попал на стажировку в red_mad_robot, а после и в компанию.

Если пока вы читали тред у вас было чувство, что это всё игрушки и баловство, посмотрите на "оффер" который прилетел недавно мне в Discord :D Оплата по пятницам раз в две недели, от 1890$ до 3360$ в месяц в зависимости от количества рабочих часов)
notion image

🔥Тред (Осип Фаткуллин)
Про мой путь в IT. Может быть это звучит как-то несерьёзно, но не получится рассказать как я пришёл в разработку, не рассказав про то как я разрабатывал плагиныдля сервера Minecraft.
Первый тред - про мой путь в IT, и как мне в этом помог Minecraft twitter.com/mobileunderhoo…

Вторник


Сегодня поговорим про #OpenSource. Один твит - один совет/наблюдение исходя из моего опыта. Поехали.

Кстати, будет классно, если вы тоже будете делиться своим опытом участия в Open Source.

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

Столкнулся с багом, нашел issue в репозитории библиотеки и лайкнул его? Ты великолепен! Если докинешь полезную для воспроизведения инфу или workaround который нашел, будет ещё лучше.

Нашёл новый баг, и вместо того чтобы писать у себя в проекте костыль со словами "ох уж этот Google" пошёл и завёл issue? Ещё лучше! Если никто не заведёт issue, велик шанс, что о проблеме ещё долго не узнают. В конце концов ты же заинтересован, чтобы баг устранили?

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

Например, мы в red_mad_robot, как и многие, плевались от реализации диплинков в androidx.navigation. А потом взяли и поправили баги которые отстреливали нам ноги: issuetracker.google.com/issues/1840728… issuetracker.google.com/issues/1855271… issuetracker.google.com/issues/1855271…

Кстати, оказалось, что эти фиксы кому-то сломали диплинки :( Прямо всё как в старом меме. xkcd.com/1172/
notion image

Перед началом работы над Pull Request'ом, обязательно согласуй изменения с командой разработки. Например, через issue. Нет ничего хуже чем потратить время, а в итоге получить закрытый PR с комментарием типа "this feature is out of the library scope".

Изучи contribution guide, если он есть. Если нет - смотри на историю коммитов и прошлые PRы. Старайся писать код "в стиле проекта". Всё это поможет сократить процесс ревью.

Наберись терпения. Ревью может (не)проходить долго, а может быстро. Зависит от проекта, от загруженности команды разработки, от их приоритетов, от фазы лунного цикла.

Причём нет прямой зависимости от количества изменений в PRе. Этому PRу с одной дополнительной extension-функцией уже 8 месяцев: github.com/gradle/gradle/… А этот PR с новым функционалом на +500 строк влили за два месяца: github.com/Kotlin/kotlinx…

Если делаешь фикс, обязательно сначала напиши тесты, которые покажут, что проблема есть. Желательно запушить тест отдельно, до фикса, чтобы CI упал и автор библиотеки мог это увидеть не запуская тесты самостоятельно. Это, конечно, при условии, что в проекте есть тесты.

Если PR можно разбить на несколько - разбивай. Несколько небольших PRов влить проще чем один большой и даже если один из PRов отклонят, остальные ещё могут влить. Такой подход, кстати, и в работе полезен.

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

Ревью может быть долгим, но можно сильно его сократить, если быстро вносить правки и реагировать на комментарии.

При добавлении нового или изменении существующего функционала не забудь изменить документацию.

Внезапный опрос. Участвуешь в open source проектах?
🤔 53.4% Нет
🤔 15.1% Завожу и лайкаю issue
🤔 16.4% ... и отправляю PRы
🤔 15.1% Сам пишу библиотеки

🔥Тред (Осип Фаткуллин)
Сегодня поговорим про #OpenSource. Один твит - один совет/наблюдение исходя из моего опыта. Поехали.
Второй тред. twitter.com/mobileunderhoo…

Среда


Могут быть разные причины чтобы написать библиотеку. Какой-то кусок кода кочует из проекта в проект? Или есть страшный костыль, который хочется ото всего изолировать и красиво упаковать, чтобы больше никому не пришлось писать такой же костыль?

Для себя я принял за правило, что оформляю что-либо в библиотеку только если сам буду это использовать. Писать библиотеку, которая тебе не нужна и надеяться, что она будет нужна кому-то ещё - пустая трата времени.

Ещё хороший вариант обстучать идею об лида или других разработчиков

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

Никому не нужна документация библиотеки на 10 языках, если библиотека при этом не работает как надо.

Хорошо. Представим, что делаем библиотеку для использования внутри компании - так будет проще.

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

Структура пакетов. Это не приложение и здесь никакой необходимости делать сложную структуру пакетов - она только запутает пользователя библиотеки. Ещё один бонус - чем проще структура, тем меньше мусора будет в импортах.

Отделяйте внешний API от деталей реализации, которые API не являются. Хороший подход - класть внутрянку в отдельный пакет, чтобы при импорте разработчик понимал что лезет куда-то не туда. Ещё лучше если язык позволяет ограничить видимость. В котлине пользуйте internal.

Не стоит затаскивать в библиотеку зависимости, которые нужны "для удобства": - DI? Пишем руками, ведь не известно какой DI-фреймворк у конечного пользователя. - Хочется реактивщины? Можно затащить, но только если реактивный подход является частью API.

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

Ещё хорошо бы вычищать лишние промежуточные зависимости. Например, библиотека зависит от kotlin-stdlib-jdk8, хотя использует только kotlin-stdlib. Или, пример хуже, тащим compose-foundation там ге достаточно compose-foundation-layout.

Дальше несколько kotlin-specific моментов. Модификатор доступа public по умолчанию это удобно, но так что-то лишнее может утечь в API. Включайте explicit API mode, тогда компилятор будет заставлять явно указывать модификаторы видимости и возвращаемые типы github.com/Kotlin/KEEP/bl…

Заранее стоит подумать нужна ли совместимость с Java. Проще сразу проставить нужные аннотации где надо, чем потом проходиться по всему проекту. kotlinlang.org/docs/java-to-k…

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

Если важна бинарная совместимость с прошлой версией, используйте валидаторы для проверки. Вот валидаторы для Java и Kotlin: lvc.github.io/japi-complianc… github.com/Kotlin/binary-…

Если бинарная совместимость не важна - всё равно используйте. Так вы точно не внесёте ломающие изменения "случайно".

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

Библиотека готова? Отлично! Теперь нужно чтобы другие разработчики поняли как её использовать. Первое, что они увидят - README, из него в первую очередь должно быть понятно: - Что это за покемон - Базовые сценарии использования - Как затащить в проект makeareadme.com

Если библиотека опенсорсная, то надо ещё лицензию указать и желательно readme писать сразу на английском. Лицензия скорее всего подойдёт MIT или Apache 2.0

Нужно ли писать wiki? По желанию. Моё мнение - гораздо важнее писать комментарии к функциям и классам, чтобы разработчик мог прямо из IDE получить ответы на интересующие его вопросы.

Ещё нашёл для себя крайне полезным постепенно заполнять changelog, по мере внесения изменений. Так меньше шансов не учесть какие-то изменения в release notes, особенно если новая версия готовилась долго. keepachangelog.com

Конечно, можно генерировать changelog из коммитов или из влитых PRов - круто, если вам подходит такой вариант!

Я ещё ничего не написал про CI, анализ кода и т.д. Потому что не стоит распыляться на инфрастуктуру пока библиотека не готова.

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

Если библиотека завирусилась и начала обрастать контрибьюторами, старайтесь упростить жизнь этим святым людям)

Можно уменьшить количество проблем на ревью настройками проекта. Например, настройки кодстайла можно пошарить с через файлик editorconfig. editorconfig.org

Кстати, ловите .editorconfig для Android-проектов. Рассортировал в нём все опции в таком порядке как они расположены в Android Studio и IDEA gist.github.com/osipxd/9a78649…

Если у вас есть идеи как улучшать проект - создавайте задачи в репозитории, не держите всё в голове. Так и вы не забудете что хотели что-то сделать, и, возможно, кто-то из внешних контриьбюторов сделает работу за вас.

Ещё один важный пункт о котором забыл. Уменьшайте "API surface", чем меньше разработчику нужно классов/функций/абстракций, чтобы начать использовать библиотеку, тем лучше.

Даже если кажется, что сейчас библиотека идеальна и в ней всё очевидно, не верьте этому чувству. Автор не может объективно оценить понятный API или нет, т.к. сам его написал.

Ну и самое главное, как всегда
notion image

На сегодня всё, а завтра будет про...
🤔 37.3% Тулинг
🤔 62.7% Хочу мемы!

Могут быть разные причины чтобы написать библиотеку. Какой-то кусок кода кочует из проекта в проект? Или есть страшный костыль, который хочется ото всего изолировать и красиво упаковать, чтобы больше никому не пришлось писать такой же костыль?
Среда - про написание библиотек twitter.com/mobileunderhoo…

Четверг


@mobileunderhood Почему опенсорс это обязательно библиотеки? Мы в компании всю разработку ведём open source github.com/flipperdevices
Не обязательно :) Просто взял как самый частый вариант. Почти всегда когда я пишу "библиотека" это может быть любой опенсорсный проект. Вы крутые! twitter.com/LionZXY/status…

Надо было другие варианты ответа делать. - Тулинг - Полное отключение телеграмма в России

🔥Тред (Осип Фаткуллин)
Кидайте самые странные/неуловимые/сложные баги, которые вам попадались!
notion image

Дисклеймер: я не обещал, что мемы буду смешные или свежие

Завели баг: в приложении часто вместо перехода на новый экран отображается просто белый экран. Фикс после исследования бага двумя разработчиками в течение нескольких дней: pic.twitter.com/7CabyBrD0t
Мой фаворит. До сих пор его не понимаю twitter.com/osiphd/status/…

Даже просто после прочтения описания возникает чувство...
notion image

Ещё один из категории "загадка дыры"
notion image

notion image

Не баг, но эльфийский костыль, который обзавёлся документацией
notion image

notion image

Ах да, чуть не забыл. Чуть ниже в этой вьюхе "с нулевой высотой" есть такое :D
notion image

Google issue tracker is...
notion image

Ещё одна нераскрытая тайна
notion image

🔥Тред (Осип Фаткуллин)
Кидайте самые странные/неуловимые/сложные баги, которые вам попадались! pic.twitter.com/NY1ARz5yoZ
Четверг - малая пятница. Тред про баги и костыли (и немного мемов) twitter.com/mobileunderhoo…

Пятница


@mobileunderhood А можешь сбросить какой-то gist с примером? Потому что это поведение просто раздражает. Сегодня с ним столкнулся в очередной раз.
Вот готовые реализации для Epoxy и Groupie gist.github.com/osipxd/45357cc… Если без использования этих библиотек, нужно просто у DiffUtil.ItemCallback всегда возвращать true для вьюхи-якоря в этих методах: twitter.com/kaganovychv/st…
notion image

Сегодня будет про тулинг: - Первое что ставлю на свежий ноут - Консольное - IDE - Проект

Пишу этот тред уже второй раз, потому что твиттер решил, что нужно меня разлогинить посередине процесса. Попробую чаще "сохраняться"
notion image

На macOS я перелез потому что на работе выдали ноут с ней. До этого сидел на ArchLinux с тайлингом (i3wm, а после SwayWM). Поэтому пытался приблизить интерфейс к привычному.

Тайлинг это когда окошки не "плавающие", а укладываются плиткой на экране. Каждое новое открытое окно делит экран пополам. Выглядит это примерно так (скрин с просторов интернета):
notion image

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

Поставил Spectacle чтобы управлять окошками клавиатурой и повесил биндинги на переход между рабочими столами, их у меня пять. На первом рабочем столе всегда IDE, на втором браузер, на третьем мессенджеры, на четвёртом консоль, на пятом может быть что угодно.

Кстати, сейчас вот пошёл гуглить, оказывается недавно на macOS сделали тайлинговый WM - Yabai. Надо будет глянуть на выходных. github.com/koekeishiya/ya…

Но ещё до того как поставить Spectacle, конечно же ставлю пакетный менеджер - Homebrew. Вообще пакетные менеджеры это гениально. Очень удобно когда все устанавливается, удаляется и обновляется "через одно место".

И уже после этого ставлю Spectacle через brew)

Второе, что было неудобно - раскладка клавиатуры. ГДЕ МОЙ Alt, КТО ТАКОЙ ЭТОТ ВАШ Option? Меняю местами fn и option через Karabiner-Elements. Раскладку в настройках выставляю PC.

Нет, не потому что мне лень переучиваться, а потому что не хочу держать в голове контекст за каким компом я сейчас сижу и какие из-за этого сочетания клавиш нужно прожимать.

Как-то раз подключил мышку и был обескуражен тем, что скролл колёсика инвертирован. Тут помогает Scroll Reverser.

Про браузеры и прочую ерунду писать не буду. Каждый использует что хочет.

Терминал. Я использую Kitty, потому что он есть и на macOS, и на Linux, а значит я могу пошарить настройки между компами

Ну и с настройками OS на этом всё. Перейду к консольным утилитам, т.к. многие задачи я решаю через консоль.

По умолчанию в macOS теперь используется zsh, но я сразу меняю его на fish. Люблю fish за его функционал "из коробки". Если интересно, почитайте мою прошлогоднюю статью про работу в консоли, там достаточно много про fish и про консоль в целом. habr.com/ru/company/red…

Вместо curl использую httpie. Там и синтаксис команд попроще, и вывод поудобнее
notion image

Чтобы смотреть файлики - bat вместо cat. Добавляет номера строк и подсветку синтаксиса
notion image

Когда забился диск, чищу его через ncdu. На скрине вот собираюсь почистить кэши Gradle
notion image

Если надо смотреть диффы из консоли, ставьте delta, с ней получается такая красота
notion image

Верный друг и помощник когда IDE выжрала всю память и зависла, не давая себя выключить - htop. И вообще посмотреть кто сколько жрёт.
notion image

На замену ls и tree можно взять exa c красивой подсветкой файлов по типам
notion image
notion image

Когда работаешь с JSON'ами сильно помогает jq. Она и отвалидировать JSON может, и отформатировать, и выкусить из него только то что нужно.
notion image

Менеджер паролей. Как я мог о нём забыть. Он у меня тоже консольный. Использую pass и безмерно им доволен потому что понимаю как он работает. Пароли шифруются GPG ключом который я сам перед этим сгенерировал, а шарятся между устройствами с помощью Git'а.

Для андроида есть приложуха чтоб смотреть пароли, синхронизировать git-репозиторий и т.д., а на компе проще из консоли скопировать, она у меня всегда открыта на четвёртом рабочем столе. pass -c и готово.

Ещё для поиска по имени файла можно использовать fd или fzf. Вон в fzf даже предпросмотр содержимого есть.
notion image

А для поиска файлов по содержимому ripgrep вместо grep. Он просто сильно быстрее

Для баловства: - tokei - чтобы посчитать количество строк в проекте - hyperfine - если бенчмаркаете вызовы консольных команд
notion image

А чтобы не забыть как этим всем пользоваться, помогает утилита tldr Вот вам tldr по tldr
notion image

А ещё, возможно вы заметили, я поставил себе в консоли цветовую схему Darcula из IDEA и шрифт JetBrains Mono :) Чтоб переход из IDE в консоль и обратно был максимально бесшовным.
notion image

Чтобы сохранять настройки всего этого счастья и шарить их между компами, использую YADM. Мои конфиги (dotfiles) лежат в гите и при необходимости я их синхронизирую. yadm.io

Перейдём к IDE. Простите, друзья iOS-еры, дальше не интересно будет. Я использую.. нет, не Android Studio :D Сижу в IDEA Ultimate и прекрасно себя чувствую.

Да, есть недостаток, что фичи Android Studio доезжают немного позже. Например, в IDEA 2021.3 плагин андроида соответствует Android Studio Arctic Fox 2020.3.1 Но есть огромное преимущество - работает стабильнее. Многие баги из Android Studio не доезжают до IDEA.

А ещё новые фичи IDEA прилетают раньше, и зачастую я их даже больше жду чем нововведений в AS.

Из плагинов. Detekt - чтобы сразу видеть что ему не нравится, а не узнавать об этом на CI. Archive Browser - чтобы смотреть содержимое всех архивов, а не только APK и подключенных библиотек. Conventional Commit - чтобы сообщения коммитов соответствовали гайдлайнам проекта

Ещё использую стандартный плагин Task Management. Благодаря ему почти полностью отпадает потребность ходить в Jira. Перевёл задачу в In Progress прямо из IDE и работаешь. А дальше автоматизации сами задачу по flow проведут.

Кстати, лайкайте этот твит, если интересно про автоматизации. Могу раскрыть эту тему подробнее, может и тред отдельный сделаю.

Понял, что забыл среди консольных утилит упомянуть scrcpy. Очень удобно, если нужно пошарить экран телефона в условный Zoom. Подключаешь телефон через scrcpy и шаришь.
notion image

Последняя часть - про инструменты которые помогают держать проект в чистоте.

Как уже писал во вторничном треде, кодстайл между участниками проекта шарим через editorconfig.

Шарим некоторые файлы из папки .idea: - dictionaries/project.xml - здесь проектные словечки, чтобы для них тоже работала проверка правописания - detekt.xml - настройки плагина detekt - externalDependencies.xml - плагины, которые нужны для работы с проектом

Ещё шарим vcs.xml. В нем кроме настроек репозитория ещё настройки для Issue Navigation хранятся. Issue Navigation это когда номера issue в IDE кликабельные и нажав на них можно сразу прыгнуть в issue-tracker.
notion image

На каждом MRе на CI гоняем detekt (с type resolution) и Android Lint. А результаты красиво отображаем в виде комментариев к MRу через Danger. danger.systems/ruby/
notion image

Это не всё что можно делать через Danger. В него можно любую нужную логику запихнуть: - проверять именование веток по правилам - смотреть количество изменений в ветке и исходя их этого вешать тег small, medium, large и т.д. - проверять, что нет лишних merge-коммитов из master

- через danger можно реализовать ревью-рулетку - проверять, не вносятся ли изменения в "опасные файлы" (например скрипты сборок, настройки линтеров) - подтягивать список задач сделанных в ветке и добавлять в описание - писать что нибудь приятное, если в MRе всё хорошо

Ещё на CI можно гонять отдельный линтер для сообщений коммитов, если у вас есть договорённости по их именованию. Тут поможет commitlint.

Кстати, если вам интересно про гит, для чего нужна чистая история, соглашения об именовании коммитов и т.д., то об этом и многом другом у меня был доклад на подлодке (доступ по ссылке). youtu.be/rR8ZnvLHnj8

Неплохие советы даёт компилятор Kotlin, поэтому считаем все warning'и ошибками с помощью флага -Werror

На этом всё. И вот я всё это рассказываю и мне стало интересно на чём нынче работают люди?
🤔 11.3% Linux
🤔 75.9% macOS
🤔 12.8% Windows

Суббота


Сегодня будет про тулинг: - Первое что ставлю на свежий ноут - Консольное - IDE - Проект
В пятницу залетает тред про тулинг twitter.com/mobileunderhoo…

Почему macOS?
🤔 21.1% Из-за железа
🤔 27.1% Из-за экосистемы
🤔 12.0% Просто выдали мак
🤔 39.8% Разрабатываю под iOS

А к пользователям Windows вопрос. Вы используете WSL или обходитесь без консоли совсем? Кто-нибудь использует менеджер пакетов Chocolatey?

🔥Тред (Осип Фаткуллин)
Кстати, лайкайте этот твит, если интересно про автоматизации. Могу раскрыть эту тему подробнее, может и тред отдельный сделаю.
Что-ж. Как обещал, попробую сделать тред про автоматизации. twitter.com/mobileunderhoo…

Когда-нибудь, когда у меня будет свой дом, я займусь автоматизациями в нём, а пока довольствуюсь автоматизацией flow работы.

Для меня в рабочем процессе есть две вещи, которые хочется максимально оптимизировать и автоматизировать. - Работа с треккером задач (у нас это Jira) - Код-ревью

Флоу работы с Jira у нас выглядит примерно так: - TODO - In Progress - Review - Resolved (задача вошла в релиз) - Done (задача протестирована и закрыта)

Почти всё дальше будет про JIRA, но некоторые общие подходы можно применить и с другими треккерами.

В In Progress хочется переводить в тот же момент когда создаёшь ветку для работы над задачей. В IDEA это можно сделать через плагин Task Management, а если такой вариант не подходит, можно использовать Raycast raycast.com

В ревью нужно переводить задачу в тот момент когда создан MR с ней. Тут я знаю два варианта: - На CI смотреть номера задач внутри MRa и через апишку менять им статус - Включить интеграцию Jira c GitLab/GitHub

В случае GitLab, интеграция с Jira есть прямо в настройках проекта. Там нужно указать креды для входа и адрес Jira, после чего все номера issue станут кликабельными, а при упоминании их в MR'ах в Jira будет добавляться комментарий об этом.

Это самая простая интеграция, есть более сложная, которая позволяет использовать разные триггеры и действия в Jira Automations.

Jira Automations это no-code конструктор автоматизаций. Сделан очень неплохо, позволяет даже переменные определять, ходить по циклам и всякое такое. Есть большое количество триггеров и действий, если чего-то не хватает можно самому дописать.

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

Базовая интеграция умеет оставлять комментарии если упомянуть issue в MRе, это и используем как триггер, чтобы перевести задачу в Code Review
notion image

Если бы интеграция была полноценная, костылить не пришлось и нужно было бы просто выбрать нужный триггер
notion image

Перевод Code Review работает, теперь нужно переводить в Resolved когда MR влит. Благо, что это умеет делать базовая интеграция в GitLab, но были случаи когда просто писали скрипт на CI, который закрывал все упомянутые в MR задачи при вливе.
notion image

Важно, что в GitLab автоматическое закрытие задач работает только если вы вливаете свою ветку в основную ветку проекта.

Но есть ещё проблема. После перевода задачи в Resolved нужно ведь ещё и Fix version указать, иначе задача потеряется и не попадёт в release notes. Тут снова помогают Automations. При переводе задачи в resolved автоматически проставляем ей ближайшую не выпущенную версию
notion image
notion image

Вся сложность в том как вычисляется значение {{nextVersion}}. Оно вычисляется с помощью Smart Values и выглядит это довольно страшно. Тут мы проходимся по всем версиям в проекте, достаём только те которые не выпущены и начинаются с буквы "a" (a - for Android) и берём последнюю
notion image

Отлично, перевод в Resolved тоже есть, версия проставляется, а дальше уже дело за QA.

Теперь хочется чтобы при закрытии версии, создавалась новая. Версия состоит из имени и кода и выглядит так: a1.0(42) Для простоты с именем ничего делать не будем, считаем, что меняется оно редко и раз в месяц можно и руками поменять. А вот номер должен всё время увеличиваться.

Опять идём в Automations и набрасываем автоматизацию на закрытие версии. Вся работа по инкременту происходит внутри объявления переменных, их содержимое в следующем твите.
notion image

Регулярками выкусываем нужные значения, а в конце составляем новую версию, но инкрементируем versionCode
notion image
notion image
notion image

Выпускать версию можно автоматически когда CI делает сборку. В качестве CD мы используем fastlane, поэтому эту задачу решаем через него плагинами jira_versions и jira_release_notes.

Ещё одно неудобство - чтобы всё работало как нужно, мы должны упоминать задачки в описании MRа. Если задач больше чем одна, руками это делать лениво. Тут помогает Danger на CI. Проходит по комментариям к коммитам, достаёт все номера issue и добавляет их в описание MRа.

В итоге получаем автоматизированный флоу, где от разработчика требуется: - Дать пинок - перевести задачу в In Progress - В коммитах указывать номер задачи А всё остальное сделают автоматизации.

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

Возможно в XCode ситуация другая, но в IDEA если у вас GitHub или Space - всё замечательно, есть официальные плагины которые показывают все PRы и позволяют быстро их спуллить, поревьюить и оставлять комментарии прямо из IDE. А вот с GitLab приходится мучиться.

Есть плагин Merge Request Integration - Code Review for GitLab, но у меня он работал очень нестабильно. Ещё пробовал CodeStream - тоже не без проблем, но ребята достаточно быстро реагируют на баги заведённые на GitHub.

Ещё в CodeStream есть возможность делать "быстрые ревью". Это когда ты посреди работы над фичой можешь выделить кусок кода и запросить ревью. А другому разработчику внутри IDE выскочит уведомление об этом.

Из дополнительных приятностей: Можно оставлять комментарии к коду, прокидывая их сразу в Slack (и не только). Можно открывать, закрывать и проводить по статусам issue из Jira (и не только). Если бы не редкие косяки с отображением комментариев в MRах, цены бы не было.

Как-то так. Хотел сделать тред про автоматизации, но вышло в основном про "наш процесс" :)

🔥Тред (Осип Фаткуллин)

Воскресенье


Писанина в твиттор слишком тяжело мне даётся чтобы заниматься ей ещё и в воскресенье, поэтому спасибо всем кто читал и спасибо @igrekde за предоставленную площадку! С вами был Осип (@osiphd), рад, если было полезно.

Жаль не успел на неделе рассказать про наши open source проекты, но вы и сами можете всё найти на этой замечательной странице. Зацените figma-export :) redmadrobot.github.io/opensource/

Не подписывайтесь на меня в twitter, а лучше заходите в tg-канал t.me/rareilly. Там я изредка пишу про всё что мне кажется интересным. В основном про android и около него.

Что-ж. Как обещал, попробую сделать тред про автоматизации. twitter.com/mobileunderhoo…
Незапланированный тред про то как устроена автоматизация флоу Jira на некоторых наших проектах twitter.com/mobileunderhoo…

🔥Тред (Осип Фаткуллин)

Ссылки