Перейти к содержимому

Релизы и обновления ​

Текущие релизы:

ПродуктВерсияПримечания
Движокlv24-seo 0.5.2Bugfix-релиз; без миграции схемы, без новых CLI-команд и MCP-инструментов
Приложение0.2.2Hardening-патч: очистка sidecar перед обновлением, надёжная запись, секреты и сброс устаревшего состояния; включает движок 0.5.2

Версия приложения и версия движка независимы, но приложение закрепляет точный движок и отказывается работать с версией ниже минимальной.

Движок 0.5.2 ​

Это bugfix-релиз линии 0.5.x. Он закрывает блокеры, найденные после 0.5.1: относительный storage.data_dir в seo.toml следовал за рабочим каталогом оболочки, CLI собирал write-gate без журнала идемпотентности, ошибки загрузки sitemap эхом возвращали URL с query-токенами, а GSC заявлял полное покрытие, когда последняя страница ровно заполняла лимит строк.

Без миграции схемы и без новых CLI-команд или MCP-инструментов. JSON-конверт сохраняет прежние ключи; doctor добавляет аддитивные поля meta.data_dir / meta.data_dir_source и может нести предупреждение. Существующие хранилища открываются без изменений, а конфиги с абсолютным data_dir работают как раньше.

Что изменилось:

  • Привязка data-dir. Относительный storage.data_dir из seo.toml теперь разрешается относительно каталога этого файла, поэтому lv24-seo --config /srv/site/seo.toml использует /srv/site/data из любого рабочего каталога. init создаёт <config dir>/data и пишет data_dir = "./data". Встроенное значение по умолчанию (без блока [storage]) и LV24_SEO_DATA_DIR намеренно остаются привязанными к процессу. doctor --json сообщает meta.data_dir и meta.data_dir_source (config или working directory), а config show --json показывает эффективный путь.
  • Абсолютные пути планировщика. resolve_config_path всегда возвращает абсолютный нормализованный путь. schedule install и schedule print встраивают абсолютный аргумент --config и используют родительский каталог конфига как рабочий каталог, поэтому задание запускает тот же конфиг из любого каталога планировщика.
  • Повторобезопасные записи CLI. Команда записи с --confirm открывает SQLite-журнал рабочей области и передаёт его в WriteGate. Повторный токен возвращает status: skipped с reason: duplicate, и провайдер вызывается ровно один раз. Dry run не открывает журнал и не создаёт базу. Без инициализированной рабочей области команда всё равно работает, но конверт предупреждает, что защита от повтора отключена на пять минут жизни токена.
  • Маскирование URL в предупреждениях sitemap. Неудачная загрузка sitemap сообщает только тип исключения (HTTPError, TimeoutError, …), но не URL и не query-строку. Сбой остаётся видимым и машиночитаемым, но ?key=… не попадает в предупреждения, limitations[] или MCP-полезную нагрузку.
  • Честность точного лимита GSC. Последняя страница GSC, которая ровно заполняет лимит в 50 000 строк, помечается truncated: true с rows_cap_50000; меньший лимит вызывающего даёт предупреждение с его значением. Нулевой лимит считается лимитом, а не пустым результатом. Полная страница не доказывает, что за лимитом нет строк.
  • Опциональное маскирующее логирование. LV24_SEO_LOG_LEVEL устанавливает redacting-handler ровно в двух точках входа: callback CLI и lv24-seo mcp serve. Если переменная не задана, конфигурация логирования вызывающего не меняется. Вывод — одна JSON-строка на запись, когда stderr не терминал (pipe, лог планировщика, MCP-хост), и обычная строка в терминале. MCP-транспорт пишет только в stderr; stdout остаётся протоколом.
  • Мелкие исправления. Pending-заявка записи после падения по-прежнему не имеет TTL; удаление data/seo.sqlite3 сбрасывает журнал; doctor не падает на относительном data-dir.

Проверки этого релиза:

