let s = import "reflection/schema.ncl" in { id = "deploy_vapora_service", trigger = "manual | NATS:ecosystem.provisioning.ready", preconditions = [ "Provisioning scaffold complete (provisioning.ready event received)", "async-first: no blocking calls in deployment scripts", "budget-boundary: deployment cost within approved limits", ], steps = [ { id = "validate_ontology", action = "Validate vapora ontology coherence before deployment", cmd = "nu {stratumiops_dir}/scripts/ontology-validate.nu {vapora_dir}/.ontology", actor = 'Agent, on_error = { strategy = 'Stop }, depends_on = [], }, { id = "build_release", action = "Build vapora-backend in release mode", cmd = "cargo build --release -p vapora-backend 2>&1", actor = 'Agent, on_error = { strategy = 'Stop }, depends_on = [{ step = "validate_ontology", kind = 'OnSuccess }], }, { id = "run_tests", action = "Run workspace tests before deploy", cmd = "cargo test --workspace --all-features 2>&1", actor = 'Agent, on_error = { strategy = 'Stop }, depends_on = [{ step = "build_release", kind = 'OnSuccess }], }, { id = "build_docker", action = "Build and tag the Docker image for this service version", cmd = "docker build -f {vapora_dir}/docker/{service_name}.Dockerfile -t vapora/{service_name}:{version} {vapora_dir}", actor = 'Agent, on_error = { strategy = 'Stop }, depends_on = [{ step = "run_tests", kind = 'OnSuccess }], }, { id = "push_image", action = "Push Docker image to registry", cmd = "docker push vapora/{service_name}:{version}", actor = 'Agent, on_error = { strategy = 'Stop }, depends_on = [{ step = "build_docker", kind = 'OnSuccess }], }, { id = "apply_kubernetes", action = "Apply Kubernetes manifests for the service", cmd = "kubectl apply -f {vapora_dir}/kubernetes/{service_name}/ --context {k8s_context}", actor = 'Agent, on_error = { strategy = 'Stop }, depends_on = [{ step = "push_image", kind = 'OnSuccess }], }, { id = "verify_rollout", action = "Wait for rollout to complete and verify pod health", cmd = "kubectl rollout status deployment/{service_name} --context {k8s_context} --timeout=300s", actor = 'Agent, on_error = { strategy = 'Retry }, depends_on = [{ step = "apply_kubernetes", kind = 'OnSuccess }], }, { id = "notify_ecosystem", action = "Publish project-state-changed event to ecosystem NATS", cmd = "nu {stratumiops_dir}/scripts/nats-publish.nu project-created --project_name {service_name} --project_dir {vapora_dir} --stack rust-tokio --type service", actor = 'Agent, on_error = { strategy = 'Continue }, depends_on = [{ step = "verify_rollout", kind = 'OnSuccess }], }, ], postconditions = [ "Service pods are Running in the target Kubernetes cluster", "Deployment visible in ecosystem NATS as project.created event", "Budget ledger updated with deployment compute cost", ], } | (s.Mode String)