Files
vidconf/CHANGELOG.md
Max Ronzhin f39c21e7e1
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
release: версия 0.0.17
2026-08-01 23:20:31 +03:00

459 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Изменения
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/),
проект придерживается [семантического версионирования](https://semver.org/lang/ru/).
## [0.0.17] — 2026-08-01
Массовый вход в систему и в конференцию перестаёт упираться в проверку пароля.
### Исправлено
- Проверка пароля больше не останавливает весь backend. Хэширование argon2 —
это десятки миллисекунд счёта, и выполнялось оно синхронно внутри
асинхронного обработчика: пока считался один пароль, процесс не обслуживал
ничего другого. На нагрузочном тесте 31.07 с примерно семью десятками
одновременных входов это дало p95 логина 7.28 секунды, p95 входа в
конференцию 7.06 секунды и 33 соединения к базе, висящих в открытой
транзакции при одном активном запросе. Страдали и посторонние запросы —
вход в конференцию отказывал, хотя пароль там не проверялся вовсе.
Теперь хэширование считается в пуле потоков.
- Параметры argon2id приведены к рекомендации OWASP (t=2, m=19 МБ, p=1)
вместо дефолтов библиотеки (t=3, m=64 МБ, p=4): 95 мс против 42 мс на
проверку. Прежнее значение `parallelism=4` вдобавок занимало все четыре
ядра сервера — те же, на которых работает медиа-сервер.
- Пароли, сохранённые со старыми параметрами, продолжают работать и
перевыпускаются автоматически при первом успешном входе.
## [0.0.16] — 2026-08-01
Роль организатора в комнате: поднятие руки с очередью и принудительный мьют.
### Добавлено
- Роль организатора прокинута в комнату — метаданные LiveKit-токена несут
подсказку `is_organizer` для UI (владелец конференции/администратор);
любое серверное действие организатора перепроверяется по владельцу
конференции в БД, метаданным токена для авторизации не доверяем.
- Поднятие руки: кнопка «Рука» в тулбаре (у всех участников, с общим
счётчиком), бейдж на плитке говорящего, видимый всем, и панель «Очередь»
для организатора — участники в порядке поднятия руки, с возможностью
опустить любую руку. Состояние — в Redis (не в БД): очередь существует
ровно во время звонка. Участник, вышедший из конференции, автоматически
исчезает из очереди; переподключение место не теряет.
- Принудительный мьют: организатор может выключить микрофон или камеру
любого участника — кнопки на его плитке. Участник получает уведомление,
что его выключил организатор, и может включить себя обратно сразу тем же
тулбаром.
- Эмодзи скачущего коня 🐎 в наборе смайликов чата.
### Изменено
- Транспорт чата (`WS /conferences/{id}/chat`) расширен: очередь поднятых
рук и уведомления о мьюте едут по тому же аутентифицированному
соединению, что и сообщения чата — без нового эндпоинта.
Миграций БД нет — новое состояние (очередь поднятых рук) хранится в Redis,
не в Postgres.
## [0.0.15] — 2026-07-30
Шесть доработок UI комнаты конференции.
### Добавлено
- Выбор эмодзи в чате — поповер с небольшим собственным набором популярных
эмодзи (без библиотеки-пикера), вставка в позицию курсора.
- Кнопка микрофона в мини-окне (Document PiP) — раньше в PiP не было
никакого способа замьютить себя, не разворачивая основное окно.
- Закрепление участника доступно из любого режима показа («Стандарт»,
«Плитки», «Живые плитки») — раньше булавка рендерилась только в
«Стандарте». Само закрепление автоматически переключает вид на «Стандарт»
(закреплённого иначе негде показать крупно); открепление вид назад не
меняет.
### Изменено
- Участник заходит в конференцию с выключенными микрофоном и камерой,
включает их сам уже в комнате.
- В топбаре комнаты вместо технического `room_name` LiveKit (вида
`hC-Dmos9KEM`) показывается название конференции; при его отсутствии —
«Конференция без названия». Номер и ссылка-приглашение не задеты.
## [0.0.14] — 2026-07-28
TURN-фолбэк для участников из сетей с жёстким NAT.
### Исправлено
- LiveKit теперь анонсирует клиентам внешний TURN-сервер (`rtc.turn_servers`
в конфигурации, UDP и TCP на 3478). Раньше coturn поднимался и был healthy,
но клиенты о нём не знали: внешний TURN в конфиге объявлен не был, встроенный
выключен, а фронтенд `iceServers` не задаёт. За всё время работы в логах
coturn не было ни одной аллокации — то есть relay не использовался никогда,
и участники из сетей, где прямое UDP-соединение не проходит, теряли связь
(`PEER_CONNECTION_DISCONNECTED`). На нагрузочном тесте 28.07 все такие
разрывы пришлись на внешних участников и ни одного — на офисных.
- Credentials TURN генерируются по механизму TURN REST API из общего
`TURN_STATIC_AUTH_SECRET`, то есть тот же секрет, что и у coturn.
### Изменено
- `deploy/render-templates.sh` подставляет `TURN_EXTERNAL_IP` и
`TURN_STATIC_AUTH_SECRET` также в конфигурацию LiveKit.
- Раздел 8 руководства по развёртыванию переписан: TURN больше не «план на
будущее», а рабочая конфигурация. Отдельно описано правило ufw для
relay-диапазона `49160:49200/udp` — без него TURN отвечает на запросы, но
релей не работает, причём в логах coturn при этом тишина.
TURN over TLS (5349/443) по-прежнему не настроен: требует монтирования
сертификата в coturn. Неработающий `turns:` намеренно не анонсируется, иначе
клиент ждал бы таймаута перед переходом к рабочему кандидату.
## [0.0.13] — 2026-07-28
Снижение нагрузки на сеть: клиент перестаёт получать полное качество всех
чужих камер независимо от того, какого размера плитка на экране.
### Изменено
- Включены `adaptiveStream` и `dynacast` в опциях комнаты. Оба флага в LiveKit
выключены по умолчанию, из-за чего каждый участник был подписан на полное
качество всех чужих треков, а каждый паблишер слал все слои симулкаста, даже
когда их никто не смотрит. Теперь качество подписки выбирается по фактическому
размеру плитки, а неотрисованные треки уходят в паузу. На локальном стенде
(9 участников, паблишеры 720p) входящий поток одного клиента упал с
11 110 до 778 кбит/с.
Вместе с этим начинает экономить уже написанный код, который до сих пор не
давал выигрыша: «скрыть остальных» не рендерит карусель (исходящий трафик
LiveKit 0.76 → 0.03 Мбит/с), пагинация сетки участников рендерит только
текущую страницу, а пауза чужого видео в свёрнутой вкладке работает лишь
при включённом `adaptiveStream`.
- Контейнеры больше не пересобирают окружение Python при запуске: во все
вызовы `uv run` в прод-путях (CMD образа, `command`/`entrypoint`/`healthcheck`
сервисов, миграции и seed в `install.sh`) добавлен `--no-sync`. Раньше
окружение, собранное на этапе build с `--no-dev`, при каждом старте
синхронизировалось заново и подтягивало dev-группу: ~26 МБ загрузок,
замедленный старт и ruff/mypy/pytest в рантайме. Healthcheck'и делали то же
самое каждые 15 секунд всю жизнь контейнера. Размер `/app/.venv` после
запуска: 574 → 456 МБ. Локальная разработка не затронута — там dev-группа
нужна и ставится как раньше.
## [0.0.12] — 2026-07-28
Разблокировка backend под нагрузкой: вход в конференцию перестаёт отваливаться,
когда участники включают микрофоны.
### Исправлено
- Обработчик webhook `track_published` больше не запускает Track Egress внутри
своей транзакции. Раньше каждый опубликованный микрофон уходил в сетевой
вызов, а на инстансе без профиля `transcribe` (egress-сервиса в деплое нет)
этот вызов висел 2025 секунд, всё это время удерживая соединение с БД. На
нагрузочном тесте с 19 участниками пул соединений выгребался за секунды, и
вход в конференцию начинал отвечать 500. Теперь запуск уходит в фоновую
задачу со своей сессией, а webhook отвечает сразу — LiveKit перестаёт копить
очередь доставки и терять события.
- Track Egress не запускается вовсе, если транскрибация выключена в настройках
инстанса — тот же guard, что уже был в обработчике `room_finished`.
- Запуск Track Egress ограничен таймаутом (по умолчанию 3 секунды) вместо
ожидания собственного таймаута LiveKit.
### Изменено
- Пул соединений с БД задаётся явно (`DB_POOL_SIZE`, `DB_MAX_OVERFLOW`,
`DB_POOL_TIMEOUT`) вместо дефолта SQLAlchemy 5 + 10. Считайте бюджет на весь
инстанс: каждый воркер держит свой пул, и сумма должна оставаться заметно
ниже `max_connections` у Postgres.
- Backend запускается с несколькими процессами uvicorn (`UVICORN_WORKERS`,
по умолчанию 2). Одиночный процесс означал, что любой блокирующий вызов
останавливает и параллельные запросы, и WS-чат всех участников. Дефолт 2, а
не по числу ядер: на четырёхъядерном сервере ядра делятся с LiveKit.
## [0.0.11] — 2026-07-28
Выбор режима показа участников в конференции, скрытие остальных и круглая
иконка участника при выключенной камере.
### Добавлено
- Выбор режима показа участников на сцене вместо автоматической раскладки:
«Стандарт» (крупная плитка плюс карусель остальных сбоку, как было),
«Плитки» (все участники равными плитками) и «Живые плитки» (плитками —
только те, у кого включена камера, остальные в карусели). Кто именно
показан крупно в «Стандарте», по-прежнему решает прежняя логика фокуса
(новая демонстрация → закреплённый → говорящий с видео → говорящий).
Выбор сохраняется между заходами в комнату.
- Скрытие остальных участников — на сцене остаётся только основная плитка.
Скрыть можно из меню «Вид», из шторки настроек на мобильном и кнопкой над
колонкой миниатюр; вернуть — кнопкой «Показать остальных (N)», которая
видна всё время, пока кто-то скрыт. В режиме «Плитки» скрывать нечего,
переключатель там заблокирован.
- Переключатель вида: кнопка «Вид» с поповером в тулбаре на широком экране;
на мобильном — секция «Вид» в шторке настроек, чтобы не добавлять шестую
кнопку в уже ужатый тулбар.
### Изменено
- Демонстрация экрана временно перебивает выбранный режим: пока идёт шэр,
сцена ведёт себя как «Стандарт», а по его завершении возвращается к
выбранному виду.
- Равномерная сетка плиток стала пригодна для телефона: 2 колонки от 360px
ширины и портретная раскладка 2×3 вместо двух плиток на страницу, которые
давал набор раскладок библиотеки. Лишние участники уходят на следующую
страницу — листается свайпом и стрелками.
### Исправлено
- Иконка участника при выключенной камере больше не превращается в эллипс:
размер считается от узкой стороны плитки (container-запросы), а не как
проценты от разных сторон. В крупной плитке иконка занимает примерно её
половину, в миниатюрах карусели — всю узкую сторону с отступом 5px; на
большой плитке фокуса иконка больше не упирается в прежний потолок 96px.
- Мини-плеер в Chrome открывался на самом пользователе вместо того, что он
видел крупно: сцена в PiP-окне — отдельный экземпляр компонента и выбирала
фокус с нуля, доходя до фолбэка «показать себя». Теперь ключ фокуса
переживает переезд в мини-окно и обратно. В Safari (video-фолбэк вместо
Document PiP) поведение не менялось.
## [0.0.10] — 2026-07-28
Разбивка метрик по контейнерам в Grafana и плашка с характеристиками сервера.
### Добавлено
- Метрики по контейнерам (CPU/память/сеть каждого отдельно) — замена
`cAdvisor`, несовместимого с containerd-снапшоттером Docker Engine на
сервере `1gb` (убран в `0.0.9`). Свой минимальный сервис
`container-exporter` (`deploy/monitoring/container-exporter/`) опрашивает
Docker Engine API параллельно в фоновой задаче, независимо от
storage-driver'а. Доступ к докер-сокету изолирован через
`docker-socket-proxy` — экспортеру разрешены только `GET`-запросы по
контейнерам, любые изменяющие запросы блокируются на уровне прокси.
Панели «Топ контейнеров по CPU/памяти» вернулись в дашборд
«Хост и контейнеры».
- Плашка «Характеристики сервера» в том же дашборде: живые «Ядра CPU» /
«Объём RAM» / «Диск (/)» из `node-exporter`, GPU — из новой info-метрики
backend `vidconf_host_info` (данные `install.sh`, `HW_*` в `.env`).
## [0.0.9] — 2026-07-28
Метрики CPU/RAM/диска хоста в Grafana; дефолтные подвкладки конференций и
пользователей в админке.
### Добавлено
- Мониторинг железа: `node-exporter` (CPU/RAM/диск/сеть/load average хоста)
— профиль compose `monitoring`, без публикации портов наружу. Новый
дашборд Grafana «Хост и контейнеры». Три новых алерта Prometheus:
`HostMemoryLow`, `HostDiskLow`, `HostCpuHigh` (пороги — под сервер `1gb`:
8 ГБ RAM, 4 CPU, 50 ГБ диска). `cAdvisor` (разбивка по контейнерам)
сознательно не включён — несовместим с containerd-снапшоттером Docker
Engine на `1gb`, см. `docs/deploy/monitoring.md`.
### Изменено
- Админка, вкладка «Конференции»: вкладка «Все» перенесена в конец списка
фильтров (после «Завершённые»), по умолчанию открываются «Запланированные».
- Админка, вкладка «Пользователи»: по умолчанию открываются «Активные»
(было «Все»).
## [0.0.8] — 2026-07-27
Админка: несколько mail-доменов для регистрации, фильтр и поиск по команде в
списке пользователей, исправлен баг сохранения настроек.
### Исправлено
- Сохранение любой настройки инстанса блокировалось ошибкой «уровень AI
недоступен», даже если AI-модуль (транскрибация/суммаризация) выключен и
пользователь уровень не трогал — фронт отправлял в `PUT /admin/settings`
весь набор полей целиком, включая уже сохранённый `ai_level`. Теперь
доступность уровня проверяется только при его фактической смене; фронт
отправляет в запросе лишь реально изменённые поля.
### Добавлено
- «Эталон mail-домена» в настройках инстанса поддерживает несколько
доменов вместо одного — регистрация проходит с email с любого домена из
списка. Старое значение из БД (один домен) читается без миграции и
переписывается в новый формат при первом же сохранении.
- В списке пользователей админки — вкладки «Активные»/«Заблокированные»/
«Все» перед полем поиска.
- Поиск по пользователям учитывает и название команды — пользователи без
команды по-прежнему остаются в общей выдаче.
## [0.0.7] — 2026-07-27
Настройки устройств: выбор аудиовывода и компактная шторка на мобильном.
### Добавлено
- Выбор устройства аудиовывода (динамики/наушники/Bluetooth-гарнитура) в
«Настройках устройств» рядом с микрофоном и камерой. Выбор переживает
перезаход в комнату. Список показывается только там, где браузер умеет
им управлять (Android Chrome и другие Chromium на десктопе/мобильном);
в iOS Safari поддержки нет вовсе — вместо списка короткая подсказка, что
переключение звука там на стороне системы.
- На мобильной ширине «Настройки устройств» открываются компактной шторкой
снизу вместо модалки по центру экрана — закрывается свайпом вниз, тапом
вне панели или Escape. На десктопе поведение не изменилось.
### Примечания по эксплуатации
- Управлять маршрутизацией звука (принудительно включить громкую связь или
перекинуть звук на Bluetooth) из браузера нельзя в принципе — это делает
ОС, веб-страница может только выбрать устройство вывода там, где браузер
это позволяет (`setSinkId`).
## [0.0.6] — 2026-07-27
Управление фокусом основного окна конференции: участника можно закрепить, а
без закрепления окно само следует за говорящим. Плюс общий футер на всех
страницах сервиса.
### Добавлено
- Закрепление участника в основном окне — кнопка-булавка на плитке.
Закреплённый участник держит фокус, даже когда говорят другие; повторное
нажатие снимает закрепление, как и выход закреплённого из комнаты.
Закреплённая плитка помечена рамкой и подсвеченной булавкой; на
тач-устройствах булавка видна без наведения.
- Общий футер на всех страницах, кроме комнаты конференции: версия инстанса
и копирайт со ссылкой на автора.
### Изменения
- Основное окно конференции следует за активным говорящим, а не удерживает
выбранного один раз участника. Фокус не переключается на короткие реплики
(удержание 1.2 с) и не уводится с идущей демонстрации экрана. Среди
нескольких одновременно говорящих крупно показывается тот, у кого включена
камера. Мини-плеер (Document PiP) работает как раньше.
- Демонстрация экрана по-прежнему главнее всего: она перебивает и
закрепление, а после её завершения фокус возвращается на закреплённого
участника.
- Футер админки заменён общим компонентом; в брендовой панели экранов входа
строка копирайта с захардкоженным годом убрана — год теперь берётся
текущий.
### Исправлено
- Календарь: «г.» после года убрана и из подписей дней в самой сетке (видны
как всплывающая подсказка и в accessibility-дереве) — в недельном и
месячном виде. В 0.0.4 это было исправлено только для подписи периода.
## [0.0.5] — 2026-07-27
Контактный адрес инстанса: настраиваемый адрес для ответов на письма
(уходят от `no-reply@`) и кнопка проверки почтовой конфигурации из
админки.
### Добавлено
- Настройка «Контактный адрес» в админке (вкладка «Настройки») — email
подставляется в заголовок `Reply-To` писем подтверждения регистрации,
приглашений на конференции и саммари; при выключенной настройке
`Reply-To` не проставляется, поведение как раньше.
- Кнопка «Отправить тестовое письмо» — синхронная проверка почтовой
конфигурации без регистрации фиктивного пользователя. Получатель по
умолчанию — email текущего администратора, можно указать другой.
Результат виден сразу: успех либо текст ошибки транспорта (сервер
недоступен/получатель отклонён), без логина и пароля SMTP в ответе.
## [0.0.4] — 2026-07-26
Календарь конференций: перестроен в раскладку «календарь во всю ширину плюс
модальные окна» — карточки событий разгружены, подробности вынесены во
всплывающее окно.
### Изменения
- Форма создания и редактирования конференции больше не занимает постоянную
колонку справа, а открывается в модальном окне — по кнопке «Новая
конференция», по карандашику на карточке события или из информационного
окна. Добавлен общий хук `useModalDismiss` (закрытие по Escape и возврат
фокуса на элемент, из которого окно открыли).
- Блок календаря занимает всю ширину страницы.
- Карточка события в сетке содержит только название (обрезается многоточием и
больше не вылезает за границы ячейки) и — у организатора — кнопку
редактирования. Время, номер и статус переехали в информационное окно.
- Клик по карточке события всегда открывает информационное окно, в том числе
для своих конференций: редактирование стало отдельным действием.
- Информационное окно вхождения дополнено статус-бейджем и кнопкой
«Редактировать» для организатора.
### Исправления
- Подпись периода в недельном и месячном виде больше не содержит «г.»
(форматирование через `Intl.DateTimeFormat` вместо локали FullCalendar).
## [0.0.3] — 2026-07-26
Мобильная версия: адаптивная вёрстка для узких экранов на ключевых экранах
сервиса, найденная и поправленная по итогам ручного прохода по мобильному
интерфейсу.
### Исправления
- Вход/регистрация (`AuthLayout`): заголовок «Ваша инфраструктура» вылезал за
край брендовой панели на узких экранах — кегль теперь адаптивно уменьшается
(`clamp()`) вместо обрезки.
- Комната конференции: топбар и тулбар не помещались на мобильной ширине
(тулбар с 8 кнопками физически шире экрана, крайние кнопки были обрезаны без
возможности до них докрутить). На мобильном тулбар сокращён до
микрофона/камеры/устройств/чата/выхода (демонстрация экрана,
полноэкранный режим и мини-окно скрыты — редко нужны с телефона), в топбаре
скрыты название конференции и строка статуса, а чип «№ … / Пригласить»
оставлен — с телефона он нужнее.
- Админка: заголовок и 4 вкладки раздела не помещались в ширину (вкладки
переносятся в 2 ряда, поясняющий текст под заголовком скрыт на мобильном);
таблицы «Конференции» и «Пользователи» обрезались вбок — на мобильном в них
остаются только ключевые колонки, название конференции стало кнопкой,
открывающей то же окно редактирования, что и раньше (туда же добавлена
кнопка удаления — на мобильном столбец действий скрыт).
- Подключение к конференции (`/join`): кнопка «Ввести другую ссылку или
номер» на экране завершённой конференции вылезала за карточку на узких
экранах (единственная кнопка на этом флоу без формы-обёртки, задающей ей
ширину, а `.btn` держит `white-space: nowrap`).
## [0.0.2] — 2026-07-26
Релиз воспроизводимого боевого развёртывания: конфигурация деплоя перенесена в
репозиторий как источник истины, устранён инцидент безопасности, добавлена
пошаговая инструкция для девопсов.
### Безопасность
- `postgres` и `redis` сняты с публикации на `0.0.0.0` и привязаны к `127.0.0.1`
(docker писал DNAT в обход `ufw`, порты были открыты в интернет).
- Порты `backend`, `livekit`-signaling, `prometheus`, `grafana`, `llm` также
переведены на loopback — наружу остаются только `80/443/7881` (+ UDP `54000-54100`).
- Для `redis` включена обязательная аутентификация (`--requirepass`); пароль
проброшен во всех потребителей (backend, worker, exporter, livekit, egress).
### Развёртывание и инфраструктура
- `nginx`/`coturn`/`livekit`: TLS на 443, http→https редирект, ACME-webroot;
конфиги вынесены в `*.template` и рендерятся через `deploy/render-templates.sh`
(`envsubst`). Секреты — только из `.env`, обязательны (`${VAR:?}`), без
небезопасных дефолтов.
- `--env-file .env` добавлен во все вызовы `docker compose` (без него compose не
подхватывал корневой `.env` и брал dev-дефолты — корень бага «конференции не
работают у других» и `WARN: LIVEKIT_API_KEY not set`).
- Мониторинг развязан от опционального LLM: `job=llm`/алерт `LlmDown`
закомментированы для профилей без `llm`/`llm-gpu`.
- `install.sh`: fail-fast валидация — установка останавливается с понятной
ошибкой, если на боевом домене остались dev-плейсхолдеры (`example.com`,
`ws://localhost`, `devkey` и т.п.), вместо тихого подъёма нерабочего прода.
- `install.sh`: флаг `--monitoring` (Grafana/Prometheus раньше не поднимались
ни в одном пресете).
- `.env.example` покрывает все параметры деплоя; дефолтные профили —
`media,monitoring`.
### Исправления
- `nginx`: `/openapi.json` больше не перехватывается SPA-фолбэком, а отдаётся
схемой backend.
- Предупреждение в `.env.example`: `LIVEKIT_PUBLIC_URL` в HTTPS-проде обязан
быть `wss://`.
### Документация
- Добавлено `docs/deploy/DEPLOYMENT.md` — полное руководство от голой Ubuntu 24
до рабочего `https://<домен>`: SSL, `.env`, профили, траблшутинг, доступ к
мониторингу через ssh-туннель, описание панелей, runbook включения
транскрибации/суммаризации. Ссылки добавлены в `README.md`.
- `docs/deploy/install.md`: задокументирован флаг `--monitoring`.
### Примечания по эксплуатации
- На боевом сервере исправлен certbot deploy-hook (`nginx -s reload``restart`):
без этого после автопродления сертификата nginx продолжал бы отдавать старый.
- TURN-раздача клиентам (`rtc.turn_servers` + TURN/TLS на 443) остаётся
опциональной — кросс-сетевое медиа проверено вживую и работает без неё;
нужна только для экстремального NAT (CGNAT/жёсткий корпоративный firewall).
## [0.0.1]
Первоначальная версия VidConf.
[0.0.10]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.10
[0.0.9]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.9
[0.0.8]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.8
[0.0.7]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.7
[0.0.6]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.6
[0.0.5]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.5
[0.0.4]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.4
[0.0.3]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.3
[0.0.2]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.2
[0.0.1]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.1