diff --git a/config/hwlab-web-probe-sentinel/cicd.auth-session-switch.d601-v03.yaml b/config/hwlab-web-probe-sentinel/cicd.auth-session-switch.d601-v03.yaml index eca346f7..2f186392 100644 --- a/config/hwlab-web-probe-sentinel/cicd.auth-session-switch.d601-v03.yaml +++ b/config/hwlab-web-probe-sentinel/cicd.auth-session-switch.d601-v03.yaml @@ -52,6 +52,11 @@ sentinel: envReuse: mode: docker-layer-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules + dockerBuild: + networkMode: host + proxySource: node.networkProfile.dockerBuildProxy + contextIgnore: generated + verifyPhase: pre-docker-build gitMirror: source: source.gitMirrorReadUrl preSync: required diff --git a/config/hwlab-web-probe-sentinel/cicd.d518-v03.yaml b/config/hwlab-web-probe-sentinel/cicd.d518-v03.yaml index 345cebe1..ef267ec5 100644 --- a/config/hwlab-web-probe-sentinel/cicd.d518-v03.yaml +++ b/config/hwlab-web-probe-sentinel/cicd.d518-v03.yaml @@ -52,6 +52,11 @@ sentinel: envReuse: mode: docker-layer-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules + dockerBuild: + networkMode: host + proxySource: node.networkProfile.dockerBuildProxy + contextIgnore: generated + verifyPhase: pre-docker-build gitMirror: source: source.gitMirrorReadUrl preSync: required diff --git a/config/hwlab-web-probe-sentinel/cicd.d601-v03.yaml b/config/hwlab-web-probe-sentinel/cicd.d601-v03.yaml index 1737c0f5..ea5dfe81 100644 --- a/config/hwlab-web-probe-sentinel/cicd.d601-v03.yaml +++ b/config/hwlab-web-probe-sentinel/cicd.d601-v03.yaml @@ -52,6 +52,11 @@ sentinel: envReuse: mode: docker-layer-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules + dockerBuild: + networkMode: host + proxySource: node.networkProfile.dockerBuildProxy + contextIgnore: generated + verifyPhase: pre-docker-build gitMirror: source: source.gitMirrorReadUrl preSync: required diff --git a/config/hwlab-web-probe-sentinel/cicd.fake-echo.d518-v03.yaml b/config/hwlab-web-probe-sentinel/cicd.fake-echo.d518-v03.yaml index 406e5849..9d70d4e1 100644 --- a/config/hwlab-web-probe-sentinel/cicd.fake-echo.d518-v03.yaml +++ b/config/hwlab-web-probe-sentinel/cicd.fake-echo.d518-v03.yaml @@ -53,6 +53,11 @@ sentinel: envReuse: mode: docker-layer-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules + dockerBuild: + networkMode: host + proxySource: node.networkProfile.dockerBuildProxy + contextIgnore: generated + verifyPhase: pre-docker-build gitMirror: source: source.gitMirrorReadUrl preSync: required diff --git a/config/hwlab-web-probe-sentinel/cicd.mdtodo.d601-v03.yaml b/config/hwlab-web-probe-sentinel/cicd.mdtodo.d601-v03.yaml index a98baa4b..4ad4805f 100644 --- a/config/hwlab-web-probe-sentinel/cicd.mdtodo.d601-v03.yaml +++ b/config/hwlab-web-probe-sentinel/cicd.mdtodo.d601-v03.yaml @@ -52,6 +52,11 @@ sentinel: envReuse: mode: docker-layer-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules + dockerBuild: + networkMode: host + proxySource: node.networkProfile.dockerBuildProxy + contextIgnore: generated + verifyPhase: pre-docker-build gitMirror: source: source.gitMirrorReadUrl preSync: required diff --git a/config/hwlab-web-probe-sentinel/profiles.yaml b/config/hwlab-web-probe-sentinel/profiles.yaml index 1086e83a..5b710c33 100644 --- a/config/hwlab-web-probe-sentinel/profiles.yaml +++ b/config/hwlab-web-probe-sentinel/profiles.yaml @@ -63,6 +63,11 @@ baselines: envReuse: mode: docker-layer-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules + dockerBuild: + networkMode: host + proxySource: node.networkProfile.dockerBuildProxy + contextIgnore: generated + verifyPhase: pre-docker-build gitMirror: source: source.gitMirrorReadUrl preSync: required diff --git a/scripts/src/hwlab-node-web-sentinel-cicd.ts b/scripts/src/hwlab-node-web-sentinel-cicd.ts index d21ed7d7..f455a7d0 100644 --- a/scripts/src/hwlab-node-web-sentinel-cicd.ts +++ b/scripts/src/hwlab-node-web-sentinel-cicd.ts @@ -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): Record): "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 { 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 { 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 { 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 { "", 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)]]), "",