UnicoreCMS

Установка

Из каталога, по ссылке, из архива или руками; обновление, включение, удаление

Готовые расширения лежат в двух репозиториях: модули и темы. Панель видит их релизы и ставит одной кнопкой; архив из файла и папка руками тоже остаются.

Из каталога

Утилиты → Модули (или Темы), блок Каталог. В нём — последние релизы из подключённых источников с версией, описанием и состоянием: не установлено, установлено, есть обновление. Кнопка рядом делает то, что написано: Установить, Обновить или Переустановить — последняя перекачивает и ставит заново тот же релиз, если файлы на сервере повредились или зеркало обновило архив, не меняя версию. Дальше всё как при установке из архива: панель подскажет, что осталось включить, пересобрать или перезапустить.

Каталог обновляется раз в десять минут; кнопка Обновить над таблицей перечитывает источники сразу. Совместимость проверяется по unicoreApi релиза — несовместимое расширение показывается, но кнопка установки у него выключена.

Источники

Кнопка Источники открывает список того, откуда каталог берёт релизы. Встроенные источники — репозитории UnicoreCMS; их можно выключить, но не удалить. Свои добавляются двух видов:

ТипЧто указатьОткуда берутся расширения
GitHubРепозиторий в виде owner/repoРелизы репозитория: каждый релиз — один архив <id>-<версия>.zip
Ссылка на каталогАдрес JSONСписок расширений в файле, архивы по ссылкам из него

Для закрытого репозитория GitHub у источника есть поле Токен — personal access token с правом чтения. Он хранится зашифрованным, наружу не отдаётся и уходит только на api.github.com; для открытых репозиториев токен тоже полезен: без него GitHub ограничивает число запросов.

Каталог по ссылке — это JSON такого вида, его удобно держать на зеркале или своём сервере:

catalog.json
{
  "extensions": [
    {
      "id": "screens",
      "kind": "module",
      "version": "1.2.0",
      "name": { "ru": "Скриншоты", "en": "Screenshots" },
      "description": { "ru": "Галерея скриншотов игроков" },
      "unicoreApi": "^1.4.0",
      "download": "https://mirror.example.com/unicore/screens-1.2.0.zip"
    }
  ]
}

Поле download может быть относительным — тогда оно считается от адреса каталога. Как выкладывать релизы на GitHub, чтобы каталог их увидел, написано в публикации модуля.

По ссылке

Кнопка По ссылке там же принимает прямой адрес zip-архива: релиз на GitHub, зеркало, любой сервер. Для закрытого репозитория токен можно передать разово, в панели он не сохраняется. Ссылки на localhost и адреса внутренних сетей отклоняются — сервер не станет ходить внутрь своей сети по указке из панели. Архив проверяется и ставится так же, как загруженный из файла.

Из архива

Утилиты → Модули (или Темы) → Установить из архива. Панель принимает zip, внутри которого лежит module.json или theme.json — в корне архива либо в единственной папке.

Расширение распаковывается в modules/<id> или themes/<id>. Идентификатор берётся из манифеста, а не из имени архива. Если вы копируете папку руками, имя ей можно дать любое: ядро читает module.json и берёт идентификатор оттуда. Две папки с одним идентификатором — единственный случай, когда вторая не загрузится, о чём будет сказано в логе.

Уже установленное под тем же идентификатором заменяется. Прежняя папка сохраняется до конца установки и возвращается на место, если что-то пошло не так.

Новый модуль ставится выключенным — сам он ничего не сделает, пока вы не включите его на странице «Модули». Обновление уже установленного модуля состояние не меняет: был включён — останется включённым.

Панель показывает, что осталось сделать: включить модуль, пересобрать фронты, перезапустить сервер. Список зависит от того, что есть у расширения.

Руками

То же самое без панели:

# 1. Скопировать папку расширения
cp -r screens /path/to/unicore/modules/

# 2. Если у расширения есть client/ или admin/
pnpm run build:client
pnpm run build:admin

# 3. Перезапустить сервер

Серверная часть модуля грузится при старте, поэтому перезапуск нужен всегда — заодно на нём создадутся таблицы расширения, если они у него есть. Фронтовые части — это слои Nuxt, они попадают в приложение только при сборке.

pnpm install ставить расширение не нужно

Папки modules/ и themes/ не входят в воркспейс pnpm — это сделано намеренно. Иначе каждое поставленное расширение становилось бы проектом воркспейса, и pnpm install на боевом сервере падал бы с ERR_PNPM_OUTDATED_LOCKFILE: лок-файл репозитория не знает про расширения, которые владелец поставил у себя. Пакеты расширение берёт у ядра из корневого node_modules, а package.json внутри архива нужен только для сборки исходников.

Выключение

Выключенный на странице «Модули» модуль пропадает с сайта и из панели сразу, стоит перезагрузить страницу: список включённых модулей фронты получают вместе с публичным конфигом и убирают всё, что модуль добавил, — пункты меню, вставки в чужие экраны, свои страницы (они начинают отдавать 404). Пересобирать фронты для этого не нужно.

Перезапуск сервера после выключения всё же нужен: серверная часть модуля уже поднята, и его HTTP-маршруты продолжают отвечать до рестарта. А пересборка нужна в обратную сторону — когда модуль включают, а его слоёв не было в последней сборке фронтов.

Что проверяется до распаковки

ПроверкаЧто отклоняется
Пути внутри архиваФайлы, выходящие за папку расширения (../)
Типы записейСимволические ссылки
МанифестБитый JSON, отсутствие обязательных полей, чужой идентификатор
Версия контрактаДиапазон unicoreApi, несовместимый с ядром
Ссылки манифестаПути на файлы, которых в архиве нет
РазмерСлишком большой архив или слишком много файлов внутри

Проверки не заменяют доверия к автору

Они защищают от испорченного и подделанного архива, но не от злого умысла: серверная часть модуля выполняется с правами процесса CMS. Ставьте только то, чему доверяете, — как плагин на игровой сервер.

Включение и выключение

Переключатель на странице «Модули». Выключенный модуль не загружается: его контроллеры, задачи и подписки на события не работают, таблицы и настройки остаются на месте. Чтобы изменение вступило в силу, сервер нужно перезапустить, а если у модуля есть фронтовая часть — пересобрать фронты.

Состояние хранится в modules/state.json, поэтому оно переживает перезапуск и обновление модуля. Тему включать не нужно: она начинает работать, когда вы выбираете её на странице «Темы».

Пересборка фронтов

Серверную часть модуля подхватывает перезапуск, а страницы и компоненты попадают на сайт только после сборки клиента и панели. Собирать руками не нужно: на странице «Модули» есть кнопка «Пересобрать» — она запускает сборку в фоне и показывает живой лог. Сайт всё это время работает на прежней сборке, новая подменяет её в конце.

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

Удаление

Удалять можно только выключённый модуль. Панель предупредит, что уйдёт вместе с ним:

  • таблицы mod_<id>_*;
  • настройки mod_<id>_* и public_mod_<id>_*;
  • строки локализации mod.<id>.*;
  • права mod.<id>.* — в том числе выданные ролям и игрокам;
  • сама папка расширения.

Тема удаляется со страницы «Темы» вместе с папкой и своими строками theme.<id>.*. Активную тему удалить нельзя — сначала выберите другую и пересоберите фронт.

Удаление данных необратимо

Резервной копии CMS не делает. Если данные модуля могут понадобиться, снимите дамп базы до удаления.

Содержание