Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on value of type null in /var/www/tgoop/function.php on line 65
462 - Telegram Web
Telegram Web
Как запускаются пайплайны и где выполняются

В предыдущем посте я уже по сути описал, как запускаются пайплайны: в каждой job указывается триггер, когда он срабатывает, все job собираются в кучу, выстраиваются в порядок и погнали.

Где выполняются пайплайны, а точнее сами job?

Чтобы ответить на этот вопрос, нужно накинуть немного контекста. Вот у нас есть сервер с CI, он рисует web-интерфейс, следит за git, отвечает за функционал создания МРов, запускает и создает пайплайны — всё такое. На этот сервер выделены какие-то ресурсы, т.е. он крутится на какой-то машине. И очень важно, чтобы сервер с CI был подобен алкашу в 21:59 – максимально быстрым.

Возвращаемся к Job. Для выполнения Job нужно определенное окружение. Если мы собираем Android-приложение, нужно, чтобы там, где выполняется Job со сборкой, была установлена JDK, а еще Android SDK, ну и желательно уже скачанный Gradle, чтобы не скачивать каждый раз. Помимо этого, сборка больших приложений — это очень дорого по памяти, нужно, чтобы её было много.

Если у нас более-менее большая команда, то будет создаваться много МРов. И вместе с этим будет запущено большое количество Job. Нам важно, чтобы сервер с CI не тормозил, и при этом чтобы сборкам хватало памяти и процессора. Для этого мы выполнение самих Job выносим на другие машины.

Выглядит это так: мы берем какой-то сервер, устанавливаем на него специальное ПО, которое называется Runner (он же агент в TeamCity). Всё, что делает этот Runner — коннектится к серверу CI как к материнскому кораблю и ждет команды. Когда CI нужно запустить какой-то пайплайн, она помещает список Job в очередь. Runner'ы, которые сейчас не заняты, забирают задачи из этой очереди и начинают выполнять Job.

Очень красивая система, которая позволяет масштабировать нашу инфраструктуру горизонтально. Поэтому даже если у нас будет создано огромное количество пайплайнов, это никак не повлияет на сервер CI. И мы можем в зависимости от нагрузки добавлять или убирать лишние Runner'ы. При этом мы еще и решаем проблему того, что например iOS приложение очень желательно собирать на Mac, а не linux машинах.

Осталась только проблема с окружением, и решается она крайне просто. У нас есть готовый Docker-образ с JDK, Android SDK и всем, что нам нужно для сборки. Когда Runner начинает выполнять Job, он сначала скачивает нужный образ (какой образ использовать, мы указываем в самой Job) и затем запускает нужные скрипты уже в рамках этого образа.
Ребятки, а поделитесь плиз в коментах, кто и как использует LLM в работе. Есть ли какие best practice, какой агент сейчас в топе и все такое? Интересен ваш опыт.
Что такое self-hosted runner?

Если вы пытались настроить GitHub Actions, то могли заметить, что там не нужно настраивать никакие Runner'ы. GitHub для опенсорс-проектов предоставляет какое-то количество бесплатных Runner с бюджетом по времени исполнения.

Другими словами, GitHub уже на своих серверах настроил Runner'ы и предоставляет вам доступ к ним. Это прекрасно работает на опенсорсных проектах или стартапах. Однако с ростом команды и компании у вас уже будут появляться ограничения.

Рано или поздно у вас в Job будут учавствовать какие-то закрытые API, которые вы не хотите открывать вне VPN. В этом случае вам помогут self-hosted runner. Вы разворачиваете ПО Runner'а на своих серверах, у которых есть доступ к внутреннему API, а весь менеджмент пайплайнов остается на серверах GitHub. Это удобно, потому как вам не нужно самим тратить время на поддержку всей CI системы, а только несколько серверов с Runner'ми.

Если же у вас в компании используется Gitlab на своих серверах, то очень вероятно, что у вас по умолчанию все Runner будут self-hosted.
Как артефакты передаются между job

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

👉 Переменные окружения
👉 Артефакты

