CI/CD на голом Bash. Собираем и публикуем приложения для Android без лишних инструментов

CI/CD на голом Bash. Собираем и публикуем приложения для Android без лишних инструментов

Содержание статьи

Я соб­рал CI/CD-сер­вер для Android-при­ложе­ний на голом Bash. Он запус­кает сбор­ки через облачный CI или Gradle нап­рямую, пуб­лику­ет резуль­тат в Google Play, монито­рит уве­дом­ления о пуб­ликации через IMAP. В качес­тве интерфей­са управле­ния я взял Telegram, но на его мес­те мог бы быть Slack, Discord, ntfy, email или обыч­ный SSH — тран­спорт здесь смен­ная деталь.

Воз­можно, ты ска­жешь, что делать все на Bash стран­но. Но ведь это как раз язык для склей­ки инс­тру­мен­тов: фай­ловый ввод‑вывод, работа с перемен­ными окру­жения, HTTP-зап­росы через curl, изме­нение JSON через jq. Получа­ется, что мы прос­то при­меним клас­сичес­кий «путь Unix» к веб-API, а не толь­ко к локаль­ным прог­раммам. И заод­но обой­дем­ся без докеров и кубер­нетесов.

А глав­ное, изме­нить мож­но будет что угод­но и в любой момент без стра­даний с деп­лоем. Теперь идея кажет­ся более здра­вой? Давай опро­буем ее на при­мере, и ста­нет понят­но, при­мени­мо ли это в жиз­ни.

Для начала пос­мотрим, как будет работать пол­ный цикл пуб­ликации. Что­бы его запус­тить, прос­то нажима­ешь «Publish Beta» — и через нес­коль­ко минут смот­ришь, что появи­лось в чате.

Бот ска­чал AAB с Codemagic, заг­рузил его в Google Play, зафик­сировал edit-тран­закцию — и потом, ког­да Google завер­шил модера­цию, поч­товый монитор пой­мал пись­мо и прис­лал финаль­ное уве­дом­ление. Все без учас­тия челове­ка.

А теперь рас­ска­жу, как я это пос­тро­ил. Если захочешь пов­торить, вот, что тебе понадо­бит­ся:

то­кен Telegram-бота (зап­роси у @BotFather);

то­кен Codemagic API или локаль­ный Android SDK с Gradle;

Google Play Service Account JSON с пра­вами Release Manager;

поч­товый ящик с дос­тупом по IMAP (Gmail подой­дет);

Docker или любой Linux-хост;

за­виси­мос­ти: curl, jq, openssl, mbsync;

Сис­тема сос­тоит из двух незави­симых про­цес­сов в одном Docker-кон­тей­нере.

Ор­кес­тра­тор сбо­рок ( publish_bot. sh ) — при­нима­ет коман­ды от опе­рато­ра, запус­кает сбор­ку через CI API или локаль­ный Gradle, отда­ет арте­факт, пуб­лику­ет в Google Play, отве­чает на зап­росы ста­туса. Обслу­жива­ет нес­коль­ко про­ектов одновре­мен­но — у каж­дого свой вор­кер‑про­цесс.

Мо­нитор поч­ты ( imap_to_telegram. sh ) — каж­дые 30 секунд чита­ет вхо­дящие по IMAP, ищет пись­ма от Google Play Console, пересы­лает уве­дом­ления в нуж­ный канал.

Меж­ду ними — файл channel_ids. json : мап­пинг «package name → иден­тифика­тор канала». Оба про­цес­са чита­ют его незави­симо.

Тран­спорт — вер­хний блок (коман­ды) и ниж­ний (уве­дом­ления) — намерен­но отде­лен от логики. Хочешь пере­ехать со Slack на Telegram или добавить парал­лель­ную отправ­ку в ntfy — пра­вишь три фун­кции, не зат­рагивая ядро.

Каж­дый осталь­ной блок тоже заменя­ем незави­симо: поменять CI-сер­вис — одна фун­кция, добавить трек пуб­ликации — один case в switch. Архи­тек­тура намерен­но плос­кая: никаких абс­трак­ций, прос­то фун­кции.

