Как опубликовать свой плагин?

Содержание
Плагины GameAP публикуются на plugins.gameap.dev — оттуда их устанавливают прямо из панели. Этот гайд проводит по всему пути: от создания карточки плагина до автоматической выкладки новых версий из CI.
Предполагается, что плагин у вас уже написан и собирается в .wasm. Ещё понадобится аккаунт
на plugins.gameap.dev: обычная регистрация с подтверждением почты либо вход через GitHub,
GitLab или Google.
Загружать версии можно двумя способами: вручную через дашборд и через API из CI. Начать проще с дашборда, а когда сборка встанет на рельсы — переключиться на CI.
Шаг 1. Аккаунт разработчика #
Публиковать плагины может аккаунт со статусом разработчика. Он выдаётся бесплатно и сразу — достаточно принять правила публикации.
В каталоге плагинов нажмите «Опубликовать свой плагин» — кнопка в правом верхнем углу.

Откроется страница с правилами публикации. Коротко, о чём вы договариваетесь:
- Рабочие и качественные плагины — только работоспособные и протестированные, делающие то, что заявлено в описании.
- Никакого вредоносного кода — без бэкдоров, скрытых майнеров и запутанной логики; сбор данных пользователей должен быть явно описан.
- Права и лицензирование — вы владеете кодом или вправе его распространять, чужие лицензии соблюдены, лицензия плагина указана.
- Совместимость с GameAP — плагин работает с актуальными версиями панели и соответствует требованиям к формату.
- Обновления и поддержка — критические ошибки и уязвимости чинятся в разумные сроки, на обращения пользователей есть ответ.
- Модерация — каждый плагин и каждая версия проходят проверку, нарушающий правила плагин может быть снят в любой момент.
- Без спама и дубликатов — без вводящих в заблуждение названий и накрутки ключевых слов.
Полный текст — на самой странице, прочитать стоит целиком.
Внизу нажмите «Принять». Роль выдаётся мгновенно, без модерации и ожидания: в сайдбаре появится раздел «Разработчик» с пунктами «Панель управления», «Мои плагины», «Новый плагин» и «Поддержка», а на почту придёт письмо о том, что вы стали разработчиком.
Важно. Принять правила можно только с подтверждённой почтой: иначе кнопка «Принять» неактивна, а на странице висит напоминание подтвердить email. При входе через GitHub, GitLab или Google почта считается подтверждённой сразу.
Кнопка «Опубликовать свой плагин» видна всем, включая не вошедших в аккаунт. Без входа на странице правил будет «Войти и принять» — после авторизации вас вернёт обратно к правилам.
Шаг 2. Создание плагина #
В меню слева выберите «Новый плагин» — откроется форма создания.

| Поле | Обязательное | Что указать |
|---|---|---|
| Название | да | До 255 символов |
| Краткое описание | да | Одна фраза для карточки в каталоге, до 500 символов |
| Описание | да | Полное описание в Markdown — над полем есть панель с разметкой |
| Категория | нет | Одна из трёх, см. ниже |
| Метки | нет | Ключевые слова, по которым плагин проще найти |
| Лицензия | нет | Произвольный текст: MIT, GPL-3.0, Proprietary |
| Исходный код | нет | Ссылка на исходники, если они открыты |
| Репозиторий | нет | Ссылка на репозиторий |
| Домашняя страница | нет | Сайт плагина или автора |
Категории:
- Управление сервером — большинство плагинов. Всё, что добавляет действия над игровым сервером.
- Файлы — расширения файлового менеджера: редакторы, просмотрщики отдельных форматов.
- Интеграция — плагины, существенно расширяющие функциональность панели, например управление базами данных.
Иконку на этом шаге загрузить нельзя — форма прямо об этом предупреждает, загрузка появится сразу после создания.
Важно. Поля «Исходный код» и «Репозиторий» влияют не только на карточку. Если не заполнено ни одно из них, к каждой версии придётся прикладывать архив с исходниками — модераторам нужно чем-то проверять сборку. Заполните хотя бы одно поле, если исходники открыты.
Шаг 3. ID плагина #
После нажатия «Создать» вы попадёте на страницу редактирования плагина. Первым блоком там идёт ID плагина — поле только для чтения с кнопкой копирования.
Этот ID нужно прописать в исходном коде плагина — в поле id структуры PluginInfo, которую
возвращает метод GetInfo. По нему панель сопоставляет установленный у пользователя плагин
с записью в маркетплейсе.
ID генерируется один раз при создании и не может быть изменён. Под капотом это 64-битное
число (8 случайных байт), записанное в base32 — 13 символов латиницы и цифр, например
fmqnme42gg7da. Тот же ID подставляется в URL страницы плагина и в адрес CI-эндпоинта.
Как это выглядит в существующих плагинах:
- plugin-mysql — константа
PLUGIN_ID(fmqnme42gg7da) - plugin-goldsrc-addons —
PLUGIN_ID(ezvdsxmlu6fbk) - plugin-minecraft-modrinth —
PLUGIN_ID(dshdabjp2l73a)
Важно. Пропишите ID и пересоберите
.wasmдо загрузки первой версии. Версии неизменяемы: перезалить файл под тем же номером не получится, придётся поднимать версию.
Шаг 4. Иконка и переводы #
На той же странице редактирования есть загрузчик иконки: JPG, PNG, WebP или SVG, до 2 МБ, рекомендуемый размер 128×128.
На странице плагина есть блок «Переводы». Каталог двуязычный, и посетитель видит карточку на своём языке: без перевода русский пользователь получит английское описание и наоборот. Название, краткое и полное описание переводятся отдельно для каждого языка — это пять минут работы, которые заметно меняют вид карточки.
Шаг 5. Загрузка версии #
На странице плагина найдите карточку «Версии» и нажмите «Загрузить версию».