Как вы помните все Job исполняются Runner'ом. Поэтому перед началом исполнения Job, нужно эти данные передать в сам Runner.

Переменные окружения представляют собой HashMap на уровне всей операционной системы, к которым можно обратиться из любой программы. В контексте CI они могут использоваться, например, для хранения номера билда. В первой Job генерируется какое-то число, которое затем передается через переменные окружения в другие Job. Кроме того, CI-системы добавляют множество своих переменных, чтобы определить, на какой ветке выполняется Job, а также токены для API и другие данные.

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

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

Следовательно, необходим третий компонент системы, который будет выполнять роль хранения артефактов. Этим компонентом является S3-совместимое хранилище. Job генерирует артефакт, затем все файлы упаковываются в архив и отправляются в S3. Отправленные файлы будут доступны только тем Job, у которых совпадает ID пайплайна. Это гарантирует, что в Job не попадет артефакт из другого пайплайна. Другие Job, которым нужен этот артефакт, просто скачивают его из S3 напрямую, минуя CI-сервер.

Как и с Runner, мы можем улучшать хранилище, масштабируя его горизонтально, и независимо от размера файлов это не повлияет на работу CI-сервера.
Как работают UI-тесты на CI

Сразу обозначу: тема UI-тестов — это глубокая нора, и я сейчас буду говорить о ней только в контексте CI. Помимо этого, я не работал с UI-тестами на фронте, но, как мне кажется, там используется похожий принцип.

Допустим, у нас есть приложение на Android и iOS, и нам нужно организовать UI-тестирование на CI. Для Android необходимо запустить эмулятор, для iOS — симулятор.

Для Android мы берём базовый Docker-образ, например с Ubuntu, накатываем на него Android SDK и эмулятор. После этого мы можем использовать этот контейнер прямо в CI-джобе и запускать тесты.

Для iOS всё то же самое, но с одной оговоркой: из-за особенностей экосистемы Apple мы обязаны использовать Mac в качестве Runner-а. В нём уже должен быть предустановлен симулятор — никакой Docker тут не поможет.

На этом можно было бы и остановиться: такой подход будет работать, если у вас немного тестов и вы не психопаты, которые в UI-тестах ходят в реальный бэк. Но что делать, если у нас, скажем, 10 тысяч UI-тестов?

👉 Во-первых, одной джобой тут явно не обойтись.
👉 Во-вторых, если выполнять тесты последовательно на одном эмуляторе — вам никакого времени не хватит.

Именно поэтому почти в каждой крупной компании делают свою ферму устройств. Берём кластер серверов (кто-то хотел про кубер, вот тут он и выходит на сцену) и поднимаем множество контейнеров с Android-эмуляторами. Для iOS — используем кластер Mac-машин и на них запускаем симуляторы. Кроме того, можно подключить реальные устройства к сети и использовать уже их для тестов.

Теперь на CI-runner-е нам не нужно накатывать тяжёлый эмулятор. Мы просто разбиваем все наши тесты на группы. Каждая группа отправляется на свой эмулятор (или реальное устройство). После выполнения всех тестов мы собираем результаты со всех устройств, агрегируем их и формируем финальный отчёт.

Всю эту возню с разбивкой тестов, запуском, сбором результатов и т.д. берёт на себя специальный инструмент — Test Runner. Не путайте его с CI-runner-ом или JUnit Runner-ом — это совсем другое, про это писал тут.

В итоге в мобильной инфре мы получаем эдакий фрактал. Мы можем масштабировать как CI-runner-ы (чтобы обрабатывать больше джоб), так и количество устройств в ферме (чтобы джоба с тестами прогонялась значительно быстрее). Помимо этого мы можем идти и дальше, например разбивать все тесты на несколько CI-Job, каждая их которых будет использовать по 20-30 эмуляторов.
Подарили мне на ДР вот такую картину, и я подумал: у меня же авторский канал, я делаю посты только про разработку — нужно иногда разбавлять чем-то ещё.

Поэтому сделаю вид, что вам не похуй, и черкану пару предложений про мою любимую игру от FromSoftware.

