Use coordinated docs port with conflict checks and deployment-independent cache keys
Verify and deploy Tabularium / verify-and-deploy (push) Successful in 4m6s

This commit is contained in:
2026-10-26 20:20:50 +08:00
parent 4a98b84aad
commit 585c602000
9 changed files with 70 additions and 12 deletions
+23 -2
View File
@@ -5,6 +5,7 @@ import os
from pathlib import Path
import re
import shutil
import socket
import subprocess
import urllib.request
from ci import APP, ROOT, fingerprint, run
@@ -29,6 +30,25 @@ def compose(release: Path, *args: str) -> None:
"--env-file", str(release / "release.env"), "-f", str(release / "compose.yml"), *args)
def check_port(port: int) -> None:
# An existing container belonging to this Compose service may retain its port.
own = run("docker", "ps", "-q", "--filter", f"label=com.docker.compose.project={APP}",
"--filter", "label=com.docker.compose.service=docs", capture=True)
if own:
for container in own.splitlines():
details = json.loads(run("docker", "inspect", container, capture=True))[0]
ports = details["NetworkSettings"]["Ports"].get("3000/tcp") or []
if any(item["HostPort"] == str(port) for item in ports):
print(f"Port {port} belongs to the current Tabularium service", flush=True)
return
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as probe:
try:
probe.bind(("0.0.0.0", port))
except OSError as error:
raise RuntimeError(f"Port {port} is already occupied; no service was changed") from error
print(f"Port {port} is available", flush=True)
def main() -> None:
if os.geteuid() != 0:
raise RuntimeError("Deployment requires root on ces-control")
@@ -48,13 +68,14 @@ def main() -> None:
run("docker", "image", "inspect", actual, capture=True)
CONFIG.parent.mkdir(parents=True, exist_ok=True)
if not CONFIG.exists():
CONFIG.write_text("TABULARIUM_BIND=0.0.0.0\nTABULARIUM_PORT=18132\n")
CONFIG.write_text("TABULARIUM_BIND=0.0.0.0\nTABULARIUM_PORT=18135\n")
CONFIG.chmod(0o600)
settings = dict(line.split("=", 1) for line in CONFIG.read_text().splitlines()
if line and not line.startswith("#"))
port = int(settings.get("TABULARIUM_PORT", "18132"))
port = int(settings.get("TABULARIUM_PORT", "18135"))
if not 1024 <= port <= 65535:
raise ValueError("Invalid port")
check_port(port)
current = DEPLOY_ROOT / "current"
previous = current.resolve() if current.is_symlink() else None
release = DEPLOY_ROOT / "releases" / sha