|
|
|
@@ -390,11 +390,18 @@ function sentinelDockerfile(baseImage: string, entrypoint: string, envReuseNodeD
|
|
|
|
|
const nodeDepsPath = shellQuote(envReuseNodeDepsPath);
|
|
|
|
|
return [
|
|
|
|
|
`FROM ${baseImage}`,
|
|
|
|
|
"ARG HTTP_PROXY",
|
|
|
|
|
"ARG HTTPS_PROXY",
|
|
|
|
|
"ARG ALL_PROXY",
|
|
|
|
|
"ARG NO_PROXY",
|
|
|
|
|
"ARG http_proxy",
|
|
|
|
|
"ARG https_proxy",
|
|
|
|
|
"ARG all_proxy",
|
|
|
|
|
"ARG no_proxy",
|
|
|
|
|
"WORKDIR /app",
|
|
|
|
|
"COPY . /app",
|
|
|
|
|
`RUN if [ -d ${nodeDepsPath} ]; then mkdir -p /app/node_modules; for dep in ${nodeDepsPath}/*; do ln -sf "$dep" "/app/node_modules/$(basename "$dep")"; done; fi`,
|
|
|
|
|
"RUN printf '%s\\n' '#!/bin/sh' 'exec bun /app/scripts/ssh-cli.ts \"$@\"' > /usr/local/bin/trans && chmod 0755 /usr/local/bin/trans",
|
|
|
|
|
"RUN bun scripts/verify-web-probe-sentinel-monitor-web.ts",
|
|
|
|
|
"ENV NODE_ENV=production",
|
|
|
|
|
`ENTRYPOINT ["bun", "${entrypoint}"]`,
|
|
|
|
|
"",
|
|
|
|
@@ -411,11 +418,21 @@ function monitorWebCicdPlan(cicd: Record<string, unknown>): Record<string, unkno
|
|
|
|
|
sourceMode: stringAt(cicd, "builder.sourceMode"),
|
|
|
|
|
envReuseMode: stringAtNullable(cicd, "monitorWeb.envReuse.mode") ?? "docker-layer-and-ci-node-deps",
|
|
|
|
|
envReuseNodeDepsPath: stringAtNullable(cicd, "monitorWeb.envReuse.nodeDepsPath") ?? "/opt/hwlab-ci-node-deps/node_modules",
|
|
|
|
|
verifyPhase: stringAtNullable(cicd, "monitorWeb.dockerBuild.verifyPhase") ?? "pre-docker-build",
|
|
|
|
|
dockerBuildNetworkMode: monitorWebDockerBuildNetworkMode(cicd),
|
|
|
|
|
dockerBuildProxySource: stringAtNullable(cicd, "monitorWeb.dockerBuild.proxySource") ?? "node.networkProfile.dockerBuildProxy",
|
|
|
|
|
dockerBuildContextIgnore: stringAtNullable(cicd, "monitorWeb.dockerBuild.contextIgnore") ?? "generated",
|
|
|
|
|
ciBudgetSeconds: numberAtNullable(cicd, "monitorWeb.ciBudget.maxSeconds") ?? numberAt(cicd, "confirmWait.maxSeconds"),
|
|
|
|
|
valuesRedacted: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function monitorWebDockerBuildNetworkMode(cicd: Record<string, unknown>): "default" | "host" {
|
|
|
|
|
const value = stringAtNullable(cicd, "monitorWeb.dockerBuild.networkMode") ?? "host";
|
|
|
|
|
if (value !== "default" && value !== "host") throw new Error(`monitorWeb.dockerBuild.networkMode must be default or host, got ${value}`);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderSentinelManifests(
|
|
|
|
|
spec: HwlabRuntimeLaneSpec,
|
|
|
|
|
sentinelId: string,
|
|
|
|
@@ -1666,6 +1683,10 @@ function sentinelPublishShell(state: SentinelCicdState, jobName: string, publish
|
|
|
|
|
const dockerfileB64 = Buffer.from(state.image.dockerfilePreview, "utf8").toString("base64");
|
|
|
|
|
const envReuseMode = stringAt(monitorWeb, "envReuseMode");
|
|
|
|
|
const envReuseNodeDepsPath = stringAt(monitorWeb, "envReuseNodeDepsPath");
|
|
|
|
|
const dockerBuildNetworkMode = stringAt(monitorWeb, "dockerBuildNetworkMode");
|
|
|
|
|
const dockerBuildProxySource = stringAt(monitorWeb, "dockerBuildProxySource");
|
|
|
|
|
const dockerBuildProxy = state.spec.networkProfile.dockerBuildProxy;
|
|
|
|
|
const dockerBuildNoProxy = dockerBuildProxy.noProxy.join(",");
|
|
|
|
|
return [
|
|
|
|
|
"set -eu",
|
|
|
|
|
`job_name=${shellQuote(jobName)}`,
|
|
|
|
@@ -1682,6 +1703,12 @@ function sentinelPublishShell(state: SentinelCicdState, jobName: string, publish
|
|
|
|
|
`files_b64=${shellQuote(filesB64)}`,
|
|
|
|
|
`env_reuse_mode=${shellQuote(envReuseMode)}`,
|
|
|
|
|
`env_reuse_node_deps_path=${shellQuote(envReuseNodeDepsPath)}`,
|
|
|
|
|
`docker_build_network_mode=${shellQuote(dockerBuildNetworkMode)}`,
|
|
|
|
|
`docker_build_proxy_source=${shellQuote(dockerBuildProxySource)}`,
|
|
|
|
|
`docker_build_http_proxy=${shellQuote(dockerBuildProxy.http)}`,
|
|
|
|
|
`docker_build_https_proxy=${shellQuote(dockerBuildProxy.https)}`,
|
|
|
|
|
`docker_build_all_proxy=${shellQuote(dockerBuildProxy.all)}`,
|
|
|
|
|
`docker_build_no_proxy=${shellQuote(dockerBuildNoProxy)}`,
|
|
|
|
|
"started_ms=$(node -e 'console.log(Date.now())')",
|
|
|
|
|
"emit_stage() { stage=$1; status=$2; started=$3; finished=$(node -e 'console.log(Date.now())'); node - \"$stage\" \"$status\" \"$started\" \"$finished\" <<'NODE'\nconst [stage, status, started, finished] = process.argv.slice(2); console.log(JSON.stringify({ event:'sentinel-publish-stage', stage, status, elapsedMs:Number(finished)-Number(started), valuesRedacted:true }));\nNODE\n}",
|
|
|
|
|
"emit_failed() { code=$?; if [ \"$code\" -ne 0 ]; then node - \"$code\" \"$job_name\" <<'NODE'\nconst [code, jobName] = process.argv.slice(2); console.log(JSON.stringify({ ok:false, status:'failed', exitCode:Number(code), jobName, valuesRedacted:true }));\nNODE\nfi; exit \"$code\"; }",
|
|
|
|
@@ -1716,16 +1743,51 @@ function sentinelPublishShell(state: SentinelCicdState, jobName: string, publish
|
|
|
|
|
"env_reuse_node_deps_present=false",
|
|
|
|
|
"env_reuse_node_deps_entries=0",
|
|
|
|
|
"if [ -d \"$env_reuse_node_deps_path\" ]; then env_reuse_node_deps_present=true; env_reuse_node_deps_entries=$(find \"$env_reuse_node_deps_path\" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l | tr -d ' '); fi",
|
|
|
|
|
"node - \"$env_reuse_mode\" \"$env_reuse_node_deps_path\" \"$env_reuse_node_deps_present\" \"$env_reuse_node_deps_entries\" <<'NODE'",
|
|
|
|
|
"const [mode, nodeDepsPath, nodeDepsPresent, nodeDepsEntries] = process.argv.slice(2); console.log(JSON.stringify({ event:'sentinel-publish-env-reuse', mode, nodeDepsPath, nodeDepsPresent: nodeDepsPresent === 'true', nodeDepsEntries: Number(nodeDepsEntries || 0), dependencyReuse: nodeDepsPresent === 'true' ? 'hit' : 'miss', valuesRedacted:true }));",
|
|
|
|
|
"env_reuse_linked_node_deps=0",
|
|
|
|
|
"rm -rf node_modules",
|
|
|
|
|
"if [ \"$env_reuse_node_deps_present\" = true ]; then mkdir -p node_modules; for dep in \"$env_reuse_node_deps_path\"/*; do [ -e \"$dep\" ] || continue; ln -sf \"$dep\" \"node_modules/$(basename \"$dep\")\"; env_reuse_linked_node_deps=$((env_reuse_linked_node_deps + 1)); done; fi",
|
|
|
|
|
"node - \"$env_reuse_mode\" \"$env_reuse_node_deps_path\" \"$env_reuse_node_deps_present\" \"$env_reuse_node_deps_entries\" \"$env_reuse_linked_node_deps\" <<'NODE'",
|
|
|
|
|
"const [mode, nodeDepsPath, nodeDepsPresent, nodeDepsEntries, linkedNodeDeps] = process.argv.slice(2); console.log(JSON.stringify({ event:'sentinel-publish-env-reuse', mode, nodeDepsPath, nodeDepsPresent: nodeDepsPresent === 'true', nodeDepsEntries: Number(nodeDepsEntries || 0), linkedNodeDeps: Number(linkedNodeDeps || 0), dependencyReuse: nodeDepsPresent === 'true' ? 'hit' : 'miss', valuesRedacted:true }));",
|
|
|
|
|
"NODE",
|
|
|
|
|
"monitor_web_verify_started_ms=$(node -e 'console.log(Date.now())')",
|
|
|
|
|
"emit_stage monitor-web-verify running \"$monitor_web_verify_started_ms\"",
|
|
|
|
|
"if ! bun scripts/verify-web-probe-sentinel-monitor-web.ts > /tmp/web-probe-sentinel-monitor-web-verify.log 2>&1; then cat /tmp/web-probe-sentinel-monitor-web-verify.log; emit_stage monitor-web-verify failed \"$monitor_web_verify_started_ms\"; exit 1; fi",
|
|
|
|
|
"cat /tmp/web-probe-sentinel-monitor-web-verify.log",
|
|
|
|
|
"monitor_web_verify_finished_ms=$(node -e 'console.log(Date.now())')",
|
|
|
|
|
"emit_stage monitor-web-verify succeeded \"$monitor_web_verify_started_ms\"",
|
|
|
|
|
"DOCKERFILE_B64=\"$dockerfile_b64\" node <<'NODE'",
|
|
|
|
|
"const fs = require('node:fs');",
|
|
|
|
|
"fs.writeFileSync('Dockerfile.web-probe-sentinel', Buffer.from(process.env.DOCKERFILE_B64 || '', 'base64'));",
|
|
|
|
|
"NODE",
|
|
|
|
|
"cat > .dockerignore <<'EOF_DOCKERIGNORE'",
|
|
|
|
|
".git",
|
|
|
|
|
".git/**",
|
|
|
|
|
".state",
|
|
|
|
|
".state/**",
|
|
|
|
|
"logs",
|
|
|
|
|
"logs/**",
|
|
|
|
|
"node_modules",
|
|
|
|
|
"node_modules/**",
|
|
|
|
|
"**/node_modules",
|
|
|
|
|
"**/node_modules/**",
|
|
|
|
|
"**/dist",
|
|
|
|
|
"**/dist/**",
|
|
|
|
|
"**/target",
|
|
|
|
|
"**/target/**",
|
|
|
|
|
"**/coverage",
|
|
|
|
|
"**/coverage/**",
|
|
|
|
|
"npm-debug.log*",
|
|
|
|
|
".env",
|
|
|
|
|
".env.*",
|
|
|
|
|
"EOF_DOCKERIGNORE",
|
|
|
|
|
"docker_ignore_entries=$(wc -l < .dockerignore | tr -d ' ')",
|
|
|
|
|
"docker_build_http_proxy_present=false; if [ -n \"$docker_build_http_proxy\" ]; then docker_build_http_proxy_present=true; fi",
|
|
|
|
|
"docker_build_https_proxy_present=false; if [ -n \"$docker_build_https_proxy\" ]; then docker_build_https_proxy_present=true; fi",
|
|
|
|
|
"docker_build_all_proxy_present=false; if [ -n \"$docker_build_all_proxy\" ]; then docker_build_all_proxy_present=true; fi",
|
|
|
|
|
"docker_build_no_proxy_present=false; if [ -n \"$docker_build_no_proxy\" ]; then docker_build_no_proxy_present=true; fi",
|
|
|
|
|
"docker_build_started_ms=$(node -e 'console.log(Date.now())')",
|
|
|
|
|
"emit_stage docker-build running \"$docker_build_started_ms\"",
|
|
|
|
|
"if ! docker build -f Dockerfile.web-probe-sentinel -t \"$image_ref\" . > /tmp/web-probe-sentinel-docker-build.log 2>&1; then cat /tmp/web-probe-sentinel-docker-build.log; emit_stage docker-build failed \"$docker_build_started_ms\"; exit 1; fi",
|
|
|
|
|
"if ! env HTTP_PROXY=\"$docker_build_http_proxy\" HTTPS_PROXY=\"$docker_build_https_proxy\" ALL_PROXY=\"$docker_build_all_proxy\" NO_PROXY=\"$docker_build_no_proxy\" http_proxy=\"$docker_build_http_proxy\" https_proxy=\"$docker_build_https_proxy\" all_proxy=\"$docker_build_all_proxy\" no_proxy=\"$docker_build_no_proxy\" docker build --network \"$docker_build_network_mode\" --build-arg HTTP_PROXY=\"$docker_build_http_proxy\" --build-arg HTTPS_PROXY=\"$docker_build_https_proxy\" --build-arg ALL_PROXY=\"$docker_build_all_proxy\" --build-arg NO_PROXY=\"$docker_build_no_proxy\" --build-arg http_proxy=\"$docker_build_http_proxy\" --build-arg https_proxy=\"$docker_build_https_proxy\" --build-arg all_proxy=\"$docker_build_all_proxy\" --build-arg no_proxy=\"$docker_build_no_proxy\" -f Dockerfile.web-probe-sentinel -t \"$image_ref\" . > /tmp/web-probe-sentinel-docker-build.log 2>&1; then cat /tmp/web-probe-sentinel-docker-build.log; emit_stage docker-build failed \"$docker_build_started_ms\"; exit 1; fi",
|
|
|
|
|
"cat /tmp/web-probe-sentinel-docker-build.log",
|
|
|
|
|
"docker_build_finished_ms=$(node -e 'console.log(Date.now())')",
|
|
|
|
|
"emit_stage docker-build succeeded \"$docker_build_started_ms\"",
|
|
|
|
@@ -1781,11 +1843,11 @@ function sentinelPublishShell(state: SentinelCicdState, jobName: string, publish
|
|
|
|
|
"fi",
|
|
|
|
|
"gitops_finished_ms=$(node -e 'console.log(Date.now())')",
|
|
|
|
|
"finished_ms=$(node -e 'console.log(Date.now())')",
|
|
|
|
|
"node - \"$job_name\" \"$source_commit\" \"$mirror_commit\" \"$image_ref\" \"$digest_ref\" \"$gitops_commit\" \"$changed\" \"$file_count\" \"$started_ms\" \"$finished_ms\" \"$source_fetch_started_ms\" \"$source_fetch_finished_ms\" \"$docker_build_started_ms\" \"$docker_build_finished_ms\" \"$docker_push_started_ms\" \"$docker_push_finished_ms\" \"$gitops_started_ms\" \"$gitops_finished_ms\" \"$env_reuse_mode\" \"$env_reuse_node_deps_path\" \"$env_reuse_node_deps_present\" \"$env_reuse_node_deps_entries\" \"$docker_build_cache_hits\" \"$docker_build_step_lines\" \"$docker_build_log_tail_b64\" <<'NODE'",
|
|
|
|
|
"const [jobName, sourceCommit, mirrorCommit, imageRef, digestRef, gitopsCommit, changed, fileCount, startedMs, finishedMs, sourceFetchStartedMs, sourceFetchFinishedMs, dockerBuildStartedMs, dockerBuildFinishedMs, dockerPushStartedMs, dockerPushFinishedMs, gitopsStartedMs, gitopsFinishedMs, envReuseMode, envReuseNodeDepsPath, envReuseNodeDepsPresent, envReuseNodeDepsEntries, dockerBuildCacheHits, dockerBuildStepLines, dockerBuildLogTailB64] = process.argv.slice(2);",
|
|
|
|
|
"node - \"$job_name\" \"$source_commit\" \"$mirror_commit\" \"$image_ref\" \"$digest_ref\" \"$gitops_commit\" \"$changed\" \"$file_count\" \"$started_ms\" \"$finished_ms\" \"$source_fetch_started_ms\" \"$source_fetch_finished_ms\" \"$monitor_web_verify_started_ms\" \"$monitor_web_verify_finished_ms\" \"$docker_build_started_ms\" \"$docker_build_finished_ms\" \"$docker_push_started_ms\" \"$docker_push_finished_ms\" \"$gitops_started_ms\" \"$gitops_finished_ms\" \"$env_reuse_mode\" \"$env_reuse_node_deps_path\" \"$env_reuse_node_deps_present\" \"$env_reuse_node_deps_entries\" \"$env_reuse_linked_node_deps\" \"$docker_build_cache_hits\" \"$docker_build_step_lines\" \"$docker_build_log_tail_b64\" \"$docker_build_network_mode\" \"$docker_build_proxy_source\" \"$docker_build_http_proxy_present\" \"$docker_build_https_proxy_present\" \"$docker_build_all_proxy_present\" \"$docker_build_no_proxy_present\" \"$docker_ignore_entries\" <<'NODE'",
|
|
|
|
|
"const [jobName, sourceCommit, mirrorCommit, imageRef, digestRef, gitopsCommit, changed, fileCount, startedMs, finishedMs, sourceFetchStartedMs, sourceFetchFinishedMs, monitorWebVerifyStartedMs, monitorWebVerifyFinishedMs, dockerBuildStartedMs, dockerBuildFinishedMs, dockerPushStartedMs, dockerPushFinishedMs, gitopsStartedMs, gitopsFinishedMs, envReuseMode, envReuseNodeDepsPath, envReuseNodeDepsPresent, envReuseNodeDepsEntries, envReuseLinkedNodeDeps, dockerBuildCacheHits, dockerBuildStepLines, dockerBuildLogTailB64, dockerBuildNetworkMode, dockerBuildProxySource, dockerBuildHttpProxyPresent, dockerBuildHttpsProxyPresent, dockerBuildAllProxyPresent, dockerBuildNoProxyPresent, dockerIgnoreEntries] = process.argv.slice(2);",
|
|
|
|
|
"const elapsed = (start, finish) => Number(finish) - Number(start);",
|
|
|
|
|
"const cacheHits = Number(dockerBuildCacheHits || 0);",
|
|
|
|
|
"console.log(JSON.stringify({ ok:true, status:'succeeded', jobName, sourceCommit, mirrorCommit, imageRef, digestRef, gitopsCommit: gitopsCommit || null, changed: changed === 'true', fileCount: Number(fileCount || 0), elapsedMs: elapsed(startedMs, finishedMs), stageTimings: { sourceFetchMs: elapsed(sourceFetchStartedMs, sourceFetchFinishedMs), dockerBuildMs: elapsed(dockerBuildStartedMs, dockerBuildFinishedMs), dockerPushMs: elapsed(dockerPushStartedMs, dockerPushFinishedMs), gitopsMs: elapsed(gitopsStartedMs, gitopsFinishedMs), totalMs: elapsed(startedMs, finishedMs), valuesRedacted:true }, envReuse: { mode: envReuseMode, nodeDepsPath: envReuseNodeDepsPath, nodeDepsPresent: envReuseNodeDepsPresent === 'true', nodeDepsEntries: Number(envReuseNodeDepsEntries || 0), dependencyReuse: envReuseNodeDepsPresent === 'true' ? 'hit' : 'miss', valuesRedacted:true }, dockerBuild: { cacheHitLines: cacheHits, stepLines: Number(dockerBuildStepLines || 0), layerCache: cacheHits > 0 ? 'hit' : 'unknown-or-miss', logTail: Buffer.from(dockerBuildLogTailB64 || '', 'base64').toString('utf8'), valuesRedacted:true }, completedStages: ['source-fetch', 'docker-build', 'docker-push', gitopsCommit ? 'gitops' : 'gitops-skipped'], valuesRedacted:true }));",
|
|
|
|
|
"console.log(JSON.stringify({ ok:true, status:'succeeded', jobName, sourceCommit, mirrorCommit, imageRef, digestRef, gitopsCommit: gitopsCommit || null, changed: changed === 'true', fileCount: Number(fileCount || 0), elapsedMs: elapsed(startedMs, finishedMs), stageTimings: { sourceFetchMs: elapsed(sourceFetchStartedMs, sourceFetchFinishedMs), monitorWebVerifyMs: elapsed(monitorWebVerifyStartedMs, monitorWebVerifyFinishedMs), dockerBuildMs: elapsed(dockerBuildStartedMs, dockerBuildFinishedMs), dockerPushMs: elapsed(dockerPushStartedMs, dockerPushFinishedMs), gitopsMs: elapsed(gitopsStartedMs, gitopsFinishedMs), totalMs: elapsed(startedMs, finishedMs), valuesRedacted:true }, envReuse: { mode: envReuseMode, nodeDepsPath: envReuseNodeDepsPath, nodeDepsPresent: envReuseNodeDepsPresent === 'true', nodeDepsEntries: Number(envReuseNodeDepsEntries || 0), linkedNodeDeps: Number(envReuseLinkedNodeDeps || 0), dependencyReuse: envReuseNodeDepsPresent === 'true' ? 'hit' : 'miss', valuesRedacted:true }, dockerBuild: { cacheHitLines: cacheHits, stepLines: Number(dockerBuildStepLines || 0), layerCache: cacheHits > 0 ? 'hit' : 'unknown-or-miss', networkMode: dockerBuildNetworkMode, proxySource: dockerBuildProxySource, proxy: { httpProxyPresent: dockerBuildHttpProxyPresent === 'true', httpsProxyPresent: dockerBuildHttpsProxyPresent === 'true', allProxyPresent: dockerBuildAllProxyPresent === 'true', noProxyPresent: dockerBuildNoProxyPresent === 'true', valuesRedacted:true }, dockerIgnoreEntries: Number(dockerIgnoreEntries || 0), verifyLocation: 'pre-docker-build', logTail: Buffer.from(dockerBuildLogTailB64 || '', 'base64').toString('utf8'), valuesRedacted:true }, completedStages: ['source-fetch', 'monitor-web-verify', 'docker-build', 'docker-push', gitopsCommit ? 'gitops' : 'gitops-skipped'], valuesRedacted:true }));",
|
|
|
|
|
"NODE",
|
|
|
|
|
"trap - EXIT",
|
|
|
|
|
].join("\n");
|
|
|
|
@@ -1933,7 +1995,7 @@ function sentinelCurrentRemotePhase(result: SentinelRemoteJobResult, events: rea
|
|
|
|
|
const running = reversed.find((event) => event.status === "running");
|
|
|
|
|
if (running !== undefined) return text(running.stage);
|
|
|
|
|
const completed = new Set(events.filter((event) => event.status === "succeeded" || event.status === "skipped").map((event) => text(event.stage)));
|
|
|
|
|
const order = domain === "publish" ? ["source-fetch", "docker-build", "docker-push", "gitops"] : ["source-mirror-fetch"];
|
|
|
|
|
const order = domain === "publish" ? ["source-fetch", "monitor-web-verify", "docker-build", "docker-push", "gitops"] : ["source-mirror-fetch"];
|
|
|
|
|
const next = order.find((stage) => !completed.has(stage));
|
|
|
|
|
return next ?? result.phase;
|
|
|
|
|
}
|
|
|
|
@@ -2580,8 +2642,10 @@ function renderPublishResult(publish: Record<string, unknown>): string {
|
|
|
|
|
const diagnosticEnvReuse = record(diagnostics.envReuse);
|
|
|
|
|
const envReuse = Object.keys(record(payload.envReuse)).length > 0 ? record(payload.envReuse) : diagnosticEnvReuse;
|
|
|
|
|
const dockerBuild = record(payload.dockerBuild);
|
|
|
|
|
const dockerBuildProxy = record(dockerBuild.proxy);
|
|
|
|
|
const timings = record(payload.stageTimings);
|
|
|
|
|
const commands = record(diagnostics.commands);
|
|
|
|
|
const proxySummary = [dockerBuildProxy.httpProxyPresent, dockerBuildProxy.httpsProxyPresent, dockerBuildProxy.allProxyPresent].some((item) => item === true) ? "present" : "none";
|
|
|
|
|
const lines = [
|
|
|
|
|
"PUBLISH",
|
|
|
|
|
table(["OK", "PHASE", "JOB", "ELAPSED", "POD", "CURRENT", "DIGEST", "GITOPS"], [[
|
|
|
|
@@ -2599,11 +2663,12 @@ function renderPublishResult(publish: Record<string, unknown>): string {
|
|
|
|
|
lines.push(
|
|
|
|
|
"",
|
|
|
|
|
"PUBLISH_ENV_REUSE",
|
|
|
|
|
table(["MODE", "NODE_DEPS", "PRESENT", "ENTRIES", "DEPENDENCY"], [[
|
|
|
|
|
table(["MODE", "NODE_DEPS", "PRESENT", "ENTRIES", "LINKED", "DEPENDENCY"], [[
|
|
|
|
|
envReuse.mode,
|
|
|
|
|
envReuse.nodeDepsPath,
|
|
|
|
|
envReuse.nodeDepsPresent,
|
|
|
|
|
envReuse.nodeDepsEntries,
|
|
|
|
|
envReuse.linkedNodeDeps ?? "-",
|
|
|
|
|
envReuse.dependencyReuse,
|
|
|
|
|
]]),
|
|
|
|
|
);
|
|
|
|
@@ -2612,11 +2677,15 @@ function renderPublishResult(publish: Record<string, unknown>): string {
|
|
|
|
|
lines.push(
|
|
|
|
|
"",
|
|
|
|
|
"PUBLISH_BUILD",
|
|
|
|
|
table(["CACHE", "CACHE_LINES", "STEP_LINES", "SOURCE_MS", "BUILD_MS", "PUSH_MS", "GITOPS_MS", "TOTAL_MS"], [[
|
|
|
|
|
table(["NETWORK", "PROXY", "IGNORE", "CACHE", "CACHE_LINES", "STEP_LINES", "SOURCE_MS", "VERIFY_MS", "BUILD_MS", "PUSH_MS", "GITOPS_MS", "TOTAL_MS"], [[
|
|
|
|
|
dockerBuild.networkMode ?? "-",
|
|
|
|
|
proxySummary,
|
|
|
|
|
dockerBuild.dockerIgnoreEntries ?? "-",
|
|
|
|
|
dockerBuild.layerCache ?? "-",
|
|
|
|
|
dockerBuild.cacheHitLines ?? "-",
|
|
|
|
|
dockerBuild.stepLines ?? "-",
|
|
|
|
|
timings.sourceFetchMs ?? "-",
|
|
|
|
|
timings.monitorWebVerifyMs ?? "-",
|
|
|
|
|
timings.dockerBuildMs ?? "-",
|
|
|
|
|
timings.dockerPushMs ?? "-",
|
|
|
|
|
timings.gitopsMs ?? "-",
|
|
|
|
@@ -2673,7 +2742,7 @@ function renderImageResult(result: Record<string, unknown>): string {
|
|
|
|
|
"",
|
|
|
|
|
table(["IMAGE", "BASE", "ENTRYPOINT", "DOCKERFILE"], [[image.ref, image.baseImage, image.entrypoint, short(image.dockerfileSha256)]]),
|
|
|
|
|
"",
|
|
|
|
|
Object.keys(monitorWeb).length === 0 ? "MONITOR_WEB\n-" : table(["STACK", "MODE", "ASSETS", "VERIFY", "ENV_REUSE"], [[monitorWeb.stack, monitorWeb.runtimeMode, monitorWeb.assetRoot, monitorWeb.verifyCommand, `${monitorWeb.envReuseMode}:${monitorWeb.envReuseNodeDepsPath}`]]),
|
|
|
|
|
Object.keys(monitorWeb).length === 0 ? "MONITOR_WEB\n-" : table(["STACK", "MODE", "ASSETS", "VERIFY", "ENV_REUSE", "BUILD_NET", "CTX_IGNORE"], [[monitorWeb.stack, monitorWeb.runtimeMode, monitorWeb.assetRoot, monitorWeb.verifyCommand, `${monitorWeb.envReuseMode}:${monitorWeb.envReuseNodeDepsPath}`, monitorWeb.dockerBuildNetworkMode, monitorWeb.dockerBuildContextIgnore]]),
|
|
|
|
|
"",
|
|
|
|
|
Object.keys(registry).length === 0 ? "REGISTRY\n-" : table(["PROBED", "PRESENT", "DIGEST"], [[record(registry.probe).url ?? "-", record(registry.probe).present ?? "-", short(record(registry.probe).digest)]]),
|
|
|
|
|
"",
|
|
|
|
|