# Автообновление через Gitea (приватный код + публичный feed) Исходники остаются в **закрытом** репозитории с игрой. Файлы обновлений (`latest.yml`, установщики) лежат в **отдельном публичном** репозитории — по HTTPS их скачивает `electron-updater`. ## Твой публичный репозиторий (уже есть) - Клон: `https://git.mailib.ru/ifontosh/DndGamePlayerUpdates.git` - Владелец/репо для секретов: **`ifontosh/DndGamePlayerUpdates`** - Базовый URL feed (вшивается в сборку и должен совпадать с secret **`DND_UPDATE_FEED_URL`**): **`https://git.mailib.ru/ifontosh/DndGamePlayerUpdates/raw/branch/updates/`** Обрати внимание: слово **`branch`** в пути — это часть URL Gitea, не имя ветки. Имя ветки — в конце: **`updates`**. В `package.json` уже указан этот же `build.publish.url` (для локального `npm run pack` и метаданных electron-builder). --- ## Шаг 0 — репозиторий сейчас пустой (важно) На странице репо написано, что **контента нет**. Пока нет **ни одного коммита**, CI не сможет сделать `git clone`. Сделай так (любой способ): 1. На сайте открой `ifontosh/DndGamePlayerUpdates` → кнопка вроде **«Инициализировать репозиторий»** / **«Добавить файл»** → создай файл `README.md` с парой строк и закоммить **в ветку по умолчанию** (часто `main`). 2. Либо с компьютера: ```bash git clone https://git.mailib.ru/ifontosh/DndGamePlayerUpdates.git cd DndGamePlayerUpdates echo "# DndGamePlayer updates feed" > README.md git add README.md git commit -m "init" git push origin main ``` (Если ветка по умолчанию у тебя `master` — подставь её вместо `main`.) После этого репозиторий **не пустой** — workflow сможет клонировать и создать ветку **`updates`**. --- ## Шаг 1 — токен для записи в публичный репозиторий Нужен **персональный токен** (PAT), с которым CI сможет **пушить** в `DndGamePlayerUpdates`. В Gitea на русском обычно так (названия могут чуть отличаться в твоей теме): 1. Вверху справа **аватар** → **Настройки** (или «Параметры»). 2. Слева найди раздел вроде **«Приложения»** / **«Токены доступа»** / **«Токены»** (в англ. интерфейсе: **Settings → Applications → Generate New Token**). 3. Создай новый токен: - имя: например `dnd-release-ci`; - права: достаточно доступа к репозиторию с **записью** (для пуша в `DndGamePlayerUpdates`). Если есть галочки — включи что-то вроде **«Запись в репозиторий»** / **write:repository** / полный доступ к репо. 4. **Скопируй токен один раз** и сохрани в менеджере паролей — потом Gitea его не покажет. Этот токен пойдёт в secret **`DND_UPDATES_PUSH_TOKEN`** (см. ниже). **Не вставляй токен в код и не коммить его.** > На **git.mailib.ru** имена секретов **не могут начинаться с `GITEA_`** (зарезервировано). Поэтому в workflow используются `DND_UPDATES_*`, а не `GITEA_*`. --- ## Шаг 2 — секреты в приватном репозитории с кодом (`dnd_player`) Открой **приватный** репозиторий, где лежит исходник игры (не `DndGamePlayerUpdates`). Дальше (русский Gitea 1.26, ориентир по меню): 1. Вкладка **«Настройки»** репозитория (вверху рядом с «Код», «Задачи» — иногда шестерёнка **«Настройки»**). 2. Слева раздел **«Секреты»** / **«Действия»** → **«Секреты»** (в англ. UI: **Settings → Actions → Secrets**). Если видишь **«Переменные»** — секреты обычно рядом; нам нужны именно **секреты** (скрытые значения). Добавь **четыре** секрета (имя **точно** как в таблице — workflow их читает): | Имя секрета | Что вписать в значение | | ------------------------ | -------------------------------------------------------------------------------------------------------- | | `DND_UPDATE_FEED_URL` | `https://git.mailib.ru/ifontosh/DndGamePlayerUpdates/raw/branch/updates/` (обязательно **слэш в конце**) | | `DND_UPDATES_SERVER` | `https://git.mailib.ru` (**без** слэша в конце) | | `UPDATES_REPO` | `ifontosh/DndGamePlayerUpdates` | | `DND_UPDATES_PUSH_TOKEN` | токен из шага 1 (одна длинная строка) | Сохрани каждый секрет кнопкой вроде **«Сохранить»** / **«Добавить»**. Если раньше создавал секреты `GITEA_SERVER` / `GITEA_TOKEN` — их workflow **не читает**; удали или оставь, но **обязательно** заведи новые имена из таблицы. --- ## Раннер act_runner — без этого «Всего: 0» и сборки не будет Gitea **не запускает** workflow на своём процессе: нужна **отдельная машина** (VPS, сервер или **WSL2 Ubuntu** на твоём ПК), на которой крутится **[act_runner](https://docs.gitea.com/usage/actions/act-runner)** и которая видит `git.mailib.ru` по сети. Пока в **«Настройки» → «Действия» → «Раннеры»** написано **«Всего: 0»**, workflow **висит в ожидании** — нечему выполнять шаги. ### Важно: это не тот токен, что для пуша в `DndGamePlayerUpdates` | Токен | Где взять | Зачем | | --------------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | | **Регистрация раннера** (короткая случайная строка) | **Настройки репо** → **Действия** → **Раннеры** → **Создать новый раннер** | Только для команды **`act_runner register`** (один раз на каталог с раннером) | | **`DND_UPDATES_PUSH_TOKEN`** (PAT) | **Аватар** → **Настройки пользователя** → токены доступа | Для CI: пуш в публичный репо обновлений (см. шаг 1 выше) | Если Gitea показала **только длинную строку** — это почти наверняка **токен регистрации раннера**. URL инстанса ты знаешь сам: **`https://git.mailib.ru`** (без пути к репозиторию). ### Требования к машине под наш `release.yml` В workflow для job **`ubuntu-22.04`** идут **`sudo apt-get`** и **Wine** на **Linux**. Поэтому: - Нужен **Linux x86_64** (идеально **Ubuntu 22.04**), либо **WSL2** с Ubuntu 22.04 на Windows. - Запускать раннер на «голом» Windows с меткой `ubuntu-22.04` **бессмысленно** — шаги с `apt` не выполнятся. ### Шаг A — получить токен регистрации в Gitea 1. Открой репозиторий с кодом (**DndGamePlayer** или как он у тебя называется). 2. **Настройки** → **Действия** → **Раннеры** → **Создать новый раннер**. 3. Выбери тип **репозитория** (repository runner), ОС **Linux**. 4. **Скопируй токен** (и при желании подсказку с URL инстанса, если она есть). Команду из мастера можно **не копировать**, если ниже удобнее готовая. ### Шаг B — скачать act_runner (бинарник) Официальные сборки: **[релизы act_runner на gitea.com](https://gitea.com/gitea/act_runner/releases)**. 1. Открой страницу релизов и посмотри **последний стабильный** тег, например **`v1.0.2`**. 2. В списке файлов скачай **`gitea-runner-ВЕРСИЯ-linux-amd64`** — это один исполняемый файл **без** расширения `.zip` (не путай с `darwin` / `arm64`, если у тебя обычный ПК/сервер Intel/AMD). **Прямая ссылка (подставь свою версию из релиза):** `https://gitea.com/gitea/act_runner/releases/download/v1.0.2/gitea-runner-1.0.2-linux-amd64` В URL после `download/` идёт тег с **`v`**, в имени файла версия **без `v`**. **Скачать с Linux/WSL одной командой** (замени `1.0.2` на актуальную версию с сайта): ```bash mkdir -p ~/gitea-act-runner && cd ~/gitea-act-runner VERSION="1.0.2" curl -fL -o act_runner "https://gitea.com/gitea/act_runner/releases/download/v${VERSION}/gitea-runner-${VERSION}-linux-amd64" chmod +x act_runner ./act_runner --version ``` Если `curl` ругается на сертификат — обнови CA или скачай тот же файл через браузер и положи в папку, затем `chmod +x`. ### Шаг C — регистрация (подставь свой токен) В каталоге, где лежит `act_runner`, выполни **одну** команду (токен — тот, что выдала Gitea при создании раннера): ```bash cd ~/gitea-act-runner ./act_runner register --no-interactive \ --instance "https://git.mailib.ru" \ --token "ВСТАВЬ_СЮДА_ТОКЕН_ИЗ_МАСТЕРА_GITEA" \ --name "dnd-release-runner" \ --labels "ubuntu-22.04:host" ``` Пояснения: - **`--instance`** — корень твоего Gitea (**без** `/ifontosh/...`). - **`--labels "ubuntu-22.04:host"`** — job в **`.gitea/workflows/release.yml`** имеет `runs-on: ubuntu-22.04`, а **`:host`** означает выполнение **на самой машине**, с настоящим `apt` и Wine (см. [документацию по меткам](https://docs.gitea.com/usage/actions/act-runner#labels)). Если при регистрации оставить **дефолтные** метки с **`docker://`**, шаги тоже могут сработать, но образ другой; для предсказуемости лучше **`ubuntu-22.04:host`** на чистой Ubuntu 22.04. - После успешной регистрации в этой папке появится файл **`.runner`** — его не удаляй и не коммить. Если Gitea пишет ошибку регистрации — часто неверный **токен** (устарел после «сброса» в UI) или выбран не тот уровень (инстанс/организация/репозиторий). Создай раннера заново и возьми **новый** токен. ### Шаг D — запуск вручную (для проверки) В той же папке: ```bash ./act_runner daemon ``` Окно терминала должно остаться **открытым**. Остановка — `Ctrl+C`. Когда убедишься, что в Gitea раннер **online**, лучше перейти на **systemd** (шаг ниже). ### Шаг D1 — systemd: автозапуск после перезагрузки (подробно) Идея: **systemd** сам поднимает `act_runner daemon` при загрузке системы и перезапускает процесс при падении. Рабочая директория должна быть **та же**, где лежат **`act_runner`** и зарегистрированный файл **`.runner`** (обычно `~/gitea-act-runner`). #### 0) Подготовка 1. Регистрация (**шаг C**) уже выполнена, в каталоге есть **`.runner`**. 2. Узнай **точный путь** к каталогу (systemd не понимает `~`): ```bash cd ~/gitea-act-runner && pwd ``` Запомни вывод, например **`/home/ivan/gitea-act-runner`**. Имя пользователя Linux: ```bash whoami ``` Дальше в примерах: **`/home/ivan/gitea-act-runner`** и пользователь **`ivan`** — замени на свои. #### 1) Останови ручной запуск Если где-то в терминале уже крутится `./act_runner daemon` — заверши **Ctrl+C**, иначе два процесса будут мешать друг другу. #### 2) Создай unit-файл службы На **VPS / обычной Ubuntu** с правами root: ```bash sudo nano /etc/systemd/system/gitea-act-runner.service ``` Вставь текст **целиком** (подставь свои `User`, `Group`, `WorkingDirectory`, `ExecStart`): ```ini [Unit] Description=Gitea Actions act_runner Documentation=https://docs.gitea.com/usage/actions/act-runner After=network-online.target Wants=network-online.target [Service] Type=simple User=ivan Group=ivan WorkingDirectory=/home/ivan/gitea-act-runner ExecStart=/home/ivan/gitea-act-runner/act_runner daemon Restart=always RestartSec=10 # Логи в journald (см. ниже как читать) StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ``` Сохрани файл: в **nano** — **Ctrl+O**, Enter, **Ctrl+X**. Пояснения: - **`User` / `Group`** — под этим пользователем ты делал `register` и владеешь папкой (проверка: `ls -la ~/gitea-act-runner` — владелец должен совпадать). - **`WorkingDirectory`** — каталог с **`.runner`**; без него раннер может не найти регистрацию. - **`ExecStart`** — полный путь к бинарнику **`act_runner`** (тот, что скачал и сделал `chmod +x`). - Блок **`After=network-online.target`** — старт после сети (удобно для `git`/`npm` в CI). Если вдруг зависнет старт из‑за сетевого таргета, можно временно заменить на **`After=network.target`**. Официальный пример с отдельным пользователем `act_runner` и `config.yaml`: [Start the runner with Systemd](https://docs.gitea.com/usage/actions/act-runner#start-the-runner-with-systemd) — у нас проще: один пользователь и без отдельного `config.yaml`, пока дефолты устраивают. #### 3) Включи и запусти службу ```bash sudo systemctl daemon-reload sudo systemctl enable gitea-act-runner.service sudo systemctl start gitea-act-runner.service sudo systemctl status gitea-act-runner.service ``` В **`status`** должно быть **`active (running)`** зелёным. Если **`failed`** — смотри лог (шаг 5). Полезные команды: | Действие | Команда | | --------------------- | ------------------------------------------------------------- | | Остановить | `sudo systemctl stop gitea-act-runner` | | Запустить снова | `sudo systemctl start gitea-act-runner` | | Перезапуск | `sudo systemctl restart gitea-act-runner` | | Выключить автозапуск | `sudo systemctl disable gitea-act-runner` | | Проверка после ребута | перезагрузи машину, затем `systemctl status gitea-act-runner` | #### 4) Проверка в Gitea Как в **шаге E**: раннер снова **online** (иногда 10–30 секунд после `start`). #### 5) Логи, если что-то не так ```bash sudo journalctl -u gitea-act-runner -e --no-pager ``` В реальном времени: ```bash sudo journalctl -u gitea-act-runner -f ``` Типичные ошибки: неверный **`User`** (нет прав на каталог), **`WorkingDirectory`** не тот (нет **`.runner`**), бинарник не исполняемый (`chmod +x`), или старый процесс `act_runner` ещё запущен вручную. #### WSL2 (Ubuntu в Windows) Если раннер стоит **внутри WSL2**: 1. На современных WSL **systemd уже может быть включён**. Проверка: `systemctl status` — без ошибки «running in chroot». 2. Если `systemctl` недоступен: в файле **`/etc/wsl.conf`** внутри дистрибутива добавь блок **`[boot]`** с **`systemd=true`**, затем из **PowerShell** Windows выполни **`wsl --shutdown`**, снова зайди в Ubuntu и повтори шаги 2–3. Подробнее: [документация Microsoft про systemd в WSL](https://learn.microsoft.com/en-us/windows/wsl/systemd). После **`wsl --shutdown`** раннер на WSL не работает, пока ты снова не откроешь WSL (это нормально для «домашнего» CI). ### Шаг E — проверка в веб-интерфейсе Обнови **Настройки → Действия → Раннеры**: должен быть **1** раннер, статус **online**. У него в метках должно быть что-то вроде **`ubuntu-22.04`** (в связке с **host**). ### Если у тебя только Windows Установи **WSL2** и дистрибутив **Ubuntu 22.04**, открой терминал Ubuntu и выполни шаги B–D **там** (это уже Linux). Файловую систему Windows из WSL видно как `/mnt/d/...`, но проще держать каталог раннера в домашнем каталоге Linux (`~/gitea-act-runner`). Официальная документация: [Gitea — Act Runner](https://docs.gitea.com/usage/actions/act-runner). Если раннер заводит **админ инстанса** — логика та же: раннер должен быть **online** и иметь метку, подходящую под **`runs-on`** в `release.yml` (сейчас **`ubuntu-22.04`**; при **`ubuntu-22.04:host`** в Gitea это сопоставляется с `runs-on: ubuntu-22.04`). --- ## Шаг 3 — включить Actions (если ещё не включены) 1. В том же **приватном** репозитории: **«Настройки»**. 2. Раздел **«Действия»** / **«Actions»** — включи использование Actions для этого репозитория, если Gitea это спрашивает. 3. Убедись, что в корне репозитория есть файл **`.gitea/workflows/release.yml`** (он уже в проекте `dnd_player`). Бегунки Gitea должны иметь доступ в интернет (для `npm ci`, `actions/checkout` и т.д.) — это настраивает админ сервера. ### Метки `runs-on` (если раннер уже есть, но job не берётся) - В списке раннеров посмотри **метки** у online-раннера. - В **`.gitea/workflows/release.yml`** в `runs-on:` должна совпадать **именно метка `ubuntu-22.04`** (Gitea сопоставляет её и с **`ubuntu-22.04:host`**, и с **`ubuntu-22.04:docker://...`** — см. [Labels](https://docs.gitea.com/usage/actions/act-runner#labels) в документации act_runner). - Если при регистрации указал только **`self-hosted`** — добавь **`ubuntu-22.04:host`** (или поменяй `runs-on` в workflow на твои метки и закоммить). Сборка **Windows (NSIS)** в CI идёт **на Linux** с **Wine**. Отдельная **macOS**-сборка в workflow отключена, пока нет Mac-раннера (см. комментарии в `release.yml`). --- ## Шаг 4 — выпуск версии 1. В `package.json` версия должна совпасть с тегом (workflow при пуше тега делает `npm version` из имени тега — удобно). 2. Закоммить все изменения в **приватный** репо, затем: ```bash git tag v1.0.1 git push origin main git push origin v1.0.1 ``` (ветка может быть не `main` — подставь свою.) 3. Открой в Gitea **«Действия»** у приватного репо — должен появиться запуск **Release**. Дождись успеха job’ов **build-windows** и **publish-update-feed** (после появления раннера, см. раздел выше). 4. После успеха открой **публичный** `DndGamePlayerUpdates` → ветка **`updates`** — в корне должны появиться `latest.yml`, установщики и т.д. --- ## Контрольный чеклист 1. **`package.json` → `build.publish.url`** = `https://git.mailib.ru/ifontosh/DndGamePlayerUpdates/raw/branch/updates/` Совпадает с **`DND_UPDATE_FEED_URL`** (со слэшем в конце). 2. В **DndGamePlayerUpdates** есть хотя бы один коммит (не пустой репо). 3. В приватном репо заданы **все четыре** секрета из таблицы шага 2 (имена **не** начинаются с `GITEA_`). 4. В репо с кодом есть **`.gitea/workflows/release.yml`**. 5. Релиз: пуш тега `v*` → в Actions job’ы **build-windows** и **publish-update-feed**; в публичном репо появляется ветка **`updates`** с `latest.yml` и установщиками (нужен online-раннер, см. раздел про act_runner). 6. В приложении: обновления только **`app.isPackaged`** и при **активной лицензии** (см. `app/main/update/installAutoUpdater.ts`). --- ## Поведение приложения - Проверка только в **собранной** установке (`app.isPackaged`). - Только если **лицензия активна**. - Первый запрос примерно через **12 с** после старта; при смене лицензии — снова (не чаще **30 с**). - Для отладки можно задать переменную окружения **`DND_UPDATE_FEED_URL`** при запуске `.exe` — переопределит feed. Подпись кода в CI отключена: `CSC_IDENTITY_AUTO_DISCOVERY=false`. --- ## Локальная отладка feed Запуск установленного приложения с другим URL (без пересборки): задать **`DND_UPDATE_FEED_URL`** в ярлыке или системных переменных окружения. --- ## Как сделать так, чтобы ассистент в Cursor мог «выпустить релиз» У ассистента **нет своего аккаунта** на `git.mailib.ru`. Релиз = **появление тега `v*`** на нужном коммите в **приватном** репозитории с кодом → Gitea Actions собирает и пушит feed. Ниже два рабочих варианта. ### Вариант A — Gitea MCP (удобно из чата) У тебя уже подключён MCP **user-gitea-mailib** с инструментом **`create_tag`**: по API создаётся тег на сервере (аналог `git tag` + `git push` тега). **Что сделать один раз:** 1. В Cursor MCP для Gitea должен быть **включён и залогинен** под учёткой, у которой есть право **создавать теги** в приватном репо с `dnd_player`. 2. Знать **`owner`** и **`repo`** этого репозитория (как в URL: `https://git.mailib.ru/OWNER/REPO`). **Как просить в чате:** «Создай тег `v1.0.2` в репозитории `OWNER/REPO` с целевой веткой `main`» (или укажи SHA коммита). Перед этим **весь код релиза уже должен быть запушен** в эту ветку — тег вешается на последний коммит (или на явный `target`). После создания тега зайди в **Действия** репозитория и проверь workflow **Release**. _(Отдельно: `create_release` в MCP создаёт **запись релиза** на Gitea; сборку у тебя запускает именно **тег** и `release.yml`.)_ ### Вариант B — команды `git` в терминале Cursor Ассистент может выполнить у тебя локально: ```bash git fetch origin git tag v1.0.2 origin/main # или другая ветка / коммит git push origin v1.0.2 ``` **Что сделать один раз:** 1. Чтобы `git push` **не спрашивал пароль** каждый раз: настроить **учётные данные** (Windows: диспетчер учётных данных / `git credential-manager`; либо **SSH-ключ** и remote `git@git.mailib.ru:...`). 2. Убедиться, что из того же окружения, где работает Cursor, `git push` в приватный репо уже проходил успешно. Тогда в чате можно написать: «Поставь тег `v1.0.2` на `origin/main` и запушь тег» — ассистент выполнит команды в `dnd_player`. ### Ограничения - Ассистент **не видит** твои пароли и не обходит Gitea: всё упирается в **MCP-токен** или **твои локальные git credentials**. - Если MCP отключён и git без настроенного доступа — релиз тегом придётся пушить **тебе** вручную (как в шаге 4 выше). --- ## Про коммит и пуш кода (не тег) Закоммитить и запушить **изменения в файлах** ассистент может через те же механизмы: либо ты делаешь `git push` после правок, либо настроенный **git** / отдельный скрипт. Без доступа к remote ассистент только правит файлы в рабочей копии.