Для тех, кто вообще не в теме: значит, есть такая японская компания. Делает она игры, скажем так, специфичные — для определённого круга геймеров с мазохистскими наклонностями. В основном это игры в стиле дарк-фэнтези и жанре RPG. Игры, в которых только тлен, депрессия и безнадёга — прям как в разработке плагинов под Gradle.

Игры от фромов мало того, что сложные геймплейно (тебя хочет убить всё, что движется, а если умираешь — беги с последнего костра), так ещё и сюжет подаётся не через кат-сцены, как обычно, а через записки, описания предметов, диалоги... Короче, нужно нехило так усилий приложить, чтобы понять, что вообще тут происходит. Да, прям как в моей любимой системе сборки.

Магнум опус компании FromSoftware — это серия Dark Souls, про которую хотя бы краем уха слышал каждый.

И вот, в 2019 выходит Sekiro — от тех же фромов. До сих пор многие ошибочно считают, что Sekiro — это Dark Souls, только в Японии. Но Sekiro вообще ничего общего не имеет с Dark Souls.

Ну и, короче, теперь кратко — почему она мне нравится.

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

Обычно как бывает: есть персонаж в игре, которого вы прокачиваете. Он становится сильнее — и это позволяет вам продвигаться дальше, даже если вы сами особо не меняетесь. В Sekiro же единственный способ пройти дальше — это самому стать лучше. Это подкупает: враги становятся сильнее, а персонаж почти не меняется, и ты понимаешь, что именно ты становишься лучше, а не герой на экране.

Ну и ещё пара крутых моментов:
👉 В ней есть адекватный сюжет, который подаётся через кат-сцены.
👉 Есть механика воскрешения, которая реально спасает и делает геймплей чуть проще.
👉 Финальный босс — для меня лучший босс не только в Sekiro, а, наверное, вообще в играх. Он элегантен, он крут, его невозможно пройти один раз — вам почти наверняка захочется пережить это сражение снова. Битва с ним не похожа на бой с боссом, она больше напоминает завораживающий танец (во время которого тебя раз пять на копьё насадят).

Если вам не заходит серия Dark Souls, на Sekiro точно стоит обратить внимание. Это совсем другая игра, которая на самом деле в разы проще того же Dark Souls.
Please open Telegram to view this post
VIEW IN TELEGRAM
Я последнее время в своих постах все дальше ухожу от тем мобильной разработки. Даже про kotlin давно ничего не упоминал, начинаю забывать свои корни. Если же вы сильно соскучились по постам про Kotlin, то рекомендую канал Kotlin Adept Notes. Название канала даже созвучно с моим, но это чистое совпадение.

Список постов, которые на мой вкус достойны вашего внимания:
👉 Что за Kotlin UUID?
👉 Сравнение реализации компонента Compose и SwiftUI
👉 Android Lint vs Detekt

Ну и мое любимое, это история про первое мобильное приложение
Ох уж эти конфликты: Консоли против ПК, Linux против MacOS, новостные каналы против здравого смысла.

Весь код, сгенерированный при помощи Cursor AI, вам не принадлежит!

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

"…Notwithstanding the foregoing, you acknowledge that Suggestions are generated automatically by machine learning technology and may be similar to or the same as Suggestions provided to other customers, and no rights to any Suggestions generated, provided, or returned by the Service for or to other customers are granted to you under these Terms"

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

Ну вообще правильно, зачем факчекать, погнали сразу пугать людей на хабре и собирать просмотры. Вообще сама по себе идея о том, что компания производящая агентов, будет претендовать на сгенериный код это же абсурд. Агентом в таком случае никто пользоватся не будет.
Сегодня на собесе у меня кандидат (а точнее кандидатка) хотела закончить собес уже на 15 минуте, сославшись на волнение и малый опыт. Тот случай когда нужно было включить психолога и сказать: "Ты че мать, сдаваться нельзя, сдаются только квартиры". После этого, она в итоге решила 3 задачи за собес, правда с подсказками, но лучше чем совсем ничего.

