Files
JWeBot/tools/activate-release.py
T

93 lines
2.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""Install and atomically activate one verified extension release."""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path[:0] = [
str(ROOT / "packages" / "jwebot-sdk" / "src"),
str(ROOT / "packages" / "jwebot-kernel" / "src"),
]
from jwebot_kernel import ( # noqa: E402
ActivationError,
ExtensionHostClient,
ReleaseError,
install_release,
)
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("artifact", type=Path)
parser.add_argument("release", type=Path)
parser.add_argument("--state-root", type=Path, required=True)
parser.add_argument("--signature", type=Path)
parser.add_argument("--allowed-signers", type=Path)
parser.add_argument("--publisher")
parser.add_argument("--allow-unsigned-local", action="store_true")
parser.add_argument("--skip-health-check-local", action="store_true")
args = parser.parse_args()
if args.allow_unsigned_local:
if any(
value is not None
for value in (
args.signature,
args.allowed_signers,
args.publisher,
)
):
parser.error(
"--allow-unsigned-local cannot include signature options"
)
elif args.signature is None or args.allowed_signers is None:
parser.error(
"signed activation requires --signature and --allowed-signers"
)
health_check = None
if not args.allow_unsigned_local and not args.skip_health_check_local:
client = ExtensionHostClient(
allowed_signers=args.allowed_signers,
expected_publisher=args.publisher,
)
health_check = lambda release_dir: client.invoke(
release_dir,
{"op": "health"},
)
try:
destination = install_release(
args.artifact,
args.release,
args.state_root,
signature=args.signature,
allowed_signers=args.allowed_signers,
expected_publisher=args.publisher,
allow_unsigned=args.allow_unsigned_local,
health_check=health_check,
allow_unhealthy_local=args.skip_health_check_local,
)
except (ActivationError, ReleaseError) as error:
parser.error(str(error))
print(
json.dumps(
{
"activated": True,
"release_dir": str(destination),
"current": str(args.state_root / "current"),
},
ensure_ascii=False,
sort_keys=True,
)
)
return 0
if __name__ == "__main__":
raise SystemExit(main())