feat(release): global create_release.py with deterministic OS marking #65
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Контекст
Сейчас
create_release.pyживёт в каждом репо отдельно (voice_assistant, video_uniq) — риск рассинхрона, нет единого стандарта. Платформа в release notes не маркируется детерминированно: asset filenamevoice-assistant.zipбез ОС, в body нет секции "Системные требования". Пользователь на странице релиза не видит для какой ОС сборка.Исследование 4 топ-проектов (VSCode/OBS/yt-dlp/espanso) показало стандарт: asset filename содержит ОС (
OBS-Studio-32.2.1-Windows-x64-Installer.exe,yt-dlp.exe,Espanso-Mac-Universal.zip), а min версия ОС упоминается в important notes (когда поднимается).Issue #63 (closed) удалил
platformarg изcreate-changelogtool — платформа не должна быть в CHANGELOG (не детерминировано, пишет агент). Платформа должна быть в CI (детерминированно).Задача
Создать
.opencode/scripts/create_release.py— глобальная утилита, self-contained (только stdlib: re, pathlib, tomllib, json, os, urllib.request):pyproject.toml→ полеname(черезtomllib, Python 3.11+)RUNNER_OSenv var (Forgejo/act runner auto-set):Windows+RUNNER_ARCH=X64→windows-x64Linux+X64→linux-x64macOS+ARM64→macos-arm64{name}-{os}-{arch}.zip(напримерvoice-assistant-windows-x64.zip)RELEASE_PLATFORMenv var (из release.yml) — полная строка для body (например "Windows 10+ (64-bit)")CHANGELOG.mdчерез встроенный экстрактор (копия логики release_notes.py из voice_assistant):extract_changelog_section(Path("CHANGELOG.md"), tag)— regex-поиск секции по тегу, срез заголовка/шапки/links, fallback на весь CHANGELOG если секция не найдена{name}-{os}-{arch}.zipчерез multipart/form-data (urllib)FORGEJO_URL(илиGITHUB_SERVER_URL),GITHUB_TOKEN,GITHUB_REF_NAME(тег),RELEASE_PLATFORM,RUNNER_OS,RUNNER_ARCHСоздать
.opencode/scripts/release_notes.py— экстрактор секции CHANGELOG (self-contained, stdlib only):extract_changelog_section(changelog_path: Path, tag: str) -> strscripts/release_notes.py(PR #27): regex^## [VERSION] [-—] YYYY-MM-DD, срез заголовка/шапки/trailing links, 3 fallback'аcreate_release.pyчерез импортОбновить
skills/release/SKILL.md— новый раздел «Платформа в релизе (детерминированный стандарт)»:{name}-{os}-{arch}.zip— формируется из pyproject.tomlname+RUNNER_OS/RUNNER_ARCHRELEASE_PLATFORMenv var в release.yml (препендится к CHANGELOG-секции)create_release.pyскачивается из opencode-config через curl в каждом репо (одна версия, не хранится локально)RELEASE_PLATFORMenv var в release.yml + запись в CHANGELOG### Измененотекстом: «Минимальная версия Windows повышена до 11» (как yt-dlp important changes)RELEASE_PLATFORMи asset filename**Платформы:**заголовок (нарушает стандарт, удалён issue #63), НЕ Python в требованиях (встроен в exe через PyInstaller), НЕ писать платформу в CHANGELOG (не детерминировано, агент может забыть)Удалить старое упоминание
platformarg из SKILL.md (если осталось после issue #63)Контракты
Что создаётся
.opencode/scripts/create_release.py— глобальная утилита, self-contained (stdlib only).opencode/scripts/release_notes.py— экстрактор, self-contained (stdlib only)Что обновляется
skills/release/SKILL.md— раздел платформы + пример release.ymlЧто НЕ меняется
create-changelogtool — уже безplatformarg (issue #63 closed)skills/repo-readme/SKILL.md— НЕ трогатьФормат asset filename
{name}-{os}-{arch}.zipгде:name=pyproject.tomlfieldname(напримерvoice-assistant)os= lowercaseRUNNER_OS(windows/linux/macos)arch= lowercaseRUNNER_ARCH(x64/arm64)voice-assistant-windows-x64.zipФормат body релиза
Где
changelog_section= результатextract_changelog_section(CHANGELOG.md, tag)— bullets секции текущей версии (без шапки, без links).Если
RELEASE_PLATFORMне задан → body =changelog_section(backward compat, без секции).Что НЕ входит в body
# Changelog, «Все заметные изменения...», «Формат: ...») — срезается экстрактором[0.1.0]: https://...) — срезаются экстрактором**Платформы:**заголовок (удалён issue #63)Инварианты
create_release.pyself-contained: только stdlib (re, pathlib, tomllib, json, os, urllib.request), без внешних зависимостейrelease_notes.pyself-contained: только stdlibRELEASE_PLATFORMне задан → body без секции (backward compat)CHANGELOG.mdотсутствует → body = "" (релиз без нот, не падать)pyproject.tomlотсутствует → ошибка (имя проекта обязательно)RUNNER_OSне задан → ошибка (ОС обязательна для asset filename)Граничные случаи
pyproject.tomlбез fieldname→ ошибка с сообщением "field 'name' not found in pyproject.toml"RUNNER_OS=Windows+RUNNER_ARCH=X64→windows-x64(lowercase)RUNNER_OS=Linux+RUNNER_ARCH=X64→linux-x64RUNNER_OS=macOS+RUNNER_ARCH=ARM64→macos-arm64(lowercase os, ноmacOS→macos)RUNNER_OS=macOS+RUNNER_ARCH=X64→macos-x64(Intel Mac)RELEASE_PLATFORM=""(пустая строка) → body без секции (backward compat, как omitted)RELEASE_PLATFORM="Windows 10+ (64-bit)"→ body с секцией—вместо дефиса-в заголовке (## [0.1.0] — 2026-08-11) → regex покрывает обаvoice-assistant→voice-assistant-windows-x64.zip(не двойной дефис)Влияние на связанные компоненты
skills/release/SKILL.md— основной файл обновления.opencode/scripts/create_release.py— новый файл.opencode/scripts/release_notes.py— новый файлcreate_release.py:scripts/create_release.py, скачать глобальный через curl вrelease.yml, добавитьRELEASE_PLATFORMenv varcreate-changelogtool — НЕ трогать (issue #63 closed,platformarg уже удалён)skills/repo-readme/SKILL.md— НЕ трогатьВне scope
create_release.py— отдельный issue в voice_assistantrelease_notes.pyтесты — опционально, если opencode-config имеет тест-инфраструктуру для Python скриптовКритерии приемки
.opencode/scripts/create_release.pyсоздан — self-contained (stdlib only), читает pyproject.toml name, парсит RUNNER_OS/ARCH, формирует asset filename{name}-{os}-{arch}.zip, формирует body с секцией "Системные требования" изRELEASE_PLATFORM, idempotent (delete+create).opencode/scripts/release_notes.pyсоздан — self-contained (stdlib only),extract_changelog_section(path, tag), 3 fallback'а (секция не найдена, CHANGELOG отсутствует, пустая секция)skills/release/SKILL.md— раздел «Платформа в релизе (детерминированный стандарт)» добавленcreate_release.py+RELEASE_PLATFORMenv var{name}-{os}-{arch}.zip### Изменено+ обновитьRELEASE_PLATFORM; multi-platform → отдельный job на ОС**Платформы:**заголовок, НЕ Python в требованиях, НЕ платформа в CHANGELOGplatformarg удалено из SKILL.md (если осталось после issue #63)