import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] class DeploymentContractTest(unittest.TestCase): def test_workflow_targets_only_olons_server(self): workflow = (ROOT / ".gitea/workflows/deploy.yml").read_text() self.assertIn("Deploy olons-server production", workflow) self.assertIn("git.olns.shop/pro/olons_server", workflow) self.assertIn("docker compose pull olons-server", workflow) self.assertIn("docker compose up -d --no-deps --wait olons-server", workflow) self.assertNotIn("im-workbench", workflow) self.assertNotIn("workbench-system", workflow) def test_dockerfile_builds_frontend_into_backend_image(self): dockerfile = (ROOT / "Dockerfile").read_text() self.assertIn("RUN pnpm run build", dockerfile) self.assertIn("ENV VITE_PUBLIC_PATH=/", dockerfile) self.assertNotIn("VITE_PUBLIC_PATH=/admin/", dockerfile) self.assertIn("COPY --from=web-builder /web/dist ./web/dist", dockerfile) self.assertIn("COPY --from=web-builder /web/dist /app/web/dist", dockerfile) self.assertIn("EXPOSE 6061", dockerfile) def test_runtime_image_includes_timezone_database_for_mysql_dsn(self): dockerfile = (ROOT / "Dockerfile").read_text() self.assertIn("RUN apk add --no-cache tzdata", dockerfile) def test_docker_context_excludes_local_artifacts(self): entries = { line.strip() for line in (ROOT / ".dockerignore").read_text().splitlines() if line.strip() and not line.lstrip().startswith("#") } for required in {".git", "web/node_modules", "web/dist", "*.log"}: self.assertIn(required, entries) if __name__ == "__main__": unittest.main()