Merging PR #1063 ("Doc update", 3.3-dev -> main) triggered the stable
release path, which fell back to the raw PR title as the version string
and shipped a Docker image tagged Doc-update as :latest — every
container pulling latest then crashed on SemVer parsing (#1065).
The release trigger is now explicit:
- bare X.Y.Z tag -> stable release, refused unless the tagged commit is
an ancestor of main
- tag containing alpha/beta -> pre-release (unchanged)
- PR merges only run tests and a docker build test
Also pass head.ref through an env var instead of inlining it in the
script (injection hardening), and take release notes solely from the
changelog file since tag pushes carry no PR body.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jejs2dffkscAbhZkcjZ1oK
Refresh the module map and migration instructions, and document the new
conventions (async DB + session-per-operation, constructor-injected
services, downloader Protocol + capabilities, reload_settings) so the old
Program/sub_thread/combine.py references don't mislead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014w1Z6Nxy6XTRgkFXqPr9Zh
Replace pip + requirements.txt with uv for dependency management.
- Multi-stage Dockerfile using ghcr.io/astral-sh/uv builder image
- CI updated to use astral-sh/setup-uv@v4
- Ruff config moved to [tool.ruff.lint] (fixes deprecation)
- Transitive deps removed, missing direct deps added (requests, PySocks, urllib3)
- Database layer migrated to async (AsyncSession + aiosqlite)
- Tests updated to match async database interface
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>