ПроверкаРезультат
Офлайн-набор тестов1141 passed, 1 skipped
ruff checkЧисто
ruff format --checkЧисто
mypy srcЧисто
MCP registry --checkЧисто (поверхность не менялась)

Известные ограничения 0.5.2:

  • Конфиг, открытый через symlink, привязывает data-dir рядом со ссылкой, а не с целью: symlinks намеренно сохраняются. LV24_SEO_DATA_DIR остаётся process-scoped переопределением.
  • Pending-заявка записи после падения не имеет TTL и считается выполняющейся, пока оператор её не освободит. Это намеренно: ложный повтор может дублировать запись провайдера.
  • Без data-dir защиты от повтора нет; токен остаётся валидным все пять минут.
  • Сайт ровно с 50 000 строк GSC и без строк за лимитом тоже помечается truncated. Это намеренно: полная страница не доказывает отсутствие следующей строки.
  • Логирование остаётся опциональным. Правила редактирования покрывают чувствительные ключи, известные префиксы токенов и длинные непрозрачные значения, но не каждый формат секрета конкретного провайдера.

Артефакты приложения 0.2.2 ​

0.2.2 — hardening-патч для превью 0.2.x. Он исправляет сбой обновления из-за заблокированного sidecar движка, делает запись конфигурации и настроек в Rust надёжной и приватной, сбрасывает устаревшее состояние UI и включает lv24-seo 0.5.2.

АртефактПлатформаНазначение
LV24.SEO.Optimizer_0.2.2_x64-setup.exe + .exe.sigWindows x64NSIS-установщик для пользователя; подписанный пакет обновления
LV24-SEO-Optimizer_0.2.2_x64-portable.zipWindows x64Portable-сборка; manual-only
LV24.SEO.Optimizer_0.2.2_aarch64.dmgmacOS Apple siliconПервая установка
LV24.SEO.Optimizer_0.2.2_x64.dmgmacOS IntelПервая установка
LV24.SEO.Optimizer_0.2.2_aarch64.app.tar.gz + .sigmacOS Apple siliconПодписанный пакет обновления
LV24.SEO.Optimizer_0.2.2_x64.app.tar.gz + .sigmacOS IntelПодписанный пакет обновления
LV24.SEO.Optimizer_0.2.2_amd64.AppImage + .AppImage.sigLinux x64AppImage; подписанный пакет обновления
LV24.SEO.Optimizer_0.2.2_amd64.deb, LV24.SEO.Optimizer-0.2.2-1.x86_64.rpmLinux x64Установка менеджером пакетов; manual-only
latest.jsonВсеПодписанный манифест обновлений
SHA256SUMS.txtВсеSHA-256 каждого опубликованного артефакта

Установщику Windows нужны Windows 10/11 x64 и runtime WebView2; NSIS-установщик может его скачать, portable ZIP — нет. Linux-пакеты собраны на Ubuntu 22.04 с базой glibc 2.35 и только для x64. macOS требует macOS 13 или новее; используйте aarch64 DMG на Apple silicon и x64 DMG на Intel.

Очистка sidecar перед обновлением ​

Sidecar движка лежит внутри установленного каталога ресурсов, поэтому запущенный процесс lv24-seo держит файл заблокированным и NSIS-установщик не может его заменить. Перед запуском установщика оболочка вызывает prepare_update, который останавливает только те PID движка, которые зарегистрировал этот экземпляр приложения при их запуске. Ничего не ищется по имени образа, поэтому другая установленная копия, portable-сборка, запущенный в терминале lv24-seo или посторонний процесс не затрагиваются. Короткое ожидание (2 с) подтверждает завершение.

Если очистка не удалась, установка блокируется с UPDATE_ENGINE_BUSY, а не запускает установщик, который сломается на середине. Ошибка повторяемая: закройте запуск, удерживающий sidecar, и нажмите кнопку снова.

