fix(cicd): 使用最小联通就绪门禁
This commit is contained in:
+11
-11
@@ -587,7 +587,7 @@ lanes:
|
|||||||
runtimeKind: go-service
|
runtimeKind: go-service
|
||||||
entrypoint: cmd/hwlab-workbench-runtime/main.go
|
entrypoint: cmd/hwlab-workbench-runtime/main.go
|
||||||
artifactKind: go-service
|
artifactKind: go-service
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6671
|
healthPort: 6671
|
||||||
healthProbe:
|
healthProbe:
|
||||||
readiness:
|
readiness:
|
||||||
@@ -612,7 +612,7 @@ lanes:
|
|||||||
runtimeKind: go-service
|
runtimeKind: go-service
|
||||||
entrypoint: cmd/hwlab-user-billing/main.go
|
entrypoint: cmd/hwlab-user-billing/main.go
|
||||||
artifactKind: go-service
|
artifactKind: go-service
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6670
|
healthPort: 6670
|
||||||
healthProbe:
|
healthProbe:
|
||||||
readiness:
|
readiness:
|
||||||
@@ -637,7 +637,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-project-management/main.ts
|
entrypoint: cmd/hwlab-project-management/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6672
|
healthPort: 6672
|
||||||
healthProbe:
|
healthProbe:
|
||||||
readiness:
|
readiness:
|
||||||
@@ -661,7 +661,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-tasktree-api/main.ts
|
entrypoint: cmd/hwlab-tasktree-api/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6673
|
healthPort: 6673
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-tasktree-api/
|
- cmd/hwlab-tasktree-api/
|
||||||
@@ -677,7 +677,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-tasktree-worker/main.ts
|
entrypoint: cmd/hwlab-tasktree-worker/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6674
|
healthPort: 6674
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-tasktree-worker/
|
- cmd/hwlab-tasktree-worker/
|
||||||
@@ -692,7 +692,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-harnessrl-api/main.ts
|
entrypoint: cmd/hwlab-harnessrl-api/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /readyz
|
healthPath: /health/live
|
||||||
healthPort: 6675
|
healthPort: 6675
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-harnessrl-api/
|
- cmd/hwlab-harnessrl-api/
|
||||||
@@ -708,7 +708,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-harnessrl-worker/main.ts
|
entrypoint: cmd/hwlab-harnessrl-worker/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /readyz
|
healthPath: /health/live
|
||||||
healthPort: 6676
|
healthPort: 6676
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-harnessrl-worker/
|
- cmd/hwlab-harnessrl-worker/
|
||||||
@@ -725,7 +725,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-workbench-api/main.ts
|
entrypoint: cmd/hwlab-workbench-api/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6677
|
healthPort: 6677
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-workbench-api/
|
- cmd/hwlab-workbench-api/
|
||||||
@@ -743,7 +743,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-workbench-worker/main.ts
|
entrypoint: cmd/hwlab-workbench-worker/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6678
|
healthPort: 6678
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-workbench-worker/
|
- cmd/hwlab-workbench-worker/
|
||||||
@@ -759,7 +759,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-hwpod-api/main.ts
|
entrypoint: cmd/hwlab-hwpod-api/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6681
|
healthPort: 6681
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-hwpod-api/
|
- cmd/hwlab-hwpod-api/
|
||||||
@@ -775,7 +775,7 @@ lanes:
|
|||||||
runtimeKind: bun-command
|
runtimeKind: bun-command
|
||||||
entrypoint: cmd/hwlab-hwpod-worker/main.ts
|
entrypoint: cmd/hwlab-hwpod-worker/main.ts
|
||||||
artifactKind: bun-command
|
artifactKind: bun-command
|
||||||
healthPath: /health/ready
|
healthPath: /health/live
|
||||||
healthPort: 6682
|
healthPort: 6682
|
||||||
componentPaths:
|
componentPaths:
|
||||||
- cmd/hwlab-hwpod-worker/
|
- cmd/hwlab-hwpod-worker/
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ function requiredEnv(name) {
|
|||||||
const revision = requiredEnv("HWLAB_SOURCE_REVISION");
|
const revision = requiredEnv("HWLAB_SOURCE_REVISION");
|
||||||
const runtimeNamespace = requiredEnv("HWLAB_RUNTIME_NAMESPACE");
|
const runtimeNamespace = requiredEnv("HWLAB_RUNTIME_NAMESPACE");
|
||||||
const gitopsTarget = requiredEnv("HWLAB_GITOPS_TARGET");
|
const gitopsTarget = requiredEnv("HWLAB_GITOPS_TARGET");
|
||||||
const argoApplication = requiredEnv("HWLAB_ARGO_APPLICATION");
|
|
||||||
const pipelineRun = process.env.HWLAB_TEKTON_PIPELINERUN || null;
|
const pipelineRun = process.env.HWLAB_TEKTON_PIPELINERUN || null;
|
||||||
const taskRun = process.env.HWLAB_TEKTON_TASKRUN || null;
|
const taskRun = process.env.HWLAB_TEKTON_TASKRUN || null;
|
||||||
const task = process.env.HWLAB_TEKTON_TASK || null;
|
const task = process.env.HWLAB_TEKTON_TASK || null;
|
||||||
@@ -161,35 +160,6 @@ function maybeEmitProgress(state, stage, stageStartedAt, payload) {
|
|||||||
emit({ stage, status: "progress", durationMs: now - stageStartedAt, readinessMode, ...payload });
|
emit({ stage, status: "progress", durationMs: now - stageStartedAt, readinessMode, ...payload });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function argoApplicationState() {
|
|
||||||
const path = "/apis/argoproj.io/v1alpha1/namespaces/argocd/applications/" + encodeURIComponent(argoApplication);
|
|
||||||
const response = await request("GET", path);
|
|
||||||
if (response.statusCode === 403) return { status: "rbac-denied", item: null, statusCode: response.statusCode };
|
|
||||||
if (response.statusCode < 200 || response.statusCode > 299) return { status: "error", item: null, statusCode: response.statusCode, body: response.body.slice(0, 500) };
|
|
||||||
return { status: "ok", item: response.json, statusCode: response.statusCode };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function waitForArgoSyncedHealthy() {
|
|
||||||
const stageStartedAt = Date.now();
|
|
||||||
const progressState = { lastProgressAt: 0 };
|
|
||||||
while (Date.now() < deadline) {
|
|
||||||
const application = await argoApplicationState();
|
|
||||||
if (application.status === "rbac-denied") return fail("argo-sync-health", "argocd-application-rbac-denied", stageStartedAt, { readinessMode });
|
|
||||||
if (application.status !== "ok") return fail("argo-sync-health", "argocd-application-read-failed", stageStartedAt, { readinessMode, statusCode: application.statusCode, body: application.body || null });
|
|
||||||
const syncStatus = application.item?.status?.sync?.status || null;
|
|
||||||
const healthStatus = application.item?.status?.health?.status || null;
|
|
||||||
const operationPhase = application.item?.status?.operationState?.phase || null;
|
|
||||||
const operationMessage = application.item?.status?.operationState?.message || null;
|
|
||||||
if (syncStatus === "Synced" && healthStatus === "Healthy") {
|
|
||||||
emit({ stage: "argo-sync-health", status: "succeeded", durationMs: Date.now() - stageStartedAt, readinessMode, syncStatus, healthStatus, operationPhase });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
maybeEmitProgress(progressState, "argo-sync-health", stageStartedAt, { syncStatus, healthStatus, operationPhase, operationMessage });
|
|
||||||
await sleep(Math.min(pollMs, Math.max(0, deadline - Date.now())));
|
|
||||||
}
|
|
||||||
return fail("argo-sync-health", "runtime-ready-wall-clock-timeout", stageStartedAt, { readinessMode }, "timeout");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function waitForArgoRefresh() {
|
async function waitForArgoRefresh() {
|
||||||
const stageStartedAt = Date.now();
|
const stageStartedAt = Date.now();
|
||||||
const progressState = { lastProgressAt: 0 };
|
const progressState = { lastProgressAt: 0 };
|
||||||
@@ -236,9 +206,7 @@ function fail(stage, reason, stageStartedAt, extra = {}, status = "failed") {
|
|||||||
|
|
||||||
emit({ stage: "runtime-ready", status: "started", readinessMode, observedServiceCount: observedServiceIds ? observedServiceIds.size : 0, timeoutMs });
|
emit({ stage: "runtime-ready", status: "started", readinessMode, observedServiceCount: observedServiceIds ? observedServiceIds.size : 0, timeoutMs });
|
||||||
try {
|
try {
|
||||||
if (!observedServiceIds) {
|
if (await waitForArgoRefresh()) {
|
||||||
if (await waitForArgoSyncedHealthy()) await waitForWorkloads();
|
|
||||||
} else if (await waitForArgoRefresh()) {
|
|
||||||
await waitForWorkloads();
|
await waitForWorkloads();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -223,6 +223,10 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
|||||||
assert.match(pipeline, /node scripts\/run-bun\.mjs test cmd\/hwlab-codex-api-responses-forwarder\/main\.test\.ts/u);
|
assert.match(pipeline, /node scripts\/run-bun\.mjs test cmd\/hwlab-codex-api-responses-forwarder\/main\.test\.ts/u);
|
||||||
assert.doesNotMatch(pipeline, /cmd\/hwlab-codex-api-responses-forwarder\/main\.mjs/u);
|
assert.doesNotMatch(pipeline, /cmd\/hwlab-codex-api-responses-forwarder\/main\.mjs/u);
|
||||||
const runtimeReadySource = await readFile(path.join(process.cwd(), "scripts/ci/runtime-ready.mjs"), "utf8");
|
const runtimeReadySource = await readFile(path.join(process.cwd(), "scripts/ci/runtime-ready.mjs"), "utf8");
|
||||||
|
assert.doesNotMatch(runtimeReadySource, /argo-sync-health|healthStatus === "Healthy"/u);
|
||||||
|
assert.doesNotMatch(runtimeReadySource, /HWLAB_ARGO_APPLICATION/u);
|
||||||
|
assert.match(runtimeReadySource, /if \(await waitForArgoRefresh\(\)\) \{\s+await waitForWorkloads\(\);/u);
|
||||||
|
assert.ok(!JSON.stringify(pipelineJson).includes("argo-application"));
|
||||||
assert.match(runtimeReadySource, /process\.exitCode = 1/u);
|
assert.match(runtimeReadySource, /process\.exitCode = 1/u);
|
||||||
assert.match(runtimeReadySource, /item\.metadata\?\.labels\?\.\["hwlab\.pikastech\.local\/source-commit"\]/u);
|
assert.match(runtimeReadySource, /item\.metadata\?\.labels\?\.\["hwlab\.pikastech\.local\/source-commit"\]/u);
|
||||||
|
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ function runtimeReadyTask({ profile = "dev", deploy = null } = {}) {
|
|||||||
runAfter: ["gitops-promote"],
|
runAfter: ["gitops-promote"],
|
||||||
workspaces: [{ name: "source", workspace: "source" }],
|
workspaces: [{ name: "source", workspace: "source" }],
|
||||||
taskSpec: {
|
taskSpec: {
|
||||||
params: [{ name: "revision" }, { name: "runtime-namespace" }, { name: "gitops-target" }, { name: "argo-application" }, { name: "timeout-ms" }],
|
params: [{ name: "revision" }, { name: "runtime-namespace" }, { name: "gitops-target" }, { name: "timeout-ms" }],
|
||||||
workspaces: [{ name: "source" }],
|
workspaces: [{ name: "source" }],
|
||||||
steps: [{
|
steps: [{
|
||||||
name: "runtime-ready",
|
name: "runtime-ready",
|
||||||
@@ -458,8 +458,7 @@ function runtimeReadyTask({ profile = "dev", deploy = null } = {}) {
|
|||||||
env: [
|
env: [
|
||||||
...proxyEnv(),
|
...proxyEnv(),
|
||||||
{ name: "HWLAB_RUNTIME_NAMESPACE", value: "$(params.runtime-namespace)" },
|
{ name: "HWLAB_RUNTIME_NAMESPACE", value: "$(params.runtime-namespace)" },
|
||||||
{ name: "HWLAB_GITOPS_TARGET", value: "$(params.gitops-target)" },
|
{ name: "HWLAB_GITOPS_TARGET", value: "$(params.gitops-target)" }
|
||||||
{ name: "HWLAB_ARGO_APPLICATION", value: "$(params.argo-application)" }
|
|
||||||
],
|
],
|
||||||
script: runtimeReadyScript()
|
script: runtimeReadyScript()
|
||||||
}]
|
}]
|
||||||
@@ -468,7 +467,6 @@ function runtimeReadyTask({ profile = "dev", deploy = null } = {}) {
|
|||||||
{ name: "revision", value: "$(params.revision)" },
|
{ name: "revision", value: "$(params.revision)" },
|
||||||
{ name: "runtime-namespace", value: namespaceNameForProfile(profile, deploy) },
|
{ name: "runtime-namespace", value: namespaceNameForProfile(profile, deploy) },
|
||||||
{ name: "gitops-target", value: gitopsTargetForProfile(profile) },
|
{ name: "gitops-target", value: gitopsTargetForProfile(profile) },
|
||||||
{ name: "argo-application", value: argoApplicationName(profile) },
|
|
||||||
{ name: "timeout-ms", value: "$(params.runtime-ready-timeout-ms)" }
|
{ name: "timeout-ms", value: "$(params.runtime-ready-timeout-ms)" }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user