| Поле | Обязательное | Что указать |
|---|---|---|
| Версия | да | Семантическая версия: 1.0.0, 1.2.0-beta.1 |
| Файл плагина | да | Скомпилированный .wasm, до 100 МБ |
| GPG подпись | нет | Открепленная подпись .sig или .asc, до 1 МБ |
| Архив исходного кода | зависит | .zip или .tar.gz, до 50 МБ |
| Список изменений | нет | Что изменилось по сравнению с прошлой версией, Markdown |
| Стабильный релиз | — | Переключатель, по умолчанию включён |
| Мин. версия GameAP | нет | Версия панели, начиная с которой плагин работает |
GPG подпись необязательна, но желательна: сервер хранит её как есть и никак не проверяет — она нужна пользователям, чтобы самостоятельно убедиться в подлинности файла.
Архив исходного кода обязателен, если у плагина не заполнены ни «Исходный код», ни «Репозиторий» — форма сама переключит подпись поля с «(необязательно)» на «(обязательно)». Архив используется только для модерации и проверки сборки, нигде не публикуется и недоступен через публичные эндпоинты.
Важно. Загруженная через дашборд версия остаётся черновиком. Пока вы не отправите её на проверку, её никто не увидит.
Скриншоты версии #
Сразу после загрузки откроется второй шаг — «Добавить скриншоты». Скриншоты привязаны к конкретной версии: JPG, PNG или WebP, до 10 штук, каждый до 5 МБ. Шаг можно пропустить и вернуться к нему позже со страницы версии.
Шаг 6. Отправка на проверку #
Плагины проходят модерацию — по тем самым правилам публикации, которые вы приняли на первом шаге. В шапке страницы плагина есть кнопка «Отправить на проверку» — она видна, только пока плагин в статусе «Черновик» или «Отклонён».
Отправить плагин без единой версии нельзя — сначала загрузите версию. Отправка версии на проверку из таблицы версий заодно переводит и сам плагин из черновика в статус «На проверке», так что отдельно нажимать кнопку в шапке обычно не требуется.
| Статус | Что значит | Что можно сделать |
|---|---|---|
| Черновик | Создан, никуда не отправлен | Редактировать, отправить на проверку, удалить |
| На проверке | Ждёт модератора | Ждать |
| Отклонён | Модератор вернул на доработку | Исправить и отправить снова |
| Опубликован | Доступен всем в каталоге | Загружать новые версии |
| Одобрен | Промежуточный статус в модели данных | — |
| Устарел | Помечен как неактуальный | Всё ещё устанавливается, но помечен |
| Отозван | Снят с публикации | Недоступен для установки |
Одобрение сразу переводит плагин и версию в «Опубликован». Публично видны только объекты в этом статусе: если плагин опубликован, а его единственная версия ещё на проверке, установить будет нечего.
Причина отклонения приходит на почту — на странице плагина отображается только статус, поэтому проверьте входящие.
Токены деплоя #
Чтобы публиковать версии из CI, нужен токен деплоя. Он живёт в самом низу страницы плагина, в карточке «Токены деплоя».

Нажмите «Создать токен» и заполните диалог: название (например, GitHub Actions)
и, при желании, срок действия.