Для чего я это пишу, ну во-первых если приходите на собес идите до конца, все таки попытка то не платная, если не повезло с первой задачей, может повезти со второй. Ну и во-вторых мое обаяние настолько велико, что девушки от меня пытаются сбежать даже на собесе 😎
Please open Telegram to view this post
VIEW IN TELEGRAM
Варианты, как ускорить пайплайны.

Ладно, продолжим по CI. Переходим к более практическим темам.

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

При этом первый вариант, который нужно рассмотреть для ускорения пайплайнов, — тупо купить лучшее железо для Runner и увеличить число самих Runner'ов. Это будет один из самых дешёвых вариантов. Если же вы уже упёрлись в железо, вот только тогда на сцену выходят они:

👉 Предпочитаем CLI вместо Gradle. Упоминал про это тут. Суть в том, что мы часто делаем через Gradle вещи, которые можно написать в 10 строк кода на Python и не тратить время на инициализацию. Поэтому золотое правило: если что-то можно делать без Gradle, лучше делать без Gradle.

👉 Параллелизация (динамические пайплайны). Упоминал этот вариант ещё в посте про тесты на CI. Мы можем ускориться, запуская тесты не в одной job, а, например, в трёх, которые будут выполняться параллельно. Да, потребляем больше runner’ов, но повышаем скорость пайплайна. Можно делать фиксированное количество job, а можно использовать динамические пайплайны, чтобы количество job зависело ещё и от количества тестов.

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

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

👉 Специфика GitLab CI. В GitLab CI есть два варианта, как задать зависимости между job: dependencies и needs. Работают они по-разному. dependencies ждёт не просто указанную job, а вообще весь предыдущий stage. Из-за чего вы могли уже запустить какой-нибудь linter, но ждёте весь stage с билдом. needs же игнорирует предыдущий stage и запускает job сразу, как только закончила выполняться зависимая job. Поэтому предпочитайте needs, а не dependencies в пайплайнах.
Расскажу про свой проеб с памятью. Делал я одну систему для импакт анализа. В этой системе нужно было хранить Coverage, чтобы потом по нему определять, какие тесты были затронуты. Изначально структура представляла собой вот такой json:

{
"ru.package.SomeClassName": [
{
"line_number": 1,
"tests": [
{"testId": 1},
{"testId": 2}]
}
]
}

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

Загадка от Жака Фреско: где тут проблема?

Проблема в том, что у каждой строки мы храним именно объекты, которые ещё и дублируются для каждой строки. Стоит добавить какое-то поле в этот объект — и размер этого JSON сразу улетает в космос. Первая версия структуры весила 1 ГБ.

Фикс заключается в том, что мы выносим объекты тестов в отдельный массив, а в строках оставляем только ID. Это уже позволило сократить размер в 4 раза.

Затем я подумал: «Вот, Google же придумал более оптимальный формат — Protobuf. Бинарный формат, который вообще должен ещё в разы сократить Coverage».

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

После Protobuf структура стала весить около 200 МБ. Не значительная экономия памяти, но неплохо. Я решил, что это максимум, который можно выжать. Инфра у нас быстрая, Coverage скачивался за секунды, и я не видел смысла что-то ещё копать.

До того момента, пока не пришёл матёрый iOS-ник и не сказал:

— Ты шо, ебанутый? Почему просто не использовал gzip?

Честно говоря, у меня не было ответа на этот вопрос. Я почему-то думал, что Protobuf эффективнее gzip. Однако на самом деле Protobuf вообще не про компрессию — он вообще другие проблемы решает.

Попробовал я gzip на нашей структуре. Угадаете результат?

Да, 20 МБ.

Дэээ… Что сказать… Скиллов убавилось, количество хромосом возросло.

Поэтому перед переходом на модные структуры пробуйте для начала дедовские методы — они чаще всего работают лучше.
Если смотреть на статистику моего канала, то можно увидить, что посты, которые набирают максимальное количества просмотров, комментариев и реакций это посты где есть упоминание: собесов и качалки (что не удивительно 90% мужской аудитории).

Поэтому для вашего удобства я собрал посты про собесы, вдруг вы какие-то пропустили:

