Publish curated ITWorx-ModelForge source from 990401737f96c8d46a9f7b0d84994516cadcb6a0

This commit is contained in:
Public Source Publisher committed 2026-09-30 09:23:17 +00:00
1 parent 7082ab955a
commit 848f0d8f8a
434 files changed
+67298 -4315

No files matched your search

+174 -102
View File
@@ -9,14 +9,16 @@ import json
import os
import secrets
import shutil
import signal
import subprocess
import sys
import time
from collections.abc import Iterator
from contextlib import contextmanager
from datetime import UTC, datetime
from pathlib import Path
from urllib.parse import urlparse
ROOT = Path(__file__).resolve().parents[1]
IMAGES = (
"modelforge-api",
@@ -24,11 +26,36 @@ IMAGES = (
"modelforge-node-agent",
"modelforge-runtime-worker",
)
ACCEPTANCE_SERVICES = ("postgres", "redis", "api", "migrate", "web")
CONFIG_SEED_IMAGE = (
"redis:7-alpine@sha256:ff02b58f971e7d7d156a1267e283fcbbeee91773b6aa36c49dac28ecfe28eadf"
)
def write_acceptance_compose_override(path: Path) -> None:
"""Write the disposable RC service policy used by acceptance."""
services = []
for service in ACCEPTANCE_SERVICES:
services.append(f' {service}:\n restart: "no"\n')
if service == "api":
services.append(
" volumes:\n"
" - type: volume\n"
" source: acceptance-config\n"
" target: /app/config\n"
" read_only: true\n"
)
path.write_text(
"services:\n"
f"{''.join(services)}"
"volumes:\n"
" acceptance-config:\n",
encoding="utf-8",
newline="\n",
)
def run(
*args: str,
cwd: Path = ROOT,
@@ -197,12 +224,57 @@ def cleanup_candidate_images(version: str, commit: str) -> None:
run("docker", "image", "rm", "--force", tag, check=False)
def _terminate_after_cleanup(signum: int, _frame: object) -> None:
raise SystemExit(128 + signum)
@contextmanager
def managed_compose_cleanup(
compose: tuple[str, ...], env: dict[str, str]
) -> Iterator[None]:
"""Remove the disposable project on normal, failed, or interrupted exits."""
def cleanup() -> None:
run(*compose, "down", "--volumes", "--remove-orphans", env=env, check=False)
atexit.register(cleanup)
previous_handlers = {
signum: signal.signal(signum, _terminate_after_cleanup)
for signum in (signal.SIGINT, signal.SIGTERM)
}
try:
yield
finally:
cleanup_complete = False
try:
cleanup()
cleanup_complete = True
finally:
if cleanup_complete:
atexit.unregister(cleanup)
for signum, handler in previous_handlers.items():
signal.signal(signum, handler)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--public-api-origin", required=True)
parser.add_argument("--output", type=Path, default=Path("acceptance-evidence"))
parser.add_argument("--trivy", default="trivy")
parser.add_argument("--project-suffix", default=os.environ.get("GITHUB_RUN_ID", "manual"))
parser.add_argument(
"--canonical-source-commit",
default=None,
help=(
"exact canonical source SHA for a parentless public export; release labels are bound "
"to it only when PUBLIC_SOURCE_MANIFEST.json proves the mapping"
),
)
parser.add_argument(
"--retain-image-bundle",
action="store_true",
help="retain the verified four-image Docker transport bundle in the output directory",
)
args = parser.parse_args()
origin = args.public_api_origin.rstrip("/")
@@ -217,25 +289,35 @@ def main() -> int:
commit = run("git", "rev-parse", "HEAD", capture=True)
if run("git", "status", "--porcelain", capture=True):
raise SystemExit("Acceptance must run from a clean, exact source commit")
canonical_commit = args.canonical_source_commit or commit
if len(canonical_commit) != 40 or any(
character not in "0123456789abcdef" for character in canonical_commit
):
raise SystemExit("--canonical-source-commit must be an exact lowercase 40-character SHA")
version = (ROOT / "VERSION").read_text(encoding="utf-8").strip()
atexit.register(cleanup_candidate_images, version, commit)
atexit.register(cleanup_candidate_images, version, canonical_commit)
built_at = datetime.now(UTC).isoformat()
output = args.output.resolve()
output.mkdir(parents=True, exist_ok=True)
project_suffix = "".join(ch for ch in args.project_suffix.lower() if ch.isalnum())[-24:]
project = f"modelforge-rc-{project_suffix or secrets.token_hex(6)}"
if not project.startswith("modelforge-rc-"):
raise SystemExit("refusing a non-RC Compose project name")
project = f"modelforge-validation-{project_suffix or secrets.token_hex(6)}"
if not project.startswith("modelforge-validation-"):
raise SystemExit("refusing a non-validation Compose project name")
run(
release_command = [
sys.executable,
str(ROOT / "scripts" / "release_build.py"),
"--output",
str(output / "release"),
"--public-api-origin",
origin,
)
]
if args.canonical_source_commit is not None:
release_command.extend(("--canonical-source-commit", canonical_commit))
if args.retain_image_bundle:
release_command.append("--image-bundle")
run(*release_command)
image_records: list[dict[str, str]] = []
for image in IMAGES:
@@ -275,13 +357,13 @@ def main() -> int:
runtime_password = secrets.token_hex(24)
operator_key = secrets.token_urlsafe(48)
backup_key = base64.urlsafe_b64encode(secrets.token_bytes(32)).decode("ascii")
database = "modelforge_rc"
database = "modelforge_validation"
env = os.environ.copy()
env.update(
{
"COMPOSE_PROJECT_NAME": project,
"MODELFORGE_VERSION": version,
"MODELFORGE_COMMIT": commit,
"MODELFORGE_COMMIT": canonical_commit,
"MODELFORGE_BUILT_AT": built_at,
"MODELFORGE_API_IMAGE": f"modelforge-api:{version}",
"MODELFORGE_WEB_IMAGE": f"modelforge-web:{version}",
@@ -301,8 +383,8 @@ def main() -> int:
"MODELFORGE_BACKUP_ENCRYPTION_KEY": backup_key,
"MODELFORGE_CORS_ORIGINS": origin,
"VITE_API_BASE_URL": origin,
"MODELFORGE_SOURCE_COMMIT": commit,
"MODELFORGE_SOURCE_REFERENCE": "rc-acceptance",
"MODELFORGE_SOURCE_COMMIT": canonical_commit,
"MODELFORGE_SOURCE_REFERENCE": "validation-acceptance",
"MODELFORGE_SOURCE_REPOSITORY": "public-source-candidate",
"MODELFORGE_API_BIND": "127.0.0.1",
"MODELFORGE_API_PUBLISHED_PORT": "0",
@@ -317,19 +399,7 @@ def main() -> int:
}
)
acceptance_override = output / "acceptance-compose.override.yml"
acceptance_override.write_text(
"services:\n"
" api:\n"
" volumes:\n"
" - type: volume\n"
" source: acceptance-config\n"
" target: /app/config\n"
" read_only: true\n"
"volumes:\n"
" acceptance-config:\n",
encoding="utf-8",
newline="\n",
)
write_acceptance_compose_override(acceptance_override)
compose = (
"docker",
"compose",
@@ -346,95 +416,97 @@ def main() -> int:
summary: dict[str, object] = {
"schema_version": 1,
"project": project,
"source_commit": commit,
"source_commit": canonical_commit,
"build_tree_commit": commit,
"version": version,
"public_api_origin": origin,
"image_bundle_retained": args.retain_image_bundle,
"production_changed": False,
"compute_identity_created": False,
"images": image_records,
"checks": {},
}
try:
run(*compose, "config", "-q", env=env)
run(*compose, "up", "-d", "--no-build", "--wait", "postgres", "redis", env=env)
provision_database_roles(compose, env, database)
provision_config_volume(project)
run(*compose, "up", "-d", "--no-build", "--wait", "api", "web", env=env)
api_container = run(*compose, "ps", "--quiet", "api", env=env, capture=True)
if not api_container:
raise RuntimeError("acceptance API container was not created")
api = "http://127.0.0.1:8000"
with managed_compose_cleanup(compose, env):
try:
run(*compose, "config", "-q", env=env)
run(*compose, "up", "-d", "--no-build", "--wait", "postgres", "redis", env=env)
provision_database_roles(compose, env, database)
provision_config_volume(project)
run(*compose, "up", "-d", "--no-build", "--wait", "api", "web", env=env)
api_container = run(*compose, "ps", "--quiet", "api", env=env, capture=True)
if not api_container:
raise RuntimeError("acceptance API container was not created")
api = "http://127.0.0.1:8000"
wait_for_container_status(api_container, f"{api}/api/v1/health/live", 200)
wait_for_container_status(api_container, f"{api}/api/v1/health/ready", 200)
version_status, version_body = container_http_status(
api_container, f"{api}/api/v1/version"
)
unauthenticated, _ = container_http_status(
api_container, f"{api}/api/v1/admin/recovery/dashboard"
)
authenticated, _ = container_http_status(
api_container,
f"{api}/api/v1/admin/recovery/dashboard",
operator=True,
)
wait_for_container_status(api_container, "http://web:3000/", 200)
if version_status != 200 or unauthenticated != 401 or authenticated != 200:
raise RuntimeError(
"acceptance boundary mismatch: "
f"version={version_status}, unauthenticated={unauthenticated}, "
f"authenticated={authenticated}"
wait_for_container_status(api_container, f"{api}/api/v1/health/live", 200)
wait_for_container_status(api_container, f"{api}/api/v1/health/ready", 200)
version_status, version_body = container_http_status(
api_container, f"{api}/api/v1/version"
)
version_payload = json.loads(version_body)
if version_payload.get("version") != version:
raise RuntimeError(f"running version does not match {version}: {version_payload}")
unauthenticated, _ = container_http_status(
api_container, f"{api}/api/v1/admin/recovery/dashboard"
)
authenticated, _ = container_http_status(
api_container,
f"{api}/api/v1/admin/recovery/dashboard",
operator=True,
)
wait_for_container_status(api_container, "http://web:3000/", 200)
if version_status != 200 or unauthenticated != 401 or authenticated != 200:
raise RuntimeError(
"acceptance boundary mismatch: "
f"version={version_status}, unauthenticated={unauthenticated}, "
f"authenticated={authenticated}"
)
version_payload = json.loads(version_body)
if version_payload.get("version") != version:
raise RuntimeError(f"running version does not match {version}: {version_payload}")
volumes = run(
"docker",
"volume",
"ls",
"--filter",
f"label=com.docker.compose.project={project}",
"--format",
"{{.Name}}",
capture=True,
).splitlines()
if not volumes or any(not volume.startswith(f"{project}_") for volume in volumes):
raise RuntimeError(f"Compose volumes are not isolated under {project}: {volumes}")
summary["checks"] = {
"live": 200,
"ready": 200,
"version": version_status,
"admin_without_key": unauthenticated,
"admin_with_key": authenticated,
"console": 200,
"database_roles_provisioned": True,
"network_probe_container": "api",
"isolated_volumes": sorted(volumes),
}
summary["result"] = "PASS"
(output / "compose-ps.json").write_text(
run(*compose, "ps", "--format", "json", env=env, capture=True) + "\n",
encoding="utf-8",
newline="\n",
)
except Exception:
summary["result"] = "FAIL"
(output / "compose-logs.txt").write_text(
run(*compose, "logs", "--no-color", env=env, check=False, capture=True) + "\n",
encoding="utf-8",
newline="\n",
)
raise
finally:
run(*compose, "down", "--volumes", "--remove-orphans", env=env, check=False)
(output / "acceptance-summary.json").write_text(
json.dumps(summary, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
newline="\n",
)
volumes = run(
"docker",
"volume",
"ls",
"--filter",
f"label=com.docker.compose.project={project}",
"--format",
"{{.Name}}",
capture=True,
).splitlines()
if not volumes or any(not volume.startswith(f"{project}_") for volume in volumes):
raise RuntimeError(f"Compose volumes are not isolated under {project}: {volumes}")
summary["checks"] = {
"live": 200,
"ready": 200,
"version": version_status,
"admin_without_key": unauthenticated,
"admin_with_key": authenticated,
"console": 200,
"database_roles_provisioned": True,
"network_probe_container": "api",
"isolated_volumes": sorted(volumes),
}
summary["result"] = "PASS"
(output / "compose-ps.json").write_text(
run(*compose, "ps", "--format", "json", env=env, capture=True) + "\n",
encoding="utf-8",
newline="\n",
)
except BaseException:
summary["result"] = "FAIL"
(output / "compose-logs.txt").write_text(
run(*compose, "logs", "--no-color", env=env, check=False, capture=True) + "\n",
encoding="utf-8",
newline="\n",
)
raise
finally:
(output / "acceptance-summary.json").write_text(
json.dumps(summary, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
newline="\n",
)
print(f"Isolated RC acceptance PASS for {commit} in {project}")
print(f"Isolated RC acceptance PASS for {canonical_commit} in {project}")
return 0