Важно. Токен показывается ровно один раз, сразу после создания. На сервере не хранится в исходном виде, восстановить значение невозможно — скопируйте его сразу в секреты CI.
Что стоит знать про токены:
- Токен привязан к одному плагину и умеет только загружать его версии. Ни другие плагины, ни остальные эндпоинты API он не открывает.
- Формат —
gapd_и 43 символа, всего 48. Префикс легко ловится сканерами секретов. - В таблице видно префикс токена, дату создания, последнего использования и срок действия — удобно понять, какой токен ещё используется.
- Отзыв срабатывает мгновенно: пайплайн с отозванным токеном сломается на следующем запуске.
- На один плагин можно завести до 20 токенов.
Публикация из CI #
CI-эндпоинт принимает новую версию без интерактивного входа — авторизация идёт по токену деплоя.
Загрузка через curl #
curl --fail-with-body -sS \
-H "Authorization: Bearer $GAMEAP_DEPLOY_TOKEN" \
-F "version=1.2.3" \
-F "file=@build/plugin.wasm" \
-F "signature=@build/plugin.wasm.asc" \
-F "changelog=Исправлено падение при перезапуске сервера" \
-F "min_gameap_version=4.1.0" \
-F "is_stable=true" \
"https://plugins.gameap.dev/api/ci/plugins/$GAMEAP_PLUGIN_ID/versions"
Запрос — POST с multipart/form-data. Поля формы:
| Поле | Обязательное | Описание |
|---|---|---|
version | да | Семантическая версия, например 1.2.3 |
file | да | Скомпилированный .wasm, до 100 МБ |
signature | нет | Открепленная GPG-подпись, до 1 МБ |
source | зависит | Архив исходников .zip/.tar.gz до 50 МБ; обязателен, если у плагина не указаны ни «Исходный код», ни «Репозиторий» |
changelog | нет | Список изменений; удобно передавать из файла: -F "changelog=<CHANGELOG.md" |
min_gameap_version | нет | Минимальная версия GameAP |
min_plugin_api_version | нет | Минимальная версия Plugin API (в форме дашборда этого поля нет) |
is_stable | нет | true или 1 помечает версию стабильной |
submit | нет | По умолчанию true; false оставит версию черновиком |
Не ставьте слеш в конце URL. На .../versions/ роутер отвечает редиректом 301, а curl
не повторяет тело POST при редиректе — загрузка молча превратится в GET.
Успешный ответ — 201 с телом вида:
{
"id": 123,
"plugin_id": "fmqnme42gg7da",
"version": "1.2.3",
"file_size": 1048576,
"file_hash": "9f86d081884c7d65...",
"has_source": false,
"status": "pending_review"
}
GitHub Actions #
Этот workflow срабатывает на публикацию GitHub-релиза, собирает плагин, подписывает его и выкладывает на plugins.gameap.dev. Тело релиза уходит в список изменений, а стабильной версия помечается, только если релиз не отмечен как pre-release.
name: Publish plugin
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build plugin
run: make wasm # должен получиться build/plugin.wasm
- name: Sign plugin
env:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
run: |
printf '%s' "$GPG_SIGNING_KEY" | gpg --batch --import
gpg --batch --yes --detach-sign --armor \
-o build/plugin.wasm.asc build/plugin.wasm
- name: Publish to plugins.gameap.dev
env:
GAMEAP_DEPLOY_TOKEN: ${{ secrets.GAMEAP_DEPLOY_TOKEN }}
GAMEAP_PLUGIN_ID: ${{ vars.GAMEAP_PLUGIN_ID }}
TAG: ${{ github.event.release.tag_name }}
RELEASE_BODY: ${{ github.event.release.body }}
PRERELEASE: ${{ github.event.release.prerelease }}
run: |
VERSION="${TAG#v}"
printf '%s' "$RELEASE_BODY" > "$RUNNER_TEMP/changelog.md"
ARGS=(--fail-with-body -sS
-H "Authorization: Bearer ${GAMEAP_DEPLOY_TOKEN}"
-F "version=${VERSION}"
-F "file=@build/plugin.wasm"
-F "signature=@build/plugin.wasm.asc"
-F "changelog=<${RUNNER_TEMP}/changelog.md")
if [ "$PRERELEASE" != "true" ]; then
ARGS+=(-F "is_stable=true")
fi
curl "${ARGS[@]}" \
"https://plugins.gameap.dev/api/ci/plugins/${GAMEAP_PLUGIN_ID}/versions"
VERSION="${TAG#v}" срезает ведущую v, чтобы тег v1.2.3 публиковался как версия 1.2.3.
Боевой вариант этого workflow со сборкой фронтенда, кешем Cargo и проверкой HTTP-статуса — в plugin-mysql.
Настройка репозитория GitHub #
Токен и ID плагина не должны лежать в коде — они хранятся в настройках репозитория. Откройте Settings → Secrets and variables (в разделе Security and quality) → Actions.