👉 Советы по прохождению алгоритмической секции
👉 Как избавится от волнения перед собесом
👉 Как перестать боятся графов
👉 Разборы задачек: раз и два
👉 Самый забавный собес в карьере

P.S посты про качалку я в другой раз соберу, а то пока там мало совсем, поэтому ждите. erid: 2W5zFGw3MPe
Чисто мои будни
Несмотря на то, что я — Android-разработчик (пока ещё), последние лет семь пользуюсь только iPhone. В этом нет никакой сложной причины — мне просто так удобнее. При этом я не считаю, что все Android-устройства — херня из-под коня, каждый выбирает под себя.

Самое забавное вот в чём: все эти семь лет я слышу одно и то же — «Ты же Android-разработчик, чего ты с iPhone ходишь?» Я, если честно, вообще не понимаю, в чём тут связь и почему я должен ходить именно с Android-устройством? Знать фичи системы? Так они практически идентичны, друг у друга концепции тырят.

Прикол ещё в том, что до такого можно доебаться только до мобильного разработчика. Представьте, как было бы забавно, если бы с такими комментариями обращались к ребятам из других сфер.
– «О, ты ML-инженер и используешь ChatGPT? А чего свою модель не обучил?»
– «О, ты разработчик embedded-систем, а чего вообще смартфон купил, а не собрал в гараже свой?»
– «О, ты ведущий Android подкаста, а не подскажешь какой стол купить? Я все никак выбрать не могу(»
Прошлым постом я вообще просто хотел похихикать над другим блогером, но, сам того не осознавая, открыл портал в чистилище.

Оставим за скобками мудаков, которые начали меня оскорблять за использование операционки, которая им не нравится. Помимо этого, было много слов про вовлечённость, ценности и даже предательство. Вы, блядь, «Россию 1» что ли насмотрелись?

На фоне такой ожесточённой дискуссии я захотел накидать пару строк про вовлечённость — тема-то интересная. Все мы боимся показаться не «вовлечёнными», иначе очередная Xsolla придёт и уволит нас одним днём.

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

Однако dogfooding не подразумевает, что ты будешь пользоваться только той платформой, под которую разрабатываешь. Почему ты «не вовлечён», если используешь свой же продукт, но через другую платформу? В этом случае я точно так же могу прийти к разработчикам и зарепортить им баг.

Представим ситуацию: ты фронтендер и работаешь над банковским сайтом. Помимо фронта у банка, разумеется, есть мобильные приложения. И что, теперь ты вынужден пользоваться только браузером, иначе ты «не ценишь свою платформу», предатель?

Думать, что dogfooding возможен всегда, — это крайне узкий взгляд на индустрию. Вот я работаю над приложением для ИП и ООО. У меня нет бизнеса, я в принципе никак не могу пользоваться своим творением, но это не мешает мне делать свою работу хорошо.

Есть приложение для девушек Flo, позволяющее отслеживать цикл. Ну че, пацаны, как тут будем вовлечённость поднимать?) А если я разрабатываю приложение для знакомств, но у меня счастливый брак?

Бизнесу по большей части похуй, насколько ты вовлечён. Есть только один показатель: ты либо приносишь бабки, либо нет. Если ты не приносишь прибыль компании (напрямую или косвенно), то тебя уволят, и неважно, насколько ты там лояльный и «вовлечённый» сотрудник. Кричать про предательство и вовлечённость — это похоже на каприз маленького ребёнка.
Если смотреть на социальную динамику, то пару лет назад многие айтишники жаловались, что им сложно найти девушку. Не то чтобы у всех была такая проблема, но, по крайней мере, стереотип такой был (да в целом и есть до сих пор).

На чистоту, найти работу было в разы проще, чем девушку. Вспомните вот эти мемы, где у девочек в Tinder'е — 100500 предложений, а у мальчиков в LinkedIn.

Ну так вот, кажется мы в том промежутке времени, где работу найти сложнее.
{1/2} Подходы для отладки пайплайнов