Секреты и конфигурация ​

  • Yandex Metrika сохраняет собственный auth-провайдер (metrika, yandex_metrika_token) в списке провайдеров, бейдже Settings, окне секретов и подписях en/ru/zh. Он никогда не берёт токен Webmaster.
  • Приложение и CLI используют одну запись OS keychain на провайдера (сервис lv24-seo). Токен, введённый через lv24-seo auth set --provider <p> --stdin в терминале, появляется в auth status приложения без повторного ввода, а токен из приложения виден CLI.
  • Токен из LV24_SEO_* показывается в UI как read-only: приложение не может удалить переменную окружения и говорит об этом, а не предлагает кнопку удаления, которая ничего не делает. auth logout с deleted: false показывается честно.
  • Состояние workspace, отчёта, doctor и секретов очищается при смене workspace или переходе движка в offline. Действия, которые не могут работать, отключаются, а не падают по клику. Каталоги сообщений en/ru/zh согласованы; отсутствующий ключ — ошибка теста.
  • Запись конфигурации и настроек атомарна и fsynced (файл и родительский каталог). Временные черновики и резервные копии имеют режим 0600; чтение конфига ограничено 8 MiB; настройки загружаются по полям; зарезервированные имена Windows и завершающие точки/пробелы отклоняются в каждом компоненте пути. stderr валидации конфигурации редактируется до попадания в UI или лог.

Матрица автообновления ​

ПакетОбновление в приложенииЧто происходит
Windows NSISДаСкачивает подписанный setup .exe, останавливает отслеживаемые PID sidecar, запускает установщик в passive-режиме, перезапускает
macOS .appДаСкачивает подписанный .app.tar.gz, заменяет приложение, перезапускает
Linux AppImageДаСкачивает подписанный AppImage, заменяет его, перезапускает
Windows portable ZIPНетSettings ведёт на страницу релиза; скачайте и распакуйте новый ZIP
Linux debНетSettings ведёт на страницу релиза; обновление менеджером пакетов
Linux rpmНетSettings ведёт на страницу релиза; обновление менеджером пакетов
MSIНетMSI не производится; установка MSI считается ручной
Неизвестный пакетНетSettings ведёт на страницу релиза

Manual-only — намеренно. Пакет deb или rpm принадлежит базе пакетов; MSI этим проектом не производится, и NSIS-пакет обновления не может его заменить; portable ZIP не имеет установщика, который можно заменить, и может лежать на съёмном носителе. Приложение сообщает тип установленного пакета и отключает встроенный установщик для таких случаев. Оно не делает вид, что ручной пакет был обновлён.

Путь Windows NSIS теперь проверен end-to-end дважды: 0.2.0 → 0.2.1 и 0.2.1 → 0.2.2. Во втором запуске установленная сборка 0.2.1 обнаружила 0.2.2, скачала и проверила подписанный пакет, установила его в passive-режиме, перезапустилась и сообщила 0.2.2 с готовым движком 0.5.2. 0.2.2 обновляется напрямую с 0.2.0; у 0.1.0 нет обновлятора, нужна одна ручная установка.

Обновление 0.2.1 → 0.2.2 выполняет старый обновлятор 0.2.1, в котором нет новой очистки отслеживаемых PID. Если во время первого обновления активен sidecar, повторите после его выхода или установите 0.2.2 вручную. 0.2.2 → later использует очистку отслеживаемых PID и блокируется с UPDATE_ENGINE_BUSY, если отслеживаемый sidecar не удаётся остановить.

Релизный конвейер ​

Workflow приложения ручной и owner-gated. У него нет триггеров push, pull-request или tag. Владелец запускает Actions → Desktop build → Run workflow и подтверждает окружение desktop-release; запуск не владельцем пропускается.

ВходЗначение по умолчаниюСмысл
engine_version0.5.2Точная версия движка в sidecar
signedfalseЗапросить подпись/нотаризацию ОС; в этом zero-spend репозитории не настроено
publishfalseСоздать GitHub release после прохождения всей матрицы
tagПустоТег релиза vX.Y.Z; обязателен при publish=true

Значение по умолчанию соответствует пину 0.2.2. Релизный гейт отклоняет несоответствие манифеста, если передана другая версия.