На вкладке Secrets нажмите New repository secret и добавьте:
| Имя | Значение |
|---|---|
GAMEAP_DEPLOY_TOKEN | Токен деплоя, скопированный при создании (начинается с gapd_) |
GPG_SIGNING_KEY | Приватный GPG-ключ в ASCII-armor, если подписываете сборки |

На вкладке Variables нажмите New repository variable и добавьте:
| Имя | Значение |
|---|---|
GAMEAP_PLUGIN_ID | ID плагина, например fmqnme42gg7da |

ID плагина — это тот же base32-идентификатор, который вы прописывали в PluginInfo. Скопировать
его можно кнопкой рядом с полем «ID плагина» на странице редактирования или из блока «Детали»
на странице плагина.
ID лежит в переменных, а не в секретах, намеренно: он не секретный, а в логах CI его видно — это сильно упрощает разбор ошибок. Токен, наоборот, всегда секрет.
Экспортировать приватный GPG-ключ для GPG_SIGNING_KEY можно так:
gpg --armor --export-secret-keys ВАШ_КЛЮЧ_ID
Публичный ключ выложите там, где пользователи смогут его найти — например, в README плагина, чтобы подпись было чем проверить.
Дашборд и CI: разные умолчания #
| Что | Дашборд | CI |
|---|---|---|
| Стабильный релиз | Переключатель включён по умолчанию | is_stable по умолчанию false — передавайте явно |
| Отправка на проверку | Вручную, кнопкой | submit по умолчанию true — версия уходит на проверку сразу |
| Скриншоты | Предлагаются после загрузки | Не поддерживаются, добавляйте через дашборд |
Если из CI нужно только положить файл, а метаданные доделать руками — передайте submit=false,
и версия останется черновиком.
Ошибки #
| Код | Причина |
|---|---|
400 | Неверный ID плагина, битый multipart или не передан file |
401 | Токен отсутствует, неверен или истёк; заголовок не в формате Bearer gapd_... |
403 | Токен валиден, но выдан для другого плагина |
409 | Версия с таким номером уже существует |
422 | Версия не проходит проверку semver; архив исходников отсутствует, слишком большой или не .zip/.tar.gz; превышены лимиты размера файла или подписи |
Тело ошибки приходит в общем формате:
{
"status": "error",
"error": "version already exists",
"message": "version already exists",
"http_code": 409
}
После ошибки 5xx не повторяйте загрузку вслепую. Запись версии и отправка на проверку —
не одна транзакция: версия может быть уже создана, и повтор вернёт 409. Загляните в дашборд
и посмотрите, что получилось.
Обновление и снятие версий #
Новая версия загружается так же, как первая, — через дашборд или из CI. Уже загруженные версии
неизменяемы: перезалить файл под тем же номером нельзя, попытка вернёт 409. Ошиблись в сборке —
поднимайте патч-версию.
В таблице версий у каждой строки есть свои действия:
- Редактировать — правка списка изменений и метаданных.
- Отправить на проверку — для черновиков и отклонённых версий.
- Устарел — для опубликованных версий. Версия остаётся доступной, но помечается как неактуальная.
- Отозвать — для опубликованных и устаревших. Версия снимается с публикации.
Удалить можно только плагин в статусе «Черновик». Опубликованный плагин удалению не подлежит — его можно отозвать.
Чек-лист #
- Почта подтверждена, правила публикации приняты, аккаунт получил статус разработчика.
- Плагин создан, название и оба описания заполнены.
- Заполнены «Исходный код» или «Репозиторий» — иначе к каждой версии нужен архив исходников.
- ID плагина прописан в
PluginInfo.id, и.wasmпересобран после этого. - Загружена иконка, добавлены переводы карточки.
- Версия загружена, приложены подпись и скриншоты.
- Версия отправлена на проверку — не оставлена черновиком.
- Для CI создан токен деплоя и сохранён в секретах, ID плагина — в переменных.
- В workflow нет слеша в конце URL и явно передан
is_stable. - После релиза проверено, что плагин и версия в статусе «Опубликован».