No description
  • TypeScript 69.3%
  • JavaScript 11.8%
  • Shell 8.6%
  • CSS 5.5%
  • HTML 4.1%
  • Other 0.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-06 08:49:14 +00:00
.forgejo/workflows feat: wire DOCS_HOSTNAME through the hostname-baking pipeline 2026-09-15 17:36:59 +03:00
.husky feat: initial landing page with APK download 2026-09-01 10:31:49 +03:00
.opencode chore(deps): update dependency zod to v4.6.5 2026-09-28 06:09:40 +00:00
assets fix: natural-sort screenshots gallery (client collator + sort -V in refresh) 2026-09-24 08:56:30 +03:00
docs feat: add <link rel=canonical> to index.html 2026-09-09 19:57:14 +03:00
scripts fix: natural-sort screenshots gallery (client collator + sort -V in refresh) 2026-09-24 08:56:30 +03:00
.dockerignore feat: initial landing page with APK download 2026-09-01 10:31:49 +03:00
.env.example feat: wire DOCS_HOSTNAME through the hostname-baking pipeline 2026-09-15 17:36:59 +03:00
.gitignore feat: local dev server with .env support replacing python http.server 2026-09-05 10:54:55 +03:00
AGENTS.md feat: add <link rel=canonical> to index.html 2026-09-09 19:57:14 +03:00
AI_PROFILES.md feat(opencode): profile plugin with adaptive model failover 2026-09-21 15:52:25 +03:00
CHANGELOG.md chore: bump version to 0.8.1 2026-09-24 08:56:47 +03:00
Dockerfile feat: wire DOCS_HOSTNAME through the hostname-baking pipeline 2026-09-15 17:36:59 +03:00
index.html chore: bump version to 0.8.1 2026-09-24 08:56:47 +03:00
LICENSE feat: brand identity, light/dark/system themes, and site polish 2026-09-01 15:58:12 +03:00
nginx.conf feat: drive /web and landing URLs from hostname env vars, open /web in new tab 2026-09-05 10:36:33 +03:00
package-lock.json chore: bump version to 0.8.1 2026-09-24 08:56:47 +03:00
package.json chore: bump version to 0.8.1 2026-09-24 08:56:47 +03:00
README.md refactor(deploy): make vps-deploy.sh verify infra instead of provisioning it 2026-09-08 12:36:27 +03:00
renovate.json ci: add Renovate for dependency updates 2026-09-08 14:28:24 +03:00
robots.txt feat: add sitemap.xml 2026-09-09 18:54:41 +03:00
sitemap.xml chore: drop the comment from sitemap.xml 2026-09-09 19:54:30 +03:00

Слово.Проповеди — Landing page

Лендинг для Android-приложения «Слово.Проповеди» — прямая загрузка APK без магазинов. Работает на https://slovo-propovedi.ru.

Как работает загрузка APK

APK-файлы не хранятся в этом репозитории. Скрипт обновления (scripts/vps-refresh-apk.sh) работает на VPS и выполняет следующее:

  1. Дважды в день по таймеру slovo-landing-refresh.timer (04:30 / 16:30 UTC, RandomizedDelaySec=30m), а также пост-деплой и вручную через refresh-apk.yml (workflow_dispatch).
  2. Загружает последний релиз мобильного приложения с Forgejo (первичный) или GitHub (резервный). Если уже обслуживаемая версия совпадает — выход 0 без повторной загрузки ~30MB архива.
  3. Извлекает APK, публикует slovo-propovedi-vX.Y.Z.apk и latest.json (версия, размер, SHA-256, дата) в /slovo/landing/apk, который nginx отдаёт с MIME-типом application/vnd.android.package-archive.
  4. Страница показывает версию, размер и SHA-256 с кнопкой копирования и QR-кодом для скачивания с телефона.
  5. Хранятся последние 3 версии (KEEP_VERSIONS=3); при ошибке сохраняется предыдущее состояние.

Токены для API (если репозитории приватные или rate-limited) хранятся в /slovo/landing/tokens/ (root-only 0700).

Скриншоты

