Files
DndGamePlayer/docs/GITEA_AUTO_UPDATE.md
T
Ivan Fontosh 8fa8467db7
Release / release (push) Successful in 7m10s
fix(ci): stream update feed squash push
Split the squashed updates feed upload through a temporary branch so large installers are pushed in smaller packs, then publish the completed updates branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 14:14:54 +08:00

38 KiB
Raw Blame History

Автообновление через 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. Либо с компьютера:
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 и которая видит 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 (пакеты nsis, wine64) на Linux. Multiarch i386 намеренно не включается — на Debian с репозиториями только под amd64 (nginx, sury и т.п.) установка wine32 часто падает с «unmet dependencies». После установки wine64 в CI создаётся скрипт /usr/local/bin/wine с exec по полному пути к wine64 (в job у act_runner иногда пустой/урезанный PATH, тогда имя wine64 без пути не находится). electron-builder проверяет именно команду wine в PATH. Поэтому:

  • Нужен 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.

  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 на актуальную версию с сайта):

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 при создании раннера):

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 (см. документацию по меткам). Если при регистрации оставить дефолтные метки с docker://, шаги тоже могут сработать, но образ другой; для предсказуемости лучше ubuntu-22.04:host на чистой Ubuntu 22.04.
  • После успешной регистрации в этой папке появится файл .runner — его не удаляй и не коммить.

Если Gitea пишет ошибку регистрации — часто неверный токен (устарел после «сброса» в UI) или выбран не тот уровень (инстанс/организация/репозиторий). Создай раннера заново и возьми новый токен.

Шаг D — запуск вручную (для проверки)

В той же папке:

./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 не понимает ~):
cd ~/gitea-act-runner && pwd

Запомни вывод, например /home/ivan/gitea-act-runner. Имя пользователя Linux:

whoami

Дальше в примерах: /home/ivan/gitea-act-runner и пользователь ivan — замени на свои.

1) Останови ручной запуск

Если где-то в терминале уже крутится ./act_runner daemon — заверши Ctrl+C, иначе два процесса будут мешать друг другу.

2) Создай unit-файл службы

На VPS / обычной Ubuntu с правами root:

sudo nano /etc/systemd/system/gitea-act-runner.service

Вставь текст целиком (подставь свои User, Group, WorkingDirectory, ExecStart):

[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

Сохрани файл: в nanoCtrl+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 — у нас проще: один пользователь и без отдельного config.yaml, пока дефолты устраивают.

3) Включи и запусти службу

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) Логи, если что-то не так

sudo journalctl -u gitea-act-runner -e --no-pager

В реальном времени:

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.

После 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.

Если раннер заводит админ инстанса — логика та же: раннер должен быть 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 в документации act_runner).
  • Если при регистрации указал только self-hosted — добавь ubuntu-22.04:host (или поменяй runs-on в workflow на твои метки и закоммить).

Сборка Windows (NSIS) и Linux (AppImage x64 + arm64) в CI идёт на одном ubuntu-22.04: NSIS + wine64 для Win, qemu-user-static для кросс-сборки arm64 AppImage на amd64 (см. release.yml). macOS в этом job не собирается (ручная выкладка или отдельный раннер — см. docs/MANUAL_MAC_UPDATE_UPLOAD.md).


Linux: AppImage и автообновление

  • В ветке updates рядом с Windows лежат latest-linux.yml и файлы *.AppImage (x64 и arm64). Скрипт scripts/sync-update-feed.mjs делает merge-копирование: файлы других ОС в репозитории не удаляются, обновляются только имена, пришедшие из текущего CI-прогона.
  • Базовый дистрибутив для бинарников: сборка на Ubuntu 22.04 (glibc 2.35) — совместимость с «максимумом» настольных дистрибутивов с glibc не старее целевого; Alpine/musl без отдельной сборки не гарантируется.
  • Запуск AppImage: на части систем нужен FUSE (например libfuse2 для старых форматов / документация дистрибутива). Подпись пакетов в первом варианте не используется (как договорённость по проекту).
  • Правила electron-updater в приложении те же: упакованная сборка и активная лицензия (installAutoUpdater.ts).

Шаг 4 — выпуск версии

  1. В package.json версия должна совпасть с тегом (workflow при пуше тега делает npm version из имени тега — удобно).
  2. Закоммить все изменения в приватный репо, затем:
git tag v1.0.1
git push origin main
git push origin v1.0.1

(ветка может быть не main — подставь свою.)

  1. Открой в Gitea «Действия» у приватного репо — должен появиться запуск Release. Дождись успеха job release (после появления раннера, см. раздел выше).

  2. После успеха открой публичный DndGamePlayerUpdates → ветка updates — в корне должны появиться latest.yml, установщики и т.д.


Контрольный чеклист

  1. package.jsonbuild.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 release: сборка Windows + Linux AppImage и push feed; в публичном репо ветка updates содержит latest.yml, latest-linux.yml, установщики Windows и .AppImage для Linux (нужен online-раннер ubuntu-22.04, см. раздел про act_runner). Скрипт sync не затирает артефакты других платформ при обновлении.
  6. В приложении: обновления только app.isPackaged и при активной лицензии (см. app/main/update/installAutoUpdater.ts).

Если git push в updates падает: remote end hung up / таймаут

Один коммит с Windows + два AppImage может быть сотни МБ — HTTPS-push иногда рвётся из‑за лимита буфера Git или таймаута nginx / reverse proxy перед Gitea.

В репозитории с кодом скрипт scripts/sync-update-feed.mjs уже выставляет в клоне feed-репо:

  • http.postBuffer 2 GiB;
  • отключение «медленной передачи» (http.lowSpeedLimit / http.lowSpeedTime);
  • до 3 повторов git push с паузой 20 с (переменная DND_GIT_PUSH_RETRIES, максимум 5).

Если ошибка сохраняется — на сервере (nginx и т.п.) проверьте, например:

  • client_max_body_size — не меньше размера push (или 0 для безлимита, если политика безопасности позволяет);
  • proxy_read_timeout / proxy_send_timeoutнесколько минут и больше для больших загрузок;
  • лимиты самого Gitea ([repository.upload], APP_MAX_FILE_SIZE в зависимости от версии) — в документации вашей сборки Gitea.

Линейная история в UPDATES_REPO (например DndGamePlayerUpdates)

Переписывается только публичный репозиторий из секрета UPDATES_REPO, ветка updates. Репозиторий с исходниками игры (DndGamePlayer) и его теги не меняются.

В workflow задано DND_UPDATES_SQUASH_HISTORY=1: после merge и подкладки артефактов скрипт делает git checkout --orphan и собирает историю только текущего релиза. Чтобы не отправлять один огромный pack (~700+ MiB) и не ловить curl 55 Broken pipe, загрузка идёт через временную ветку updates-upload-*: сначала small files, затем каждый большой файл отдельным push (порог DND_FEED_LARGE_FILE_BYTES, по умолчанию 64 MiB). Ветка updates передвигается на готовый финальный коммит только в конце через --force-with-lease (если ветка уже была) или обычный первый push. Пользователи не видят «полурелиз», потому что updates меняется только после полной загрузки.

На сервере Gitea старые объекты коммитов остаются «висячими», пока не отработает сборка мусора репозитория (настройки сервера / ручной git gc в bare-репо). Для пользователей приложения важны только URL latest*.yml и установщиков — они не меняются по смыслу.

Не запускайте два релиза, которые одновременно пушат feed, — возможна гонка и отказ --force-with-lease.


Если push отклонён: (fetch first) / rejected

Пока job собирает артефакты, в updates мог успеть попасть другой коммит (второй релиз, ручная выкладка). Скрипт sync-update-feed.mjs перед push (в режиме без squash) делает git fetch + git merge origin/updates (и после клона — то же в начале), плюс shallow глубина (DND_UPDATES_CLONE_DEPTH: по умолчанию 40, при DND_UPDATES_SQUASH_HISTORY=1 в скрипте по умолчанию 8). В режиме squash перед финальным push merge не выполняется — уже смерженное дерево отправляется через временную ветку и затем публикуется force-with-lease. Не запускайте два релиза одного и того же репо одновременно по двум тегам — возможны конфликты merge.


ENOSPC / «no space left on device» при sync

Частая причина: дублирование артефактов (release/_linux/_win → временный клон в /tmp) на раннере с маленьким root. Сейчас CI не копирует в _win/_linux: ARTIFACT_WIN и ARTIFACT_LINUX указывают на release/, а временный клон feed создаётся под DND_FEED_TMP_ROOT (в workflow — ${{ github.workspace }}/.dnd-feed-tmp). Скрипт по возможности делает rename файлов в клон (без второй полной копии на том же диске).

Если ошибка остаётся — на машине раннера нужно освободить место или увеличить диск / вынести workspace на больший том.

Перед git clone скрипт проверяет свободное место на томе, где лежит DND_FEED_TMP_ROOT (оценка: артефакты × 2.5 + ~1 GiB запас, минимум ~2 GiB). Если проверка мешает (редкий ложный срабатывание), можно задать DND_FEED_SKIP_DISK_CHECK=1 (лучше всё же поправить диск).

Несколько неудачных git fetch подряд (обрыв TLS) могли раньше забивать диск частично распакованными pack-файлами; между попытками вызывается git gc --prune=now.


Сбой fetch: GnuTLS recv error / early EOF

Сеть или TLS к серверу Gitea. Скрипт делает несколько повторов git fetch (DND_GIT_FETCH_RETRIES, по умолчанию 6), между попытками — git gc --prune=now, для clone/fetch задано http.version=HTTP/1.1 (иногда стабильнее за прокси). Если ветки updates на сервере ещё нет, merge намеренно пропускается (первый push feed); при любой другой ошибке fetch job завершится ошибкой — не будет «тихого» продолжения с последующим ENOSPC на git add.

При стабильных обрывах проверьте прокси/MTU/антивирус на раннере и лимиты прокси к Gitea.


Поведение приложения

  • Проверка только в собранной установке (app.isPackaged).
  • Только если лицензия активна.
  • Первый запрос примерно через 12 с после старта; при смене лицензии — снова (не чаще 30 с).
  • Для отладки можно задать переменную окружения DND_UPDATE_FEED_URL при запуске приложения (Windows / Linux / macOS) — переопределит feed.

Подпись кода в CI отключена: CSC_IDENTITY_AUTO_DISCOVERY=false (в т.ч. Linux AppImage без репозитория подписи).


Локальная отладка 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

Ассистент может выполнить у тебя локально:

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 ассистент только правит файлы в рабочей копии.