RunnerTargetПакеты
windows-latestx86_64-pc-windows-msvcNSIS
ubuntu-22.04x86_64-unknown-linux-gnuAppImage, deb, rpm
macos-15aarch64-apple-darwinDMG + app
macos-15-intelx86_64-apple-darwinDMG + app

Все runner'ы — стандартные GitHub-hosted. Не используются larger runner, платные минуты, платное хранилище или платный сервис подписи. Артефакты сборки хранятся 7 дней; GitHub release — долговечный канал распространения.

Пин sidecar и контрольные суммы ​

Релизный sidecar — дерево PyInstaller onedir, собранное на соответствующем хосте; PyInstaller не кросс-компилирует. Версии движка, Python, Pydantic, Typer и PyInstaller закреплены в scripts/cli-checksums.json. 0.2.2 закрепляет движок 0.5.2, Python 3.12, Pydantic 2.14.3, Typer 0.29.0 и PyInstaller 6.22.3.

Вывод PyInstaller onedir не байт-воспроизводим. Поэтому политика контрольных сумм разделена:

  • Локальная релизная сборка — строгая. scripts/verify-sidecar.mjs должен совпасть с закоммиченными SHA-256 и размером; --write обновляет пин после ревью. null означает «ещё не проверено», а не «проверено».
  • CI-пересборка — rebuild-aware. Job сборки запускает верификатор с --no-hash и записывает фактический SHA-256 в release/sidecar-checksums-<target>.json.
  • Релизный гейт — по отчётам. Релизный job требует валидный отчёт для каждого отгружаемого target: совпадение имени target, hashPolicy: "rebuild", ok: true, 64-hex хеш, положительный размер и точную версию движка.

Для 0.5.2 Windows x64 имеет проверенный локальный пин; target'ы Linux и macOS остаются null, пока sidecar 0.5.2 не будет пересобран и проверен на соответствующем хосте. Windows-пин 0.5.1 не переносился, потому что исполняемый файл меняется вместе с движком. Отчёты контрольных сумм — доказательства CI, а не релизные артефакты. SHA256SUMS.txt покрывает установщики, пакеты обновления, подписи и latest.json; исполняемый файл sidecar находится внутри этих пакетов и отдельно не указан. При ручной установке сверяйте скачанный артефакт с SHA256SUMS.txt.

bash
node scripts/verify-sidecar.mjs \
  --root src-tauri/engine \
  --target x86_64-pc-windows-msvc \
  --engine-version 0.5.2

latest.json, подпись и публикация ​

Подписи обновлений используют бесплатный ключ Ed25519/minisign, отдельный от подписи кода ОС. Публичный ключ встроен в приложение; приватный — секрет репозитория, передаваемый только на шаг сборки. Включён requireSignedVersion, поэтому объявленная версия привязана к подписанному пакету. Обновление принимает только версию выше текущей, поэтому откатиться нельзя.

scripts/stage-release-assets.mjs выравнивает и нормализует имена пакетов и пишет метаданные updater-<platform>.json для каждой платформы. scripts/merge-latest-json.mjs объединяет их в latest.json:

  • обязательные generic-ключи: windows-x86_64, linux-x86_64, darwin-aarch64, darwin-x86_64;
  • bundle-алиасы, которые проверяет обновлятор: windows-x86_64-nsis, linux-x86_64-appimage, darwin-aarch64-app, darwin-x86_64-app;
  • необязательные linux-x86_64-deb и linux-x86_64-rpm только если Tauri создал их подписи;
  • каждый URL указывает под releases/download/<tag>/;
  • каждая подпись сверяется с файлом .sig на диске;
  • каждый упомянутый артефакт должен существовать;
  • примечания берутся из docs/releases/<version>.md, если файл есть.

Релиз сначала создаётся как draft. Артефакты загружаются, пока он draft, latest.json — последним, затем job публикует через gh release edit --draft=false и проверяет удалённые имена артефактов. releases/latest/download/latest.json разрешается только на опубликованный релиз, поэтому пользователи не видят частично загруженный манифест. Повторный запуск переиспользует существующий draft, очищает его артефакты и отказывается перезаписывать опубликованный релиз.

