«С блэкджеком и CI/CD»: APT-репозиторий на базе GitHub и Cloudflare Workers

от автора

В Linux с давних пор киллерфичей была возможность централизованного управления (поиск, установка, удаление, обновление, разрешение зависимостей) софтом при помощи пакетных менеджеров (apt, yum, pacman и т.д.).

Однако существует большое количество интересных и полезных программ, которые распространяются разработчиками либо через собственный сайт, либо через релизы на GitHub, либо в виде статического бинарника, либо вообще исключительно в исходниках (при этом под той же Windows у того же проекта часто есть нормальный инсталлятор с автопроверкой обновлений).

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

Как всё начиналось

Я использую Linux как основную (и единственную) систему уже много лет. Естественно, за это время мне приходилось ставить кучу разного софта — в том числе собирать его из исходников.

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

Эра Docker

Со временем познакомился с Docker и стал писать сборочные Dockerfile — даже кидал разработчикам PR’ы с Dockerfile, чтобы облегчить жизнь пользователям (кто-то придумывал отговорки, а кто-то даже принимал их).

Но проблема не ушла: даже с Docker я продолжал возиться с ручной установкой и перетаскиванием собранных пакетов между компьютерами.

Свой репозиторий version 1.0

Потом меня этот цирк с конями окончательно задолбал, и я решил автоматизировать всё. У меня была VPS, и я на ней запустил собственный репозиторий при помощи aptly и навайял скрипты для получения обновлений.

Сначала схема работала, но потом начались проблемы. Кончилось место на диске из-за истории релизов в aptly (VPS была самая дешевая). А потом (в связи со всем известными событиями) хостер ликвидировал мою VPS-ку, и все наработки превратились в тыкву.

На какое-то время я забил. Тем более всё, что надо было, у меня на компе давно стояло и работало. Особо уже не было потребностей что-то компилировать и устанавливать (постарел, наверное).

«Хватит это терпеть!»

Недавно решил вспомнить молодость и снести всё нафиг на ноуте: сделать полнодисковое шифрование, поставить ОС начисто и заново настроить софт.

После переустановки вспомнил, что есть софт, который надо откуда-то качать. Старые .deb у меня были, но хотелось свежих версий.

И тут я решил

Стал думать, как сделать так, чтобы всё само собой делалось, надёжно, дёшево и сердито. Опять запускать репозиторий на VPS и городить скрипты в кроне? А дальше думать о бэкапах и мониторинге, чтобы опять не было больно?

В ходе этих размышлений возникла мысль:

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

Как публиковать такой репозиторий?

  • GitHub Pages: пришлось бы заливать .deb-пакеты физически, а там ограничение в 10 МБ на файл.

  • Свой веб-сервер на VPS: опять амортизация VPS со всеми вытекающими.

Тогда я вспомнил про Cloudflare Workers. Ранее я уже имел с ними дело и подумал, что эта штука отлично подойдёт для моей задачи. В итоге получилась удобная схема публикации APT-репозитория.

Как это устроено

Суть простая: под капотом нет ни одного своего сервера. Сам софт хранится в GitHub Releases, текстовые индексы репозитория отдаёт Cloudflare Pages, а все редиректы обрабатывают Cloudflare Workers.

Вся логика разнесена по трём веткам git-репозитория:

  • apps — сборочная ветка с описаниями пакетов.

  • apt — ветка публикации метаданных APT (хостится на Cloudflare Pages).

  • worker — код роутеров на Cloudflare Workers.

Схема публикации у меня получилась такая:

  1. .deb-пакеты лежат в GitHub Releases. При появлении обновлений GitHub Actions собирает .deb и создаёт новый релиз на GitHub. В сам Git бинарники не коммитятся.

  2. Метаданные APT лежат на Cloudflare Pages. Небольшие текстовые индексы (dists/) генерируются при деплое и публикуются в ветку apt.

  3. Cloudflare Worker рулит запросами:

  • Запросы к /dists/* и /apt-key.asc проксируются с Cloudflare Pages.

  • Запросы к /pool/*.deb считывают карту pool-map.json и отдают 302 Redirect на прямой URL файла в GitHub Releases.

  • Запрос к корню / показывает веб-страницу со списком пакетов (для браузера) или краткую инструкцию (для curl).

apt абсолютно нормально обрабатывает 302-редиректы и скачивает пакеты напрямую с CDN GitHub.

Автоматизация CI/CD

За сборку, проверку обновлений и деплой отвечают три воркфлоу GitHub Actions:

  • check-updates.yml — периодически проверяет наличие обновлений. Если обновление вышло, собирает .deb через docker buildx и выкладывает новый GitHub Release, после чего триггерит воркфлоу деплоя.

  • deploy-apt.yml — подтягивает свежие релизы, генерирует и подписывает GPG-ключом индексы APT (dists/), обновляет карту редиректов, пушит изменения в ветку apt и публикует анонсы в Telegram-канал (при ошибках — шлёт уведомление в ЛС).

  • deploy-worker.yml — деплоит воркеры через Wrangler при изменениях в ветке worker.

Как добавить свой пакет

Пакет для публикации приложения — это отдельная директория apps/<app>/ с двумя файлами:

  • package — bash-скрипт, отвечающий за метаданные пакета (SOURCE_URL, DESCRIPTION) и отслеживание обновлений у авторов программы (check_update и get_version).

  • Dockerfile — инструкция по сборке самого пакета (компиляция из исходников, распаковка бинарника или готового .deb). Финальный стейдж всегда FROM scratch, в котором остается только собранный .deb.

В папке docs/template/ есть заготовка с подробными примерами под разные случаи:

  • отслеживание релизов на GitHub

  • сборка по тегам и коммитам ahead (когда формальных релизов у проекта нет)

  • парсинг сайта разработчика

  • использование хелперов fetch_url и gh_fetch_raw

Пример скрипта apps/<app>/package:

SOURCE_URL="https://github.com/owner/repo"DESCRIPTION="Some application description"check_update() {    gh_tag_ahead "owner/repo" "$1"}get_version() {    gh_latest_release "owner/repo"}

Локально проверить сборку пакета можно одной командой:

bash apps/build.sh <app>

Ну и куда нынче без ИИ. Написал скилл create-package (.agents/skills/create-package/). Можно вызвать как-то так: «Создай при помощи create-package пакет для программы programname». Отвечаешь после этого на пару уточняющих вопросов, а дальше он сам анализирует исходный репозиторий проекта, выбирает схему версионирования, генерирует package с Dockerfile и проверяет сборку.

Что в итоге

Я считаю, что в итоге у меня получилась неплохая схема на бесплатном стеке (GitHub + Cloudflare Workers), которая сама отслеживает апдейты у авторов софта, деплоит .deb-пакеты и не требует расходов на VPS или места под архивы.

Главный профит для меня — теперь я могу ставить нужный мне софт одной командой apt install, не думая, где взять свежую версию, или что там опять сломалось в зависимостях.

Сейчас репозиторий заточен под Ubuntu 24.04 (потому что сижу на ней). Но, может быть, в будущем, буду добавлять и другие дистры.

Если хотите добавить своё приложение — присылайте PR!

Обновляемый список пакетов и инструкция по подключению можно посмотреть на apt.smbit.pro и в репозитории на GitHub

ссылка на оригинал статьи https://habr.com/ru/articles/1062422/