Скриншоты не хранятся в этом репозитории. Скрипт (scripts/vps-refresh-screenshots.sh) работает на VPS и выполняет следующее:

  1. Дважды в день по таймеру slovo-landing-refresh-shots.timer (04:30 / 16:30 UTC, RandomizedDelaySec=30m), а также пост-деплой.
  2. Получает git-дерево мобильного репозитория (Forgejo — первичный, GitHub — резервный) и выбирает канонические PNG из assets/screenshots/.
  3. Проверяет каждый файл: магические байты PNG и git-blob sha1 (sha1("blob <size>\0" + содержимое) должен совпасть с sha из дерева).
  4. Публикует файлы с именами <stem>-<sha8>.png (sha в имени → immutable-кеш) и manifest.json (fingerprint, updatedAt, sourceUrl, sourcePath, images) в /slovo/landing/screenshots, который nginx отдаёт как /screenshots.
  5. Если fingerprint уже совпадает с удалённым деревом — выход 0 без повторной загрузки и перезаписи (устаревшие файлы всё равно удаляются — галерея самовосстанавливается). При ошибке сохраняется предыдущее состояние (keep-last-good).

Страница показывает галерею из manifest.json с обязательной строкой «Скриншоты: © 2026 Slovo.Propovedi, GPL-3.0-or-later» (лицензия GPL-3.0-or-later из REUSE.toml мобильного репозитория).

Разработка

Запуск локально

docker build -t slovo-propovedi-landing .
docker run --rm -p 8080:8080 \
  -v /path/to/apk+latest.json:/usr/share/nginx/html/apk:ro \
  slovo-propovedi-landing

Для локального тестирования положите APK и latest.json в директорию test-apk/ (gitignored).

npm-команды

npm ci                           # установка зависимостей (husky)
npm run validate                 # проверка согласованности файлов (CI parity)
npm run generate-qr              # пересоздать assets/img/qr.svg (DOMAIN-PINNED к https://slovo-propovedi.ru)
npm run generate-og              # пересоздать assets/img/og.png (нужен rsvg-convert или ImageMagick)
npm run dev                      # локальный просмотр на http://localhost:8377 (Node, читает .env; остановка Ctrl+C)

Процесс релиза

  1. Bump версии:

    npm run bump-version <version|patch|minor|major>
    

    Скрипт обновляет package.json, CHANGELOG.md, package-lock.json и ?v= cache-busting в index.html (включая theme-init.js), коммитит с DCO signoff и создаёт тег vX.Y.Z.

  2. Пush:

    git push --follow-tags origin main
    
  3. CI проверяет (ci.yml): npm run validate на ubuntu-24.04.

  4. Тег запускает release.yml:

    • Проверяет согласованность версий (tag vs package.json).
    • Ждёт прохождения CI на закоммиченном коммите.
    • Передаёт исходный код на VPS через tar+ssh.
    • Запускает scripts/vps-deploy.sh (buildx-сборка, read-only контейнер за Traefik с apex + www хостами и www→apex редиректом, LE-сертификат).
    • Прокидывает опциональные токены и запускает обновление APK.
    • Создаёт Forgejo Release с секцией из CHANGELOG.md.

Граница ответственности. vps-deploy.sh владеет только контейнером slovo-landing, его сетью slovo-landing и таймерами обновления APK/скриншотов. Общая инфра — Docker, пользователь slovo, buildx-билдер slovo-constrained, Traefik (slovo-traefik.service) и сеть traefik — принадлежит внешнему slovo-propovedi-playbook и должна быть развёрнута заранее (just setup-all). Скрипт её только проверяет и падает с ошибкой, если чего-то нет.

Настройка нового VPS

  1. Создайте репозиторий в организации Slovo_Propovedi на git.lightnode.ru и запушьте main.

  2. Разверните общую инфру на VPS через slovo-propovedi-playbook (just setup-all) — Docker, пользователь slovo, buildx-билдер, Traefik.

  3. Добавьте секреты (Settings → Actions → Secrets):

    Секрет Описание
    VPS_SSH_PRIVATE_KEY SSH-ключ (ed25519) для доступа к VPS
    VPS_HOST Хостнейм или IP VPS
    VPS_SSH_USER SSH-пользователь на VPS
    FORGEJO_API_TOKEN (опционально) токен Forgejo API
    GITHUB_MIRROR_TOKEN (опционально) токен GitHub API
  4. Раннер: ubuntu-24.04.

  5. DNS: A-записи для apex (slovo-propovedi.ru) и www указывают на VPS.

  6. Первый релиз — тег v0.1.0.

Лицензия

Приложение распространяется под лицензией GPL-3.0-or-later — см. репозиторий мобильного приложения.

Атрибуция

  • Иконка приложения (assets/img/icon.png, логотип в шапке) — это иконка приложения «Слово.Проповеди», скопированная без изменений из мобильного репозитория. Распространяется под GPL-3.0-or-later (та же лицензия, что и у ассетов приложения).
  • Иконки интерфейса — Ionicons v5 (https://ionicons.com), © Ionic — MIT (https://github.com/ionic-team/ionicons/blob/main/LICENSE).