Закрепление версий ​

Версия приложения должна совпадать в package.json, src-tauri/tauri.conf.json, src-tauri/Cargo.toml, Git-теге и заголовке релиза. Пин движка живёт в scripts/cli-checksums.json; workflow передаёт engine_version явно, а релизный гейт требует совпадения с манифестом.

MIN_ENGINE_VERSION в src-tauri/src/commands.rs в текущем исходнике равен 0.5.2. Оболочка принимает движок не старше этой версии и помечает более старый как offline с уведомлением. Более новый движок проходит гейт, но не является релизно-проверенным пином. Сборочная версия может использовать LV24_SEO_BIN с другой версией; UI помечает его внешним и всё равно проверяет минимум. Движок из PATH используется только при LV24_SEO_ALLOW_PATH_ENGINE=1.

Однократное обновление с 0.1.0 ​

У 0.1.0 нет updater, endpoint и публичного ключа. Он не может найти или установить 0.2.2. Скачайте и установите 0.2.2 вручную один раз (NSIS-установщик или portable ZIP в Windows). После этого установка 0.2.2 может автоматически обновляться до следующих релизов, если использует пакет с поддержкой автообновления.

Предыдущие релизы ​

  • Приложение 0.2.1 исправило поверхность токена Yandex Metrika и сделало общий keychain CLI/приложения явным. Это был первый релиз, доставленный встроенным обновлятором с 0.2.0.
  • Приложение 0.2.0 было первым мультиплатформенным релизом: Windows NSIS и portable ZIP, Linux AppImage/deb/rpm, macOS DMG и подписанные пакеты обновления.
  • Движок 0.5.1 исправил повторы write-gate, ограничил текст обхода, поправил MCP-аннотации и достижимые лимиты. Он считал последнюю страницу GSC на точном лимите полной; 0.5.2 меняет это решение и считает полную последнюю страницу потенциально усечённой.

Откат ​

Автоматического отката нет. Откат — ручная установка более старого релиза.

СбойДействие
Плохой установщик, но рабочее приложениеВыпустить исправленный патч; не перезаписывать артефакты под тем же тегом
Плохой latest.jsonВыпустить исправленный патч; draft-гейт не даёт частичному манифесту стать видимым
Скомпрометированный ключ обновленийРотировать ключ, выпустить ручной релиз с новым публичным ключом; автообновление не переживает ротацию
Регрессия движкаЗакрепить предыдущую версию движка, пересобрать и выпустить патч
Нужна старая сборка приложенияУстановить вручную; обновлятор отказывается от понижения

Не перемещайте и не переиспользуйте опубликованный тег. Держите артефакты предыдущего релиза доступными для отката. Если endpoint нужно отключить, выпустите ручной релиз и задокументируйте это.

Проверка загрузки ​

SHA256SUMS.txt покрывает каждый опубликованный артефакт. Проверьте файлы, которые собираетесь устанавливать:

bash
sha256sum -c SHA256SUMS.txt --ignore-missing

На macOS shasum -a 256 -c SHA256SUMS.txt доступен в базовой системе. В Windows сравните Get-FileHash <file> -Algorithm SHA256 с соответствующей строкой. Не запускайте файл, хеш которого не совпадает.

По умолчанию пакеты ОС не подписаны (Windows, Linux) или подписаны ad-hoc (macOS). Подпись обновления аутентифицирует обновления, а не первую ручную загрузку. Предупреждения SmartScreen и Gatekeeper ожидаемы; сверьте контрольную сумму и используйте документированный путь More info → Run anyway или Open Anyway. Не отключайте эти защиты глобально.

См. Безопасность и приватность для доверия к обновлениям и Архитектуру для раскладки sidecar.

Source: _source/engine-releases-0.5.2.md, _source/desktop-releases-0.2.2.md, _source/desktop-releases-0.2.1.md, _source/desktop-releases-0.2.0.md, _source/desktop-release.md, _source/desktop-security.md.