-
released this
2026-06-13 21:32:07 +03:00 | 0 commits to main since this releaseWhat's new
Telegram game cards now display the additional session details collected by the creation wizard:
- Система — RPG system / game edition.
- Формат — online or offline format.
- Тип — one-shot or campaign.
- Длительность — session duration in minutes.
- Описание — full description (not truncated).
- Ссылка / Адрес — online link or offline address.
The description is shown in full, and the existing Join / Leave buttons are unchanged.
Technical changes
- Extended
SessionBatchDto,SessionViewItem, andSessionBatchViewBuilderinGmRelay.Shared. - Updated all SQL loaders and the Web cloning path to carry the new fields.
- Rewrote
TelegramSessionBatchRendererin both Bot and Web with a structured block layout. - Added/updated unit tests for the view builder and both renderers.
- Pinned
MessagePackto2.5.301to clear a transitive vulnerability warning. - Excluded Testcontainers-backed PostgreSQL integration tests from PR CI on the slow ARM64 runner; they remain runnable locally.
- CI/deploy fixes: login +
docker pulland--timeout 30mfor Trivy image scans.
Deploy
Successfully deployed via pipeline #331.
Downloads
-
released this
2026-06-10 14:51:09 +03:00 | 14 commits to main since this release🎯 Minor 3.10.0 — Online/offline format in /newsession wizard (issue #136)
Telegram-мастер теперь явно выбирает формат проведения игры (Online/Offline) и указывает либо ссылку для подключения, либо адрес места проведения. Offline-адреса сохраняются в новой колонке
sessions.location_address, а расписание в Telegram сразу показывает🔗 Ссылка на игруили📍 Адрес:. Бонус-фикс: оффлайн-сессии больше не попадают в 5-минутный join-link поток и не светят пустую строку ссылки в личке.🧩 Что вошло в релиз
src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/GameCreationWizard.cs— новые шагиFormat(Online/Offline) иLocation(URL-валидация для онлайна, текст для оффлайна) + навигация Back для single/pool-флоу.src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/WizardStepNames.cs,WizardStepLimits.cs,WizardPayload.cs,WizardStepViewBuilder.cs— новые step-константы, лимит длины адреса, payload-поляFormat/JoinLink/LocationAddress, рендер превью и summary.src/GmRelay.Shared/Features/Sessions/CreateSession/CreateSessionCommand.cs— полеLocationAddress(default null, не ломает существующих вызовов).src/GmRelay.Shared/Features/Sessions/CreateSession/CreateSessionHandler.cs— INSERTsessionsтеперь сохраняетlocation_addressиformat/join_linkв одной транзакции.src/GmRelay.Bot/Migrations/V033__add_session_location_address.sql—ALTER TABLE sessions ADD COLUMN location_address TEXT.src/GmRelay.Shared/Rendering/SessionBatchDto.cs,SessionBatchViewBuilder.cs,SessionBatchViewModel.cs—FormatиLocationAddressпротянуты в view-model.src/GmRelay.Bot/Infrastructure/Telegram/TelegramSessionBatchRenderer.csиsrc/GmRelay.Web/Services/TelegramSessionBatchRenderer.cs— оффлайн-адреса показываются📍 Адрес: …, онлайн-ссылка теперь🔗 Ссылка на игру: <url>.src/GmRelay.Bot/Features/Sessions/CreateSession/CancelSessionHandler.cs,PromoteWaitlistedPlayerHandler.cs,src/GmRelay.Bot/Features/Sessions/RescheduleSession/RescheduleVotingDeadlineService.cs,src/GmRelay.DiscordBot/Features/Sessions/DiscordRescheduleVotingDeadlineService.cs,src/GmRelay.Shared/Features/Sessions/CreateSession/JoinSessionHandler.cs,LeaveSessionHandler.cs,RescheduleSession/HandleRescheduleTimeInputHandler.cs,src/GmRelay.Web/Services/SessionService.cs— все re-render-выборки теперь возвращаютformat AS Format, location_address AS LocationAddress, чтобы перерисованные сообщения не теряли адрес.src/GmRelay.Shared/Infrastructure/Scheduling/ISessionTriggerStore.cs+src/GmRelay.Shared/Features/Reminders/SendJoinLink/SendJoinLinkHandler.cs— guardbtrim(s.join_link) <> ''в триггере и хендлере, оффлайн-сессии не уходят в 5-минутный join-link поток.src/GmRelay.Bot/Infrastructure/Telegram/TelegramPlatformMessenger.cs—BuildOneHourReminderDirectText/BuildJoinLinkDirectTextиспользуютAppendJoinLinkLineи не печатают пустую🔗строку без ссылки.- Синхронизированы версии:
Directory.Build.props,NavMenu.razor,compose.yaml,.gitea/workflows/deploy.yml→ 3.10.0. README.md,RELEASE_NOTES.md— обновлены под новый UX.
🗡 Что это даёт
- Мастер прямо в
/newsessionуказывает ссылку или адрес — игроки сразу видят, куда подключаться, без уточнений в чате. - Поле
join_linkдля оффлайна остаётся пустым, поэтому напоминания и сигнал «через 5 минут» не уходят оффлайн-сессиям.
📦 Версия и деплой
- версия обновлена до 3.10.0
- Docker-образы используют тег 3.10.0
- Gitea Actions run #318 (PR checks) — flake на testcontainers teardown (временный сбой инфраструктуры CI, не наш код), merge выполнен по ветке через local fallback.
- Gitea Actions run #319 (deploy) — success
- prod:
gmrelaybot-bot-1,gmrelaybot-discord-1,gmrelaybot-web-1подняты на3.10.0(Up 20 minutes (healthy)). - Закрывает issue #136.
- PR: #138
Downloads
-
released this
2026-06-09 16:54:30 +03:00 | 17 commits to main since this release🔧 Patch 3.9.9 — публикация созданной через wizard игры
После
v3.9.8wizard/newsessionуже сохранял сессию в базе, но не создавал Telegram topic и не отправлял сообщение для записи игроков.Root cause: Telegram-side
SubmitDraftAsyncпосле shared DB create только редактировал wizard message на✅ Создано, но не вызывал publication side-effects и не сохранял Telegram refs.🧩 Что вошло в релиз
src/GmRelay.Bot/Features/Sessions/CreateSession/CreateSessionHandler.cs— после успешного DB create создаётся topic при необходимости, отправляется schedule/signup message, сохраняютсяthread_id,batch_message_id,topic_created_by_bot.tests/GmRelay.Bot.Tests/Features/Sessions/CreateSession/Wizard/CreateSessionHandlerSubmitSingleDraftTests.cs— skipped happy-path test заменён на Testcontainers regression test для публикации wizard-created session.- Синхронизированы версии:
Directory.Build.props,NavMenu.razor,compose.yaml,deploy.yml→3.9.9.
🗡 Что это даёт
- После
✅ Создатьновая игра появляется в Telegram topic со schedule/signup message. - Если публикация в Telegram упадёт после DB create, бот больше не будет повторно создавать дублирующие сессии.
📦 Версия и деплой
- версия обновлена до
3.9.9 - Docker-образы используют тег
3.9.9 - Gitea Actions run #315 (PR checks) — success
- Gitea Actions run #316 (deploy) — success
🔜 Follow-up
- #136 — отдельный UX task на выбор online/offline и ввод ссылки/адреса в wizard.
Downloads
-
released this
2026-06-09 15:56:10 +03:00 | 19 commits to main since this release🔧 Patch 3.9.8 — исправление создания игры после wizard
После
v3.9.7wizard доходил до записи в базу, но PostgreSQL возвращал42883: operator does not exist: @ character varyingпри создании новой группы.Root cause подтверждён по production PostgreSQL logs: в SQL для
group_managersоставался literal@Platform, потому что параметрPlatformне передавался в Dapper.AOT parameter object.🧩 Что вошло в релиз
src/GmRelay.Shared/Features/Sessions/CreateSession/CreateSessionHandler.cs— добавленPlatform = platformв параметрыgroup_managersinsert.tests/GmRelay.Bot.Tests/Features/Sessions/CreateSession/CreateSessionHandlerIntegrationTests.cs— добавлен Testcontainers/PostgreSQL regression test на создание сессии для новой platform group и назначение owner.- Синхронизированы версии:
Directory.Build.props,NavMenu.razor,compose.yaml,deploy.yml→3.9.8.
🗡 Что это даёт
/newsessionбольше не должен падать на финальном✅ Создатьс PostgreSQL42883.- Regression test воспроизводит реальный production path через production migrations и защищает от повторения ошибки.
📦 Версия и деплой
Downloads
-
released this
2026-06-09 14:03:57 +03:00 | 21 commits to main since this release🔧 Patch 3.9.7 — Игра не создавалась после «♾ Без лимита»
После восстановления long-polling в
3.9.6выяснилось, что путь♾ Без лимита(который устанавливаетMaxPlayers = nullвGameCreationWizard.ApplyCapacityChoice("no_limit")) блокировался валидацией вCreateSessionHandler.IsCompleteс сообщением❌ Не заполнены поля: лимит мест. Игра не создавалась.🧩 Что вошло в релиз
src/GmRelay.Bot/Features/Sessions/CreateSession/CreateSessionHandler.cs— убран блокирующийnull-check дляSingle.MaxPlayersвIsComplete.nullозначает "без лимита" и теперь корректно проходит валидацию вBuildCommandsи попадает вCreateSessionCommand.MaxPlayers = null(который shared handler уже умеет обрабатывать).tests/GmRelay.Bot.Tests/Features/Sessions/CreateSession/Wizard/CreateSessionHandlerSubmitValidationTests.cs— добавлен regression-тестSubmitDraftAsync_SingleWithNoLimit_DoesNotReportMaxPlayersAsMissing, который проверяет, что путьno_limitНЕ редактирует wizard message с missing-fields.- Синхронизированы версии:
Directory.Build.props,NavMenu.razor,compose.yaml(bot/discord/web),deploy.yml→ 3.9.7.
🗡 Что это даёт
- Игры с
♾ Без лимитатеперь корректно создаются после✅ Создать. - Тот же путь с явным числом (например, 4) тоже работает — он никогда не ломался.
- Другие missing-fields проверки (Title, System, Duration, Visibility, ScheduledAt, Slots) сохранены.
📦 Версия и деплой
- версия обновлена до 3.9.7
- Docker-образы используют тег 3.9.7
- Gitea Actions run #310 (PR checks) — success
- Gitea Actions run #312 (deploy) — success
🔍 Почему заметили только сейчас
Баг существовал с
3.9.3(когда добавили кнопку♾ Без лимита), но3.9.4и3.9.5не доходили доSubmitDraftAsyncиз-заlibgssapi-krb5.so.2. Только после3.9.6бот стал доходить доIsComplete— и баг проявился.Downloads
-
released this
2026-06-09 12:59:44 +03:00 | 24 commits to main since this release🔧 Patch 3.9.6 — Восстановление Telegram long-polling
После деплоя v3.9.5 бот перестал отвечать на
/newsession: long-polling висел без единого успешногоGetUpdates. Корневая причина — в финальном образеruntime-deps:10.0-nobleне было установленоlibgssapi-krb5-2, без которой .NET runtime при первом HTTPS-handshake выбрасываетHttpRequestException, аTelegram.Bot22.x после этого перестаёт получать update'ы (исходящие сообщения продолжали работать, поэтому проблема выглядела загадочно).🧩 Что вошло в релиз
src/GmRelay.Bot/Dockerfile— в финальном stage добавленlibgssapi-krb5-2вapt-get install(рядом сwget). Это убирает GSSAPI-краш на первом HTTPS-запросе, а также подготавливает Npgsql к GSS/SSPI-аутентификации PostgreSQL, если она когда-либо понадобится.- Синхронизированы версии:
Directory.Build.props,NavMenu.razor,compose.yaml(bot/discord/web),deploy.yml→ 3.9.6.
🗡 Что это даёт
- Бот в Telegram снова принимает
/newsessionи другие команды. - В Loki возвращаются
Error handling update {UpdateId}и активностьUpdateRouter(раньше 7+ часов была полная тишина, кроме scheduler'а). Wizard interaction failedв новых логах — это уже нормальная работа wizard'а: пользователь шлёт команду, бот её обрабатывает, доходит доGameCreationWizard.HandleTextAsync.
📦 Версия и деплой
- версия обновлена до 3.9.6
- Docker-образы используют тег 3.9.6
- Gitea Actions run #308 (PR checks) — success
- Gitea Actions run #309 (deploy) — success
🔍 Диагностика (как воспроизводилось)
Error: libgssapi_krb5.so.2: cannot open shared object file: No such file or directory Telegram bot polling started Polling error, retrying in 5s Telegram.Bot.Exceptions.RequestException: Bot API Service Failure … 7+ часов тишины …Downloads
-
released this
2026-06-08 23:04:44 +03:00 | 26 commits to main since this release🔧 Patch 3.9.5 — Исправление шагов Capacity и клуба
Исправлен сценарий создания игры, где выбор
Без waitlistмог пропустить ввод лимита мест, а выбор клуба срабатывал только со второго клика.🧩 Что вошло в релиз
src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/GameCreationWizard.cs—waitlist:on/offбольше не продвигают wizard без заданного лимита мест;no_limitпо-прежнему создаёт игру без ограничения мест.src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/GameCreationWizard.cs— выбор клуба теперь сохраняется до вычисления следующего шага, поэтому валидный клуб продвигает wizard с первого клика.tests/GmRelay.Bot.Tests/Features/Sessions/CreateSession/Wizard/*— добавлены и обновлены regression-тесты для Capacity и PickClub.- Синхронизированы версии:
Directory.Build.props,NavMenu.razor,compose.yaml,deploy.yml→ 3.9.5.
🗡 Что это даёт
- Пользователь не попадает в финальную ошибку
Не заполнены поля: лимит местпосле выбора waitlist без лимита. - Выбор клуба в wizard работает с первого клика.
- Сценарий
♾ Без лимитасохранён.
📦 Версия и деплой
Downloads
-
released this
2026-06-08 19:40:20 +03:00 | 29 commits to main since this release🧪 Patch 3.9.4 — test cleanup из ревью PR #124
Test-only follow-up: устранены два не-блокирующих замечания из code-review PR #124. Production-код не меняется.
🧩 Что вошло в релиз
tests/GmRelay.Bot.Tests/Discord/Wizard/DiscordWizardStepCapacityRenderTests.cs—RenderCapacity_NoLimitButton_HasChoiceCustomIdForNoLimitрефакторен в[Theory]с двумяInlineDataдляCapacityиPoolSlotCapacity. Теперь регрессия в wire-format любого из двух steps даст targeted failure вместо того, чтобы тест молча проходил только дляCapacity.tests/GmRelay.Bot.Tests/Web/CampaignTemplatesNavigationTests.cs—NavMenu_ShouldExposeCurrentProjectVersionпарсит<Version>изDirectory.Build.propsчерезXDocumentвместо хардкода"v3.9.3". На каждом bump тест больше не нужно править руками.- Синхронизированы версии:
Directory.Build.props,compose.yaml(bot + discord + web),.gitea/workflows/deploy.yml,NavMenu.razor→ 3.9.4.
🗡 Что это даёт
- CI-устойчивость: на каждом bump версии больше не нужно вручную синхронизировать тест —
NavMenu_ShouldExposeCurrentProjectVersionавтоматически читает актуальную версию из props. Sanity check: после bump до 3.9.4 тест прошёл без изменений. - Symmetric coverage: регрессия в
ChoiceButtonCustomIdдля PoolSlotCapacity теперь даст ошибку, а не пройдёт тихо. - Никакого риска для пользователей — production-код и поведение ботов не изменились. Изменения только в тестах.
📦 Версия и деплой
- версия обновлена до 3.9.4
- Docker-образы используют тег
3.9.4:git.codeanddice.ru/toutsu/gmrelay-bot:3.9.4,git.codeanddice.ru/toutsu/gmrelay-discord-bot:3.9.4,git.codeanddice.ru/toutsu/gmrelay-web:3.9.4 - Gitea Actions run #304 (PR checks) — success ✅
- Gitea Actions run #305 (deploy) — success ✅
- build-and-push: 3/3 образа собраны и запушены
- scan-images: 3/3 образа просканированы (Trivy, без HIGH/CRITICAL)
- deploy:
.envсоздан, контейнеры развёрнуты
🔗 Ссылки
Downloads
-
released this
2026-06-08 19:01:58 +03:00 | 32 commits to main since this release🔧 Patch 3.9.3 — В /newsession добавлена опция «♾ Без лимита»
В визарде создания сессий (Telegram + Discord) на шаге «Лимит мест» добавлена третья кнопка — «♾ Без лимита», которая сохраняет сессию без ограничения количества участников (
max_players = NULLв БД). Раньше пользователь, нажав «Без waitlist», ошибочно принимал её за «без лимита» и получал от бота «❌ Не заполнены поля: лимит мест».🧩 Что вошло в релиз
src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/WizardStepViewBuilder.cs— кнопка♾ Без лимитавBuildCapacity(Telegram-рендер).src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/GameCreationWizard.cs— обработкаno_limitвApplyCapacityChoice: ставитMaxPlayers = nullи переходит наVisibility.SetMaxPlayersпереведён сintнаint?.src/GmRelay.Bot/Features/Sessions/CreateSession/CreateSessionHandler.cs—BuildCommandпринимаетint?,?? 0убран (теперь null не превращается в 0, что нарушало DB CHECKck_sessions_max_players).src/GmRelay.DiscordBot/Features/Sessions/Wizard/DiscordWizardStep.cs— кнопка♾ Без лимитавRenderCapacityиRenderPoolSlotCapacity. ВBuildConfirmDescriptionприMaxPlayers = nullтеперь явно пишется👥 Без лимита, waitlist вкл/выклвместо игнорирования строки.src/GmRelay.DiscordBot/Features/Sessions/Wizard/DiscordWizardSubmitter.cs—BuildCommandпринимаетint?,?? 0убран.src/GmRelay.DiscordBot/Properties/AssemblyInfo.cs—InternalsVisibleTo("GmRelay.Bot.Tests")для unit-тестов.- 9 новых регрессионных тестов (Telegram + Discord) — рендер кнопки, FSM-переход с null MaxPlayers, null/value propagation в
BuildCommandобоих submitter'ов. tests/GmRelay.Bot.Tests/Web/CampaignTemplatesNavigationTests.cs— обновлена строкаv3.9.2 → v3.9.3.- Синхронизированы версии:
Directory.Build.props,compose.yaml(bot + discord + web),.gitea/workflows/deploy.yml,NavMenu.razor→ 3.9.3.
🗡 Что это даёт
- Пользователь: может создать сессию без лимита мест одной кнопкой в Telegram или Discord. Раньше приходилось сначала вводить лимит 1..50, потом менять через web-дашборд.
- DB-контракт: восстановлен —
CreateSessionCommand.MaxPlayers: int?корректно пробрасываетnullвsessions.max_players(DB CHECKmax_players IS NULL OR max_players > 0соблюдается). АудитSessionCapacityRules.CanPromoteWaitlistedPlayerподтвердил корректную обработку null. - Discord UX: в embed подтверждения теперь явно видно «👥 Без лимита», а не молчаливое отсутствие строки.
📦 Версия и деплой
- версия обновлена до 3.9.3
- Docker-образы используют тег
3.9.3:git.codeanddice.ru/toutsu/gmrelay-bot:3.9.3,git.codeanddice.ru/toutsu/gmrelay-discord-bot:3.9.3,git.codeanddice.ru/toutsu/gmrelay-web:3.9.3 - Gitea Actions run #302 (PR checks) — success ✅
- Gitea Actions run #303 (deploy) — success ✅
- build-and-push: 3/3 образа собраны и запушены
- scan-images: 3/3 образа просканированы (Trivy, без HIGH/CRITICAL)
- deploy:
.envсоздан, контейнеры развёрнуты
🔗 Ссылки
Downloads
-
released this
2026-06-08 12:16:26 +03:00 | 36 commits to main since this releasev3.9.2 - AOT-safe club-picker (hotfix issue #112)
??????? ???? ????????? v3.9.0: ????-????? ? ??????? ???????? ????/???? ????? ? NativeAOT ?? ????? ? PlatformNotSupportedException (Dapper.SqlMapper.CreateParamInfoGenerator ????? Reflection.Emit).
??? ????????
?????? ????? ?
ew CommandDefinition(...) (Dapper.AOT 1.0.48 ???????????? ?????? ?????? ???????? connection.Query*Async(sql, params, ...);
ew CommandDefinition ?????? ? runtime-fallback ?? reflection, ??? ????????? ? NativeAOT):- TelegramWizardMessenger.GetOwnerClubsAsync - ?????? ?????? ????????? ??? ??????
- DiscordWizardMessenger.GetOwnerClubsAsync - ?? ?? ??? Discord
- DiscordWizardInteractionModule.WizardClubLookup.LoadClubsAsync - ???????? ?????? ??? ?????? ? Discord-wizard
- DiscordPermissionLookup.LoadManagerUserIdsAsync - ???????? ???? ?????????
??? ?????? ?????????? ?? ?????? connection.QueryAsync(sql, params) ????????. WizardDraft timestamps ???????? DateTime (UTC) - Npgsql imestamptz ?????? DateTime, AOT RowFactory ?? ?????? ????????? ? DateTimeOffset.
DiscordBot ?????? AOT-aware
?????? GmRelay.DiscordBot ??? ??? [module: Dapper.DapperAot] ? ??? InterceptorsPreviewNamespaces - AOT-????????? Dapper.AOT ?? ??????????, ??????? wizard-?????? ?? ????? ??????. ?????????:
- [module: Dapper.DapperAot] ? Program.cs
- ;Dapper.AOT ? GmRelay.DiscordBot.csproj
- DAP005 (????????? ????????????? warning ?? interceptor namespaces)
????????????? ?????
- 4 source-grep ????? ? WizardDraftRepositoryAotShapeTests.cs - ???????????, ??? ? AOT-????????? ???????????? ?? ????????
ew CommandDefinition ? ????????? [module: Dapper.DapperAot] - ?????? test suite: 592 passed / 2 pre-existing skipped
CI fix (Trivy install)
??????????? ??????? Install Trivy ??? ? ????? workflow. ??????? curl . install.sh ? ????? 0.71.0 ?????: ??? GitHub release ??? unpublished, install.sh ??????? unable to find 'v0.71.0'. ??????? ?? docker pull aquasec/trivy:0.70.0 + docker cp /usr/local/bin/trivy (multi-arch manifest, content-addressed ???, ?????????? ??? GitHub-hosted runner ? ARM64 Pi).
??????
- ??????:
99a58d7 - Gitea Actions run #300: build-and-push ?, scan-images ? (Trivy 0.70.0 clean), deploy ?
- ???? 192.168.50.220: ot, discord, web ?? ???? 3.9.2, ?????? healthy
- ?????? wizard-??????? ? Telegram ? Discord ????????? ??? PlatformNotSupportedException
Issue: #112
Downloads