cli: scaffold phase 1 asset release commands

Add metin-release CLI with argparse dispatcher, result envelope and
error hierarchy, and the full Phase 1 release subcommand set:

  release inspect         - scan source root
  release build-manifest  - wraps make-manifest.py
  release sign            - wraps sign-manifest.py, enforces mode 600
  release diff-remote     - HEAD each blob hash against a base URL
  release upload-blobs    - rsync release dir minus manifest
  release promote         - rsync manifest.json + signature
  release verify-public   - GET + Ed25519 verify, optional blob sampling
  release publish         - composite of the above with per-stage timings

Respects --json / --verbose / --quiet. Exit codes follow the plan
(1 validation, 2 remote, 3 integrity, 4 reserved for ERP).
This commit is contained in:
Jan Nedbal
2026-04-14 18:59:50 +02:00
parent fb1e0cda87
commit e70fc300e2
22 changed files with 1344 additions and 1 deletions

42
pyproject.toml Normal file
View File

@@ -0,0 +1,42 @@
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
[project]
name = "metin-release-cli"
version = "0.1.0"
description = "Orchestration CLI for Metin2 client releases"
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ name = "Jan Nedbal", email = "jan.nedbal@apertia.cz" },
]
requires-python = ">=3.11"
dependencies = [
"cryptography>=41",
"requests>=2.31",
]
[project.optional-dependencies]
dev = [
"pytest>=8",
"pytest-mock>=3",
]
[project.scripts]
metin-release = "metin_release.cli:main"
[tool.setuptools.packages.find]
where = ["src"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q"
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "W", "I", "B", "UP"]
ignore = ["E501"]