95 lines
4.1 KiB
Python
95 lines
4.1 KiB
Python
"""ORCH-036 TC-14: prod deploy is build-ONCE — retag the staging image, no rebuild (AC-7).
|
|
|
|
The detached prod-deploy command must pass ``SOURCE_IMAGE=<staging-image>`` to the
|
|
hook so it retags the staging-validated image onto the prod tag instead of running
|
|
``docker build``. We assert the composed ssh command carries the staging source
|
|
image and never asks the hook to build.
|
|
"""
|
|
|
|
import os
|
|
|
|
os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token")
|
|
os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token")
|
|
|
|
from src import self_deploy # noqa: E402
|
|
|
|
|
|
def test_tc14_deploy_command_retags_staging_image_no_build(monkeypatch):
|
|
monkeypatch.setattr(self_deploy.settings, "deploy_ssh_user", "slin")
|
|
monkeypatch.setattr(self_deploy.settings, "deploy_ssh_host", "mva154")
|
|
monkeypatch.setattr(
|
|
self_deploy.settings, "deploy_prod_source_image", "orchestrator-orchestrator-staging"
|
|
)
|
|
|
|
cmd = self_deploy.build_deploy_command("orchestrator", "ORCH-036", "feature/ORCH-036-x")
|
|
remote = cmd[-1]
|
|
|
|
# The prevalidated staging image is handed to the hook as SOURCE_IMAGE (build-once).
|
|
assert "SOURCE_IMAGE=orchestrator-orchestrator-staging" in remote
|
|
# No rebuild is requested in the remote command.
|
|
assert "docker build" not in remote
|
|
assert "--build" not in remote
|
|
|
|
|
|
def test_tc14_hook_retag_branch_present():
|
|
"""The hook itself must honour SOURCE_IMAGE by retagging (no rebuild)."""
|
|
import pathlib
|
|
hook = pathlib.Path(__file__).resolve().parents[1] / "scripts" / "orchestrator-deploy-hook.sh"
|
|
text = hook.read_text(encoding="utf-8")
|
|
assert 'SOURCE_IMAGE="${SOURCE_IMAGE:-}"' in text
|
|
# Build-once retag branch present; the hook never runs `docker build`.
|
|
assert 'docker tag "$SOURCE_IMAGE" "$TARGET_IMAGE"' in text
|
|
# No EXECUTABLE `docker build` line on the PROD path (comments are fine).
|
|
# ORCH-058: the only build allowed is the staging-freshness rebuild,
|
|
# which is explicitly tagged with `--build-arg GIT_SHA` (Strategy A).
|
|
# Executable lines only: drop comments and `log "..."` strings that merely
|
|
# mention "docker build" in human-readable diagnostics.
|
|
exec_lines = [
|
|
ln.strip() for ln in text.splitlines()
|
|
if ln.strip()
|
|
and not ln.strip().startswith("#")
|
|
and not ln.strip().startswith("log ")
|
|
]
|
|
for ln in exec_lines:
|
|
if "docker build" in ln:
|
|
assert "--build-arg GIT_SHA" in ln, (
|
|
f"unexpected docker build on prod retag path: {ln}"
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ORCH-058 TC-06: build_deploy_command threads EXPECTED_REVISION (Strategy B)
|
|
# ---------------------------------------------------------------------------
|
|
def test_tc06_deploy_command_passes_expected_revision(monkeypatch):
|
|
"""When image-freshness is active, the prod hook receives EXPECTED_REVISION."""
|
|
from src import image_freshness
|
|
monkeypatch.setattr(self_deploy.settings, "deploy_ssh_user", "slin")
|
|
monkeypatch.setattr(self_deploy.settings, "deploy_ssh_host", "mva154")
|
|
monkeypatch.setattr(
|
|
self_deploy.settings, "deploy_prod_source_image", "orchestrator-orchestrator-staging"
|
|
)
|
|
monkeypatch.setattr(
|
|
image_freshness, "expected_revision", lambda repo, branch: "abc123def456"
|
|
)
|
|
|
|
cmd = self_deploy.build_deploy_command("orchestrator", "ORCH-058", "feature/ORCH-058-x")
|
|
remote = cmd[-1]
|
|
|
|
assert "EXPECTED_REVISION=abc123def456" in remote
|
|
|
|
|
|
def test_tc06_no_expected_revision_when_inactive(monkeypatch):
|
|
"""When image-freshness resolves to no SHA, EXPECTED_REVISION is omitted."""
|
|
from src import image_freshness
|
|
monkeypatch.setattr(self_deploy.settings, "deploy_ssh_user", "slin")
|
|
monkeypatch.setattr(self_deploy.settings, "deploy_ssh_host", "mva154")
|
|
monkeypatch.setattr(
|
|
self_deploy.settings, "deploy_prod_source_image", "orchestrator-orchestrator-staging"
|
|
)
|
|
monkeypatch.setattr(image_freshness, "expected_revision", lambda repo, branch: "")
|
|
|
|
cmd = self_deploy.build_deploy_command("orchestrator", "ORCH-058", "feature/ORCH-058-x")
|
|
remote = cmd[-1]
|
|
|
|
assert "EXPECTED_REVISION=" not in remote
|