Сейчас будет лонгрид, на две части, так что соберитесь!

Как только я сел писать данный пост, я понял один прекол. Все мои best practices работают только для GitLab CI и GitHub Actions. Для остальных систем эти советы могут быть не особо актуальны.

В GitLab CI и GitHub Actions конфигурация пайплайнов хранится в репозитории вместе с основным кодом. Это дает плюсы вроде: версионирования, коллаборации, документированности и того, что вся конфигурация находится в одном месте. Минусы же такого подхода в том, что ты не можешь протестировать пайплайн, не смержив новые изменения.

На примере: у тебя есть Job с билдом и Job с тестами. Job с билдом работает хорошо и стабильно, а Job с тестами ты пытаешься настроить. В CI системах у тебя нет возможности изменять Job с тестами, используя результаты из Job с билдом. Для проверки правильности твоих изменений тебе нужно запускать весь пайплайн, и это главная проблема в их отладке.

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

Следовательно все советы по отладке будут направлены на то, чтобы сгладить эти две основные проблемы. Погнали.
{2/2} Подходы для отладки пайплайнов

👉 Делаем дебажное правило, которое позволяет запускать пайплайн на любой ветке по API. В GitLab CI выглядит примерно так:

rules:
# Тут будут основные правила запуска
- if: $PIPELINE_TYPE == "DEBUG_MR" # это правило позволяет запустить пайплайн на любой ветке, без создания МРа через API


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

👉 Используем конструкцию с echo, чтобы понять, с какими аргументами запустили программу. Например, вы в Job вычисляете какие-то параметры, чтобы потом запустить Gradle. У Gradle, как вы знаете, логи ублюдские, поэтому проще узнать, а с каким параметром мы вообще его запустили. По умолчанию в логах Job не будет этой информации, однако вот такая конструкция легко позволяет ее получить:

echo "./gradlew some-task $args"
./gradlew some-task $args


👉 Канарейка. Внезапно, да, можно использовать канарейку и в CI/CD. Может возникнуть вопрос, нахера в CI/CD-то оно нужно. Дело в том, что на большом проекте, когда у вас орда разрабов, которые что-то постоянно пушат и создают МРы, вам желательно (но не обязательно) не косячить в пайплайнах. Мы помним, что при обновлении пайплайнов не все сразу перейдут на новую версию.

Поэтому, когда вы, например, добавляете новую экспериментальную Job, очень крутой подход — сделать эту Job под флагом. Флагом, который вы в случае чего можете быстро выключить в консоли CI системы:

rules:
- if: $FEATURE_NEW_JOB_ENABLED == "true"


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

Меня очень спасает подход, когда я эти дебажные логи могу включить не только через флаг, но и через ENV переменную. Это нужно, чтобы я мог просто в консоли CI быстро добавить эту ENV переменную и сразу везде, без изменения пайплайнов, включить логи и посмотреть, где проблема.

👉 База. Ну и, разумеется, очевидные советы, вроде: используйте cat и echo в скриптах, чтобы понимать, что происходит, в bash-скриптах не забывайте использовать set -x, чтобы видеть все команды, не забывайте проверять наличие файлов перед их использованием.

И самое главное, ни при каких обстоятельствах, чтобы не происходило с вашей карьерой, не ешьте желтый снег!
Меня так бесит, когда я описываю идею какой-то статьи, и меня спрашивают:
— "А какую проблему решает твоя статья?"
Да никакую, блять! Это же не бизнес-идея, почему она вообще должна что-то решать?

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

Статья — это всегда про творчество, которое может быть связано с твоей работой. Ты описываешь свой опыт: как у тебя круто получилось или как не получилось (второй вариант, как правило, интереснее). Да, будет, конечно, круто, если статья еще чему-то тебя научит, но в основном главное, чтобы читатель просто кайфанул и все.

Давайте быть честными: люди по большей части на Хабр идут за развлечением, а не за знаниями. А вот эти душнилы, которые голову парят о проблематике потом и пишут унылую херню, которую читать невозможно.
2025/07/04 13:59:39
Back to Top
HTML Embed Code: