Sueta

Gitizen

1.0.0

Sync Denizen scripts directly with your GitHub repository.

·Script

Gitizen

Безопасное обновление Denizen-скриптов из Git прямо на Minecraft-сервере.

Gitizen загружает нужную ветку репозитория, проверяет новые скрипты, аккуратно
заменяет рабочий каталог Denizen и автоматически возвращает предыдущую версию,
если Denizen обнаруживает ошибку.


Contents / Содержание


Русский

Возможности

  • Синхронизация Denizen-скриптов с GitHub по HTTPS.
  • Работа с приватными и публичными репозиториями.
  • Несколько профилей, например production и staging.
  • Отдельная ветка и каталог для каждого профиля.
  • Проверка файлов .dsc parser-ом установленного Denizen.
  • Безопасная замена каталога через staging-папку.
  • Автоматический возврат предыдущей версии при ошибке загрузки Denizen.
  • Ручной rollback по номеру deployment или commit hash.
  • Команда статуса с текущим и удалённым commit.
  • История deployment и постоянные метрики.
  • Discord и Telegram уведомления.
  • Интерактивные сообщения: hover-подсказки, копирование hash и ссылки на GitHub.
  • Защита от одновременного запуска двух операций одного профиля.
  • Обнаружение файлов, вручную изменённых в рабочем каталоге.

Git checkout хранится в plugins/Gitizen/repositories, а не в
plugins/Denizen/scripts. Поэтому папка Denizen не содержит .git и используется
только для активных скриптов.

Требования

  • Paper 1.21.x.
  • Java 21 или новее.
  • Установленный и запущенный Denizen.
  • Исходящий HTTPS-доступ к GitHub.
  • Для уведомлений — исходящий HTTPS-доступ к Discord или Telegram.

Gitizen зависит от Denizen. Если Denizen отсутствует, Paper не загрузит Gitizen.

Установка

  1. Остановите Minecraft-сервер.
  2. Скопируйте Gitizen-1.0.0.jar в папку plugins.
  3. Убедитесь, что Denizen.jar также находится в папке plugins.
  4. Запустите сервер один раз.
  5. Остановите сервер и откройте plugins/Gitizen/config.yml.
  6. Укажите URL репозитория и нужную ветку.
  7. Если репозиторий приватный, настройте токен.
  8. Запустите сервер и выполните /gitizen status.
  9. Для первого deployment выполните /gitizen sync.

Перед первой установкой рекомендуется сохранить резервную копию
plugins/Denizen/scripts. Во время дальнейших deployment Gitizen самостоятельно
сохраняет предыдущий рабочий каталог до завершения проверки.

Быстрый старт

Публичный репозиторий

Минимальная конфигурация:

default-profile: "production"

profiles:
  production:
    repo-url: "https://github.com/USER/REPOSITORY.git"
    branch: "main"
    repository-subdirectory: ""
    target-directory: "scripts"
    reload-denizen: true
    username: "gitizen"
    token-env: "GITIZEN_GITHUB_TOKEN"
    token: ""

Если .dsc находятся, например, в папке minecraft/denizen внутри репозитория:

repository-subdirectory: "minecraft/denizen"

После сохранения конфигурации:

/gitizen reload
/gitizen status production
/gitizen sync production

Приватный репозиторий

Создайте GitHub fine-grained Personal Access Token с доступом только к нужному
репозиторию и разрешением Contents: Read.

Предпочтительный вариант — переменная окружения:

GITIZEN_GITHUB_TOKEN=github_pat_...

Название переменной указывается в:

token-env: "GITIZEN_GITHUB_TOKEN"

На игровых хостингах переменные окружения могут называться «Environment variables»,
«Startup variables» или «Secrets». Если панель их не поддерживает, токен можно
записать непосредственно в конфиг:

token-env: ""
token: "github_pat_..."

Не передавайте PAT через Minecraft-команду. Команда /gitizen setup намеренно
не принимает токен, чтобы он не оказался в консольных логах.

Профили production и staging

Профиль — это сохранённый сценарий deployment. Он отвечает на пять вопросов:

  1. Из какого Git-репозитория загружать файлы?
  2. Какую ветку использовать?
  3. Из какой папки внутри репозитория брать скрипты?
  4. В какую папку Denizen их поместить?
  5. Нужно ли после этого перезагрузить активные скрипты?

Названия production и staging сами по себе ничего не переключают. Это обычные
имена профилей, которые можно изменить. Поведение определяется значениями
branch, repository-subdirectory, target-directory и reload-denizen.

В стандартной схеме профили используются так:

ПрофильВетка GitКуда копируются файлыDenizen исполняет эти файлы?
productionmainplugins/Denizen/scriptsДа, сразу после успешной проверки
stagingdevelopplugins/Denizen/scripts-stagingНет, это отдельная тестовая копия

Пример двух профилей:

default-profile: "production"

profiles:
  production:
    repo-url: "https://github.com/USER/REPOSITORY.git"
    branch: "main"
    repository-subdirectory: "denizen"
    target-directory: "scripts"
    reload-denizen: true
    username: "gitizen"
    token-env: "GITIZEN_GITHUB_TOKEN"
    token: ""

  staging:
    repo-url: "https://github.com/USER/REPOSITORY.git"
    branch: "develop"
    repository-subdirectory: "denizen"
    target-directory: "scripts-staging"
    reload-denizen: false
    username: "gitizen"
    token-env: "GITIZEN_GITHUB_TOKEN"
    token: ""

Что произойдёт при sync production

/gitizen sync production

Gitizen выполнит следующую последовательность:

  1. Загрузит ветку main из указанного repo-url.
  2. Возьмёт только содержимое папки denizen из репозитория.
  3. Проверит найденные .dsc parser-ом Denizen.
  4. Подготовит новую версию во временной папке.
  5. Заменит plugins/Denizen/scripts.
  6. Перезагрузит Denizen, потому что указано reload-denizen: true.
  7. При ошибке автоматически вернёт предыдущие скрипты.

После успешной команды изменения становятся активными на игровом сервере.

Что произойдёт при sync staging

/gitizen sync staging

Gitizen загрузит ветку develop, проверит файлы и положит их в
plugins/Denizen/scripts-staging. Рабочая папка plugins/Denizen/scripts при
этом не изменяется, а Denizen продолжает исполнять текущую production-версию.

Профиль staging полезен, чтобы:

  • убедиться, что нужные файлы действительно загружаются из Git;
  • заранее проверить структуру .dsc;
  • посмотреть подготовленную версию на сервере;
  • не затронуть игроков во время подготовки релиза.

Важно: Gitizen не переносит staging в production автоматически. Обычный безопасный
процесс выглядит так:

  1. Разработчик отправляет изменения в ветку develop.
  2. Администратор выполняет /gitizen sync staging и проверяет результат.
  3. Изменения объединяются из develop в main через GitHub.
  4. Администратор выполняет /gitizen sync production.

Staging-проверка подтверждает, что файлы читаются parser-ом, но не проверяет их
поведение внутри игры: reload-denizen: false означает, что эти файлы не
подключаются к работающему Denizen.

Разница между source и target

Эти два параметра часто путают:

  • repository-subdirectory — откуда брать файлы внутри Git-репозитория;
  • target-directory — куда помещать файлы на Minecraft-сервере.

Для приведённого примера путь выглядит так:

GitHub: REPOSITORY/denizen/
                   │
                   ├─ production → plugins/Denizen/scripts/
                   └─ staging    → plugins/Denizen/scripts-staging/

target-directory задаётся относительно plugins/Denizen:

ЗначениеПолный путь на сервере
scriptsplugins/Denizen/scripts
scripts-stagingplugins/Denizen/scripts-staging
test/server-oneplugins/Denizen/test/server-one

Указать ../ и выйти за пределы plugins/Denizen нельзя — Gitizen заблокирует
такую конфигурацию.

Что означает reload-denizen

  • true — после замены файлов Gitizen просит Denizen загрузить новую версию.
    Используйте это для активного production-каталога.
  • false — файлы копируются и проверяются, но работающий Denizen их не загружает.
    Используйте это для staging, архива или ручной проверки.

Если указано reload-denizen: true, Gitizen сверяет target-directory с реальной
активной папкой Denizen. При несовпадении deployment останавливается. Это защищает
от ситуации, когда команда сообщает об успехе, но Denizen продолжает использовать
другую папку.

Разные репозитории и токены

Профили не обязаны использовать один репозиторий. Например, production можно
загружать из закрытого основного репозитория, а staging — из отдельного тестового.
Для разных токенов укажите разные переменные окружения:

profiles:
  production:
    token-env: "GITIZEN_PRODUCTION_TOKEN"
  staging:
    token-env: "GITIZEN_STAGING_TOKEN"

default-profile: "production" означает, что команда /gitizen sync без имени
профиля равнозначна /gitizen sync production.

Профиль можно создать командой:

/gitizen setup production https://github.com/USER/REPOSITORY.git main

После изменения repository-subdirectory, каталога или секретов выполните
/gitizen reload.

Команды

КомандаОписаниеПраво
/gitizen helpПоказать доступные команды—
/gitizen sync [profile]Проверить и развернуть выбранную веткуgitizen.sync
/gitizen status [profile]Показать Git HEAD, remote HEAD и метрикиgitizen.status
/gitizen rollback [profile] <номер|hash>Вернуть предыдущую версиюgitizen.rollback
/gitizen logs [profile] [count]Показать последние commitsgitizen.logs
/gitizen list [profile]Показать все .dsc рекурсивноgitizen.list
/gitizen profilesПоказать настроенные профилиgitizen.status
/gitizen setup <profile> <url> [branch]Создать или изменить профильgitizen.admin
/gitizen reloadПеречитать config.ymlgitizen.admin

Если профиль не указан, используется default-profile.

Право gitizen.admin включает все остальные права.

Что показывает status

/gitizen status production выводит:

  • ветку профиля;
  • HEAD внутреннего checkout;
  • HEAD удалённой ветки;
  • commit, который сейчас развёрнут;
  • дату последнего успешного deployment;
  • количество успешных и неуспешных операций;
  • длительность и число файлов последней операции.

Если deployed commit отличается от remote HEAD, доступно обновление либо сейчас
активен rollback.

Rollback

Вернуть deployment, который был перед текущим:

/gitizen rollback 1

То же для конкретного профиля:

/gitizen rollback production 1

Откатиться на конкретный commit:

/gitizen rollback production a1b2c3d

Число означает позицию среди предыдущих успешных deployment:

  • 1 — версия перед текущей;
  • 2 — ещё одна версия назад.

История хранится в plugins/Gitizen/state.yml. Её размер задаётся параметром
deployment.max-history.

После ручного rollback команда /gitizen sync снова развернёт актуальный
origin/<branch>.

Автоматический rollback

Перед заменой рабочей папки Gitizen проверяет staging-файлы parser-ом Denizen.
После замены выполняется настоящий reload Denizen. Если Denizen сообщает об ошибке:

  1. Новая папка удаляется.
  2. Возвращается предыдущая папка.
  3. Возвращается предыдущий Git HEAD.
  4. Denizen повторно загружает восстановленные скрипты.
  5. Ошибка записывается в метрики и отправляется в настроенные уведомления.

Discord и Telegram

Отдельно хостить бота или веб-приложение не требуется. Gitizen отправляет HTTPS-запрос
прямо с Minecraft-сервера. Хостинг должен разрешать исходящие соединения.

Discord

  1. Откройте настройки Discord-сервера.
  2. Перейдите в Integrations → Webhooks.
  3. Создайте webhook и скопируйте URL.
  4. Передайте URL через переменную окружения:
GITIZEN_DISCORD_WEBHOOK=https://discord.com/api/webhooks/...

Конфигурация:

notifications:
  discord:
    webhook-url-env: "GITIZEN_DISCORD_WEBHOOK"
    webhook-url: ""

Если переменные окружения недоступны, URL можно записать в webhook-url.

Telegram

  1. Создайте бота через @BotFather.
  2. Отправьте своему боту любое сообщение.
  3. Получите ID пользователя, группы или канала.
  4. Добавьте бота в нужную группу/канал и выдайте необходимые права.
  5. Настройте переменные:
GITIZEN_TELEGRAM_BOT_TOKEN=123456:ABC...
GITIZEN_TELEGRAM_CHAT_ID=-1001234567890

Конфигурация:

notifications:
  telegram:
    bot-token-env: "GITIZEN_TELEGRAM_BOT_TOKEN"
    chat-id-env: "GITIZEN_TELEGRAM_CHAT_ID"
    bot-token: ""
    chat-id: ""

Если уведомления не приходят, проверьте токен, chat ID, права бота и доступ
Minecraft-хостинга к api.telegram.org.

Настройки безопасности

security:
  require-https: true
  allowed-hosts:
    - "github.com"

validation:
  require-dsc-files: true
  max-script-size-kb: 1024

deployment:
  max-history: 20
  max-changes-in-chat: 30
  • require-https запрещает незашифрованные и SSH URL.
  • allowed-hosts ограничивает серверы, которым Gitizen может передать Git credentials.
  • require-dsc-files запрещает deployment без Denizen-скриптов.
  • max-script-size-kb ограничивает размер одного проверяемого скрипта.
  • max-history определяет глубину rollback.
  • max-changes-in-chat ограничивает количество строк изменений в Minecraft-чате.

Для GitHub Enterprise добавьте его домен в allowed-hosts.

Репозиторий Denizen фактически содержит исполняемую серверную логику. Выдавайте
доступ на запись только доверенным разработчикам и используйте read-only PAT.

Частые проблемы

«Ветка не найдена в origin»

Проверьте точное имя branch, регистр букв и наличие этой ветки в репозитории.

«Хост отсутствует в security.allowed-hosts»

Добавьте домен Git-сервера в security.allowed-hosts. Не добавляйте неизвестные
домены, если используете приватный токен.

Ошибка авторизации GitHub

Проверьте:

  • URL использует HTTPS;
  • PAT не истёк;
  • PAT имеет Contents: Read для нужного репозитория;
  • организация разрешила токен, если используется SSO;
  • переменная окружения действительно передана процессу Java.

«target-directory не совпадает с активным каталогом Denizen»

Для профиля с reload-denizen: true каталог должен совпадать с папкой, которую
реально использует Denizen. Обычно это plugins/Denizen/scripts, поэтому значение
должно быть scripts.

Deployment отклонён до активации

Проверьте сообщения Gitizen и консоль. Возможные причины: пустой .dsc, ошибка
структуры YAML/Denizen, слишком большой файл, symlink или отсутствие .dsc.

Уведомления не отправляются

Убедитесь, что хостинг разрешает исходящий HTTPS на:

  • github.com;
  • discord.com;
  • api.telegram.org.

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

Старый config.yml

Конфигурация старых версий с ключами repo-url, github-token и branch
читается как профиль production. Для доступа ко всем новым настройкам рекомендуется
сделать копию старого файла, удалить его и перезапустить сервер, затем перенести URL,
ветку и токен в новую структуру.

Служебные файлы

ПутьНазначение
plugins/Gitizen/config.ymlПользовательские настройки
plugins/Gitizen/state.ymlИстория и метрики
plugins/Gitizen/repositories/<profile>Внутренние Git checkout
plugins/Denizen/scriptsАктивные production-скрипты

Не редактируйте внутренние checkout вручную. Изменения в активном каталоге будут
обнаружены и заменены при следующем sync.


English

Gitizen safely deploys Denizen scripts from Git repositories directly to a
Minecraft server. It fetches the configured branch, validates the candidate
scripts, swaps the Denizen directory, and restores the previous version
automatically when Denizen reports an error.

Features

  • Public and private GitHub repositories over HTTPS.
  • Multiple deployment profiles such as production and staging.
  • A separate repository, branch, source directory, and target for each profile.
  • Preflight validation using the parser of the installed Denizen plugin.
  • Staged directory replacement and automatic rollback.
  • Manual rollback by deployment number or commit hash.
  • Status command with repository, remote, deployment, and metrics information.
  • Persistent deployment history.
  • Discord and Telegram notifications.
  • Adventure components with hover details, hash copying, and GitHub links.
  • Per-profile operation lock and working-directory drift detection.

Git checkouts are stored under plugins/Gitizen/repositories. The active
plugins/Denizen/scripts directory is not used as a Git repository.

Requirements

  • Paper 1.21.x.
  • Java 21 or newer.
  • Denizen installed and enabled.
  • Outbound HTTPS access to GitHub.
  • Outbound HTTPS access to Discord or Telegram when notifications are enabled.

Gitizen declares Denizen as a required dependency.

Installation

  1. Stop the Minecraft server.
  2. Copy Gitizen-1.0.0.jar to the plugins directory.
  3. Make sure Denizen is installed.
  4. Start the server once.
  5. Stop it and open plugins/Gitizen/config.yml.
  6. Configure the repository URL and branch.
  7. Configure a token if the repository is private.
  8. Start the server and run /gitizen status.
  9. Run /gitizen sync for the first deployment.

Create a manual backup of plugins/Denizen/scripts before the first installation.
Gitizen protects the previous directory during later deployments.

Quick start

Minimal public-repository configuration:

default-profile: "production"

profiles:
  production:
    repo-url: "https://github.com/USER/REPOSITORY.git"
    branch: "main"
    repository-subdirectory: ""
    target-directory: "scripts"
    reload-denizen: true
    username: "gitizen"
    token-env: "GITIZEN_GITHUB_TOKEN"
    token: ""

If scripts are stored in a repository subdirectory:

repository-subdirectory: "minecraft/denizen"

Apply and deploy:

/gitizen reload
/gitizen status production
/gitizen sync production

For a private repository, create a fine-grained GitHub Personal Access Token with
Contents: Read access to the required repository. Prefer an environment variable:

GITIZEN_GITHUB_TOKEN=github_pat_...

If your hosting panel does not support environment variables:

token-env: ""
token: "github_pat_..."

Do not send the token through a Minecraft command. /gitizen setup intentionally
does not accept secrets.

Production and staging profiles

A profile is a saved deployment recipe. It answers five questions:

  1. Which Git repository should be fetched?
  2. Which branch should be used?
  3. Which directory inside the repository contains the scripts?
  4. Which Denizen directory should receive them?
  5. Should the active Denizen scripts be reloaded afterward?

production and staging are not special keywords. They are ordinary profile
names. Their behavior comes from branch, repository-subdirectory,
target-directory, and reload-denizen.

The default workflow is:

| Profile | Git branch | Destination |

Similar projects

Script →