Деп­лой — одна коман­да:

Скрипт start. sh запус­кает оба про­цес­са:

Даль­ше раз­берем кон­крет­ные задачи по поряд­ку.

Преж­де чем пог­ружать­ся в детали — важ­ный архи­тек­турный момент. В сис­теме есть ров­но три точ­ки вза­имо­дей­ствия с опе­рато­ром:

Вхо­дящие коман­ды — отку­да сер­вис получа­ет задание (запус­тить сбор­ку, показать ста­тус).

Ис­ходящие уве­дом­ления — куда сооб­щать о резуль­тате.

Дос­тавка арте­фак­тов — куда отда­вать соб­ранный APK/AAB.

Все это реали­зова­но в трех‑четырех фун­кци­ях. Поменять тран­спорт — зна­чит перепи­сать эти фун­кции.

Только уведомления

Ес­ли инте­рак­тив не нужен — вари­анты прос­тые.

ntfy.sh — минима­лис­тичный вари­ант. Пуб­личный сер­вис, бес­плат­ный, с мобиль­ным при­ложе­нием. Отпра­вить уве­дом­ление:

То­пик — прос­то стро­ка в URL. Под­писыва­ешь­ся в при­ложе­нии — получа­ешь push. Никакой регис­тра­ции, никаких токенов. Мож­но под­нять собс­твен­ный ntfy-сер­вер для при­ват­ности.

Slack/Discord webhooks — если коман­да уже исполь­зует его. Нам дос­таточ­но сде­лать один POST-зап­рос с JSON:

У Discord поле называ­ется content вмес­то text , URL дру­гой, но пат­терн тот же.

Email через msmtp — работа­ет сов­сем без зависи­мос­ти от сто­рон­них сер­висов:

Двусторонний канал

Ес­ли нуж­ны и коман­ды, и уве­дом­ления, то выбор сле­дующий.

Telegram — самый удоб­ный вари­ант для этой задачи: бес­плат­ный API, long polling без пуб­лично­го IP, фай­лы до 50 Мбайт мож­но слать пря­мо в чат, кноп­ки дела­ются одним JSON. Под­робно раз­берем ниже.

Slack slash-коман­ды — рабочий вари­ант для коман­дной раз­работ­ки. Slash-коман­да отправ­ляет POST на твой endpoint — зна­чит нужен пуб­личный URL, в отли­чие от Telegram polling. Отве­ты при­нима­ем через webhook.

Matrix/Element — откры­тый про­токол с REST API, под­держи­вает polling ( / sync ), мож­но захос­тить сер­вер у себя. Схе­ма та же что у Telegram: loop, затем curl / sync , обра­бот­ка события, и сле­дом curl / send .

SSH — для лич­ного исполь­зования экзо­тич­но, но зато зависи­мос­ти нулевые:

cron — подой­дет, если инте­рак­тив вооб­ще не нужен. Если у тебя ноч­ные сбор­ки и еже­недель­ные бета‑релизы, то мож­но вооб­ще всё авто­мати­зиро­вать и обой­тись без мес­сен­дже­ров.

Что дей­стви­тель­но слож­но заменить — это отправ­ку фай­лов. Telegram при­нима­ет APK пря­мо в чат, файл ска­чива­ется одним тапом. У Slack лимит на заг­рузку в бес­плат­ном пла­не, у ntfy фай­лов нет. Аль­тер­натива: S3 или Cloudflare R2 как хра­нили­ще, а ссыл­ка будет при­ходить в уве­дом­лении.

Привязка проекта к каналу уведомлений

Сер­вис обслу­жива­ет нес­коль­ко при­ложе­ний. Как он понима­ет, для какого про­екта приш­ла коман­да и в какой канал слать уве­дом­ление?

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

9990 рублей 5000 р.

950 р.

Если на сервере с Windows остались MSI-пакеты установленных программ, стоит проверять их м…

← Cybersecurity