Bind installed releases to signed artifact receipts

This commit is contained in:
2026-07-22 20:42:05 +02:00
parent 4dc0c8d013
commit 9c0650b2ed
13 changed files with 2179 additions and 52 deletions

View File

@@ -23,8 +23,25 @@ def main() -> int:
selective.add_argument("--channel", default="stable")
selective.add_argument("--repo-version", action="append", default=[], metavar="REPO=VERSION", required=True)
selective.add_argument("--catalog-signing-key", action="append", default=[], metavar="KEY_ID=PRIVATE_KEY", required=True)
selective.add_argument(
"--python-artifact",
action="append",
default=[],
metavar="REPO=/PATH/TO/WHEEL",
help=(
"Built immutable wheel whose archive and install-stable payload identity "
"will be computed into the signed catalog; may be repeated."
),
)
selective.add_argument("--base-catalog", help="Catalog path or URL to use as the source. Defaults to local channel, then public channel.")
selective.add_argument("--output-dir", type=Path, help="Candidate output directory. Defaults to runtime/release-candidates/<channel>-<timestamp>.")
selective.add_argument(
"--output-dir",
type=Path,
help=(
"Private candidate output directory. Defaults below "
"$XDG_STATE_HOME/govoplan/release-candidates (or ~/.local/state)."
),
)
selective.add_argument("--public-base-url", default="https://govoplan.add-ideas.de")
selective.add_argument("--repository-base", default="git+ssh://git@git.add-ideas.de/add-ideas")
selective.add_argument("--source-remote", default="origin", help="Configured Git remote containing immutable source tags.")
@@ -74,6 +91,7 @@ def main() -> int:
expires_days=args.expires_days,
sequence=args.sequence,
check_public=not args.skip_public_check,
python_artifacts=parse_repo_paths(tuple(args.python_artifact)),
)
payload = to_jsonable(result)
if args.json:
@@ -144,6 +162,20 @@ def parse_repo_versions(values: tuple[str, ...]) -> dict[str, str]:
return result
def parse_repo_paths(values: tuple[str, ...]) -> dict[str, Path]:
result: dict[str, Path] = {}
for value in values:
if "=" not in value:
raise SystemExit(f"--python-artifact must use REPO=/path/to/wheel: {value}")
repo, path_text = value.split("=", 1)
repo = repo.strip()
path_text = path_text.strip()
if not repo or not path_text or repo in result:
raise SystemExit(f"--python-artifact must uniquely use REPO=/path/to/wheel: {value}")
result[repo] = Path(path_text).expanduser()
return result
def print_text_summary(payload: dict[str, object]) -> None:
print("Selective catalog candidate")
for key in (