fix(cicd): wire hwlab branch-follower health gate

This commit is contained in:
Codex
2026-07-04 05:15:17 +00:00
parent 94ea900e4a
commit a111d9195d
2 changed files with 28 additions and 2 deletions
+15 -1
View File
@@ -186,12 +186,26 @@ async function runtimeSummary(expected) {
async function healthSummary() {
if (!healthUrl) return { ok: null, reason: "health-url-not-configured" };
const targets = [`${healthUrl.replace(/\/+$/u, "")}/health/readiness`, `${healthUrl.replace(/\/+$/u, "")}/health/live`];
const targets = healthProbeTargets(healthUrl);
const probes = [];
for (const url of targets) probes.push(await httpProbe(url));
return { ok: probes.every((probe) => probe.ok), probes };
}
function healthProbeTargets(value) {
const trimmed = value.replace(/\/+$/u, "");
try {
const parsed = new URL(trimmed);
const pathname = parsed.pathname.replace(/\/+$/u, "");
if (pathname.endsWith("/health") || pathname.endsWith("/api/health") || pathname.endsWith("/health/readiness") || pathname.endsWith("/health/live")) {
return [trimmed];
}
} catch {
// Fall back to the historical base-url contract when HEALTH_URL is not a full URL.
}
return [`${trimmed}/health/readiness`, `${trimmed}/health/live`];
}
function workloadSummary(spec, item, expected) {
const status = item?.status || {};
const desired = item?.spec?.replicas ?? 1;
+13 -1
View File
@@ -5,6 +5,7 @@ import { resolveAgentRunLaneTarget } from "./agentrun-lanes";
import { nativeCicdScriptLoadShell } from "./cicd-native-bundle";
import { waitForJobShell } from "./cicd-controller-render";
import type { BranchFollowerRegistry, FollowerSpec, ParsedOptions } from "./cicd-types";
import { hwlabRuntimeLaneSpecForNode } from "./hwlab-node-lanes";
import { shQuote, redactText } from "./platform-infra-ops-library";
type KubeScriptRunner = (registry: BranchFollowerRegistry, options: ParsedOptions, script: string, input: string, timeoutMs: number) => CommandResult;
@@ -54,7 +55,7 @@ function gateJobManifest(registry: BranchFollowerRegistry, follower: FollowerSpe
const labels = { ...registry.controller.labels, "app.kubernetes.io/component": "cicd-gate-job" };
const agentrun = follower.adapter === "agentrun-yaml-lane" ? resolveAgentRunLaneTarget({ node: follower.target.node, lane: follower.target.lane }).spec : null;
const gitopsBranch = agentrun?.gitops.branch ?? "";
const healthUrl = agentrun?.runtime.internalBaseUrl ?? "";
const healthUrl = gateHealthUrl(follower);
const workloads = (follower.nativeStatus.runtime?.workloads ?? []).map((item) => ({ kind: item.kind, name: item.name, sourceCommit: item.sourceCommit }));
const gatePolicy = gatePolicyEnv(follower);
const gateScript = [
@@ -122,6 +123,17 @@ function gateJobManifest(registry: BranchFollowerRegistry, follower: FollowerSpe
};
}
function gateHealthUrl(follower: FollowerSpec): string {
if (follower.adapter === "agentrun-yaml-lane") {
return resolveAgentRunLaneTarget({ node: follower.target.node, lane: follower.target.lane }).spec.runtime.internalBaseUrl;
}
if (follower.adapter === "hwlab-node-runtime") {
const spec = hwlabRuntimeLaneSpecForNode(follower.target.lane, follower.target.node);
return `${spec.publicApiUrl.replace(/\/+$/u, "")}/health`;
}
return "";
}
function gatePolicyEnv(follower: FollowerSpec): { slowTaskSeconds: number; healthTimeoutMs: number } {
if (follower.drillDown === null) {
throw new Error(`follower ${follower.id} registry is missing drillDown policy`);