fix: 非运行态提交跳过 Todo 发布
This commit is contained in:
@@ -57,4 +57,14 @@ For migrated sentinel CI/CD half-state triage, the PaC `status` command owns the
|
||||
- Sentinel `ENV_REUSE=hit` means dependency reuse was available; `cache=hit` is separate BuildKit evidence.
|
||||
- HWLAB `skipped,skip=<n>` means service-level artifact planning skipped reusable builds; inspect the PipelineRun detail when deciding which service changed.
|
||||
|
||||
## UniDesk Host Runtime Change Filtering
|
||||
|
||||
The `unidesk-host` consumer separates source observation from runtime delivery. `config/unidesk-host-k8s.yaml#delivery.changeDetection.runtimePaths` is the only editable list of source paths that can change the selected runtime, while `delivery.gitops.releaseStatePath` points to the generated GitOps release state used as the comparison baseline.
|
||||
|
||||
- `build`: at least one declared runtime path changed, or no trustworthy prior release state is available. Build the image, update the manifest and release state, then let Argo converge.
|
||||
- `skip`: the source commit advanced but no declared runtime path changed. Do not build an image, do not modify the GitOps branch, and do not cause an Argo rollout; retain the prior runtime source commit and digest as provenance.
|
||||
- `disabled`: `delivery.enabled=false`. Remove the generated manifest and release state; this is service retirement, not a synonym for `skip`.
|
||||
|
||||
CLI, documentation, issue metadata and other files outside `runtimePaths` must resolve to `IMAGE_STATUS=skipped`. A successful skip still has a short PaC PipelineRun as source-observation evidence, but image build and GitOps publication are skipped. `status` and `closeout` must validate the retained digest, GitOps revision, Argo state, runtime readiness and health without requiring the runtime source commit to equal the newer non-runtime source commit.
|
||||
|
||||
Missing reuse text is not proof of a failed reuse path. Check the consumer type and PipelineRun detail first.
|
||||
|
||||
@@ -41,16 +41,23 @@ spec:
|
||||
env:
|
||||
- name: SOURCE_COMMIT
|
||||
value: "{{revision}}"
|
||||
- name: SOURCE_SNAPSHOT_PREFIX
|
||||
value: "{{source_snapshot_prefix}}"
|
||||
script: |
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
rm -rf source release
|
||||
git clone --filter=blob:none --no-checkout http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git source
|
||||
cd source
|
||||
git fetch --depth=1 --filter=blob:none origin "+refs/unidesk/snapshots/gitea-actions/unidesk-master-nc01/$SOURCE_COMMIT:refs/remotes/origin/unidesk-source-snapshot"
|
||||
git fetch --depth=1 --filter=blob:none origin "+$SOURCE_SNAPSHOT_PREFIX/$SOURCE_COMMIT:refs/remotes/origin/unidesk-source-snapshot"
|
||||
git checkout --detach "$SOURCE_COMMIT"
|
||||
test "$(git rev-parse HEAD)" = "$SOURCE_COMMIT"
|
||||
bun scripts/native/cicd/prepare-unidesk-host-release.mjs --config config/unidesk-host-k8s.yaml --output-dir /workspace/release
|
||||
bun scripts/native/cicd/prepare-unidesk-host-release.mjs \
|
||||
--config config/unidesk-host-k8s.yaml \
|
||||
--source-root /workspace/source \
|
||||
--source-commit "$SOURCE_COMMIT" \
|
||||
--source-snapshot-prefix "$SOURCE_SNAPSHOT_PREFIX" \
|
||||
--output-dir /workspace/release
|
||||
volumeMounts:
|
||||
- name: workspace
|
||||
mountPath: /workspace
|
||||
@@ -104,6 +111,7 @@ spec:
|
||||
--config /workspace/source/config/unidesk-host-k8s.yaml \
|
||||
--source-root /workspace/source \
|
||||
--metadata /workspace/build-metadata.json \
|
||||
--release-dir /workspace/release \
|
||||
--source-commit "$SOURCE_COMMIT" \
|
||||
--worktree /workspace/unidesk-host-gitops
|
||||
volumeMounts:
|
||||
|
||||
@@ -20,6 +20,21 @@ runtime:
|
||||
delivery:
|
||||
enabled: true
|
||||
serviceRef: services.todoNote
|
||||
changeDetection:
|
||||
runtimePaths:
|
||||
- .tekton/unidesk-host-pac.yaml
|
||||
- config/platform-infra/pipelines-as-code.yaml
|
||||
- config/unidesk-host-k8s.yaml
|
||||
- scripts/native/cicd/build-unidesk-host-image.sh
|
||||
- scripts/native/cicd/prepare-unidesk-host-release.mjs
|
||||
- scripts/native/cicd/publish-unidesk-host-gitops.mjs
|
||||
- scripts/native/deploy/render-unidesk-host-service.mjs
|
||||
- src/components/microservices/todo-note/Dockerfile
|
||||
- src/components/microservices/todo-note/bun.lock
|
||||
- src/components/microservices/todo-note/package.json
|
||||
- src/components/microservices/todo-note/src
|
||||
- src/components/microservices/todo-note/tsconfig.json
|
||||
- src/components/shared
|
||||
build:
|
||||
networkMode: host
|
||||
proxy:
|
||||
@@ -42,6 +57,7 @@ delivery:
|
||||
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
|
||||
branch: unidesk-host-gitops
|
||||
manifestPath: deploy/gitops/unidesk-host/todo-note.yaml
|
||||
releaseStatePath: deploy/gitops-state/unidesk-host/todo-note.json
|
||||
author:
|
||||
name: UniDesk Host CI
|
||||
email: unidesk-host-ci@unidesk.local
|
||||
|
||||
@@ -8,11 +8,12 @@ metadata_file=${UNIDESK_HOST_BUILD_METADATA_FILE:-/workspace/build-metadata.json
|
||||
build_log=${UNIDESK_HOST_BUILD_LOG:-/workspace/image-build.log}
|
||||
source_commit=${SOURCE_COMMIT:?SOURCE_COMMIT is required}
|
||||
|
||||
enabled=$(cat "$release_dir/enabled")
|
||||
if [ "$enabled" != true ]; then
|
||||
action=$(cat "$release_dir/action")
|
||||
reason=$(cat "$release_dir/reason")
|
||||
if [ "$action" != build ]; then
|
||||
: >"$digest_file"
|
||||
: >"$metadata_file"
|
||||
printf '{"ok":true,"phase":"image-build","status":"skipped","reason":"delivery-disabled","sourceCommit":"%s","valuesPrinted":false}\n' "$source_commit"
|
||||
printf '{"ok":true,"phase":"image-build","status":"skipped","action":"%s","reason":"%s","sourceCommit":"%s","valuesPrinted":false}\n' "$action" "$reason" "$source_commit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bun
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
@@ -20,6 +21,27 @@ function required(value, path) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function safeRelativePath(value, path) {
|
||||
const result = required(value, path);
|
||||
if (result.startsWith("/") || result.split("/").includes("..")) throw new Error(`${path} must be a safe relative path`);
|
||||
return result;
|
||||
}
|
||||
|
||||
function stringArray(value, path) {
|
||||
if (!Array.isArray(value) || value.length === 0) throw new Error(`${path} must be a non-empty string array`);
|
||||
return value.map((item, index) => safeRelativePath(item, `${path}[${index}]`));
|
||||
}
|
||||
|
||||
function run(command, args, cwd, allowFailure = false) {
|
||||
const result = spawnSync(command, args, { cwd, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 });
|
||||
if (result.error !== undefined) throw result.error;
|
||||
if (result.status !== 0 && !allowFailure) {
|
||||
const detail = `${result.stderr || result.stdout || "command failed"}`.trim().slice(-2000);
|
||||
throw new Error(`${command} ${args.join(" ")} failed (${result.status}): ${detail}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function valueAt(root, reference) {
|
||||
return reference.split(".").reduce((value, key) => record(value, reference)[key], root);
|
||||
}
|
||||
@@ -30,20 +52,65 @@ function writeValue(outputDir, name, value) {
|
||||
|
||||
function main() {
|
||||
const configPath = option("--config") ?? "config/unidesk-host-k8s.yaml";
|
||||
const sourceRoot = resolve(option("--source-root") ?? process.cwd());
|
||||
const sourceCommit = required(option("--source-commit"), "--source-commit");
|
||||
const sourceSnapshotPrefix = required(option("--source-snapshot-prefix"), "--source-snapshot-prefix");
|
||||
const outputDir = resolve(required(option("--output-dir"), "--output-dir"));
|
||||
if (!/^[0-9a-f]{40}$/u.test(sourceCommit)) throw new Error("--source-commit must be a full Git commit SHA");
|
||||
if (run("git", ["check-ref-format", sourceSnapshotPrefix], sourceRoot, true).status !== 0) throw new Error("--source-snapshot-prefix must be a valid Git ref prefix");
|
||||
const config = record(Bun.YAML.parse(readFileSync(configPath, "utf8")), configPath);
|
||||
const delivery = record(config.delivery, "delivery");
|
||||
const serviceRef = required(delivery.serviceRef, "delivery.serviceRef");
|
||||
const service = record(valueAt(config, serviceRef), serviceRef);
|
||||
const changeDetection = record(delivery.changeDetection, "delivery.changeDetection");
|
||||
const runtimePaths = stringArray(changeDetection.runtimePaths, "delivery.changeDetection.runtimePaths");
|
||||
const build = record(delivery.build, "delivery.build");
|
||||
const proxy = record(build.proxy, "delivery.build.proxy");
|
||||
const image = record(delivery.image, "delivery.image");
|
||||
const gitops = record(delivery.gitops, "delivery.gitops");
|
||||
const readUrl = required(gitops.readUrl, "delivery.gitops.readUrl");
|
||||
const branch = required(gitops.branch, "delivery.gitops.branch");
|
||||
const releaseStatePath = safeRelativePath(gitops.releaseStatePath, "delivery.gitops.releaseStatePath");
|
||||
const enabled = delivery.enabled === true;
|
||||
if (delivery.enabled !== true && delivery.enabled !== false) throw new Error("delivery.enabled must be boolean");
|
||||
const noProxy = proxy.noProxy;
|
||||
if (!Array.isArray(noProxy) || noProxy.some((value) => typeof value !== "string" || value.length === 0)) throw new Error("delivery.build.proxy.noProxy must be a non-empty string array");
|
||||
let action = enabled ? "build" : "disabled";
|
||||
let reason = enabled ? "gitops-baseline-unavailable" : "delivery-disabled";
|
||||
let baselineSourceCommit = null;
|
||||
let changedPaths = [];
|
||||
if (enabled) {
|
||||
const gitopsRef = "refs/unidesk/release-baseline/unidesk-host";
|
||||
const gitopsFetch = run("git", ["fetch", "--depth=1", readUrl, `+refs/heads/${branch}:${gitopsRef}`], sourceRoot, true);
|
||||
if (gitopsFetch.status === 0) {
|
||||
const stateResult = run("git", ["show", `${gitopsRef}:${releaseStatePath}`], sourceRoot, true);
|
||||
if (stateResult.status === 0) {
|
||||
const state = record(JSON.parse(stateResult.stdout), releaseStatePath);
|
||||
if (state.kind !== "UniDeskHostReleaseState") throw new Error(`${releaseStatePath}.kind must be UniDeskHostReleaseState`);
|
||||
if (state.serviceRef !== serviceRef) throw new Error(`${releaseStatePath}.serviceRef must match delivery.serviceRef`);
|
||||
baselineSourceCommit = required(state.sourceCommit, `${releaseStatePath}.sourceCommit`);
|
||||
if (!/^[0-9a-f]{40}$/u.test(baselineSourceCommit)) throw new Error(`${releaseStatePath}.sourceCommit must be a full Git commit SHA`);
|
||||
const sourceRef = "refs/unidesk/release-baseline/unidesk-host-source";
|
||||
const sourceFetch = run("git", ["fetch", "--depth=1", "--filter=blob:none", "origin", `+${sourceSnapshotPrefix}/${baselineSourceCommit}:${sourceRef}`], sourceRoot, true);
|
||||
if (sourceFetch.status === 0) {
|
||||
const diff = run("git", ["diff", "--name-only", "--no-renames", sourceRef, sourceCommit, "--", ...runtimePaths], sourceRoot);
|
||||
changedPaths = diff.stdout.split(/\r?\n/u).filter(Boolean);
|
||||
action = changedPaths.length === 0 ? "skip" : "build";
|
||||
reason = changedPaths.length === 0 ? "runtime-inputs-unchanged" : "runtime-inputs-changed";
|
||||
} else {
|
||||
reason = "source-baseline-unavailable";
|
||||
}
|
||||
} else {
|
||||
reason = "release-state-missing";
|
||||
}
|
||||
}
|
||||
}
|
||||
mkdirSync(outputDir, { recursive: true });
|
||||
writeValue(outputDir, "enabled", enabled ? "true" : "false");
|
||||
writeValue(outputDir, "action", action);
|
||||
writeValue(outputDir, "reason", reason);
|
||||
writeValue(outputDir, "baseline-source-commit", baselineSourceCommit ?? "");
|
||||
writeFileSync(resolve(outputDir, "changed-paths.json"), `${JSON.stringify(changedPaths)}\n`, { encoding: "utf8", mode: 0o644 });
|
||||
writeValue(outputDir, "dockerfile", required(record(service.repository, `${serviceRef}.repository`).dockerfile, `${serviceRef}.repository.dockerfile`));
|
||||
writeValue(outputDir, "image-repository", required(image.repository, "delivery.image.repository"));
|
||||
writeValue(outputDir, "network-mode", required(build.networkMode, "delivery.build.networkMode"));
|
||||
@@ -51,7 +118,7 @@ writeValue(outputDir, "http-proxy", required(proxy.http, "delivery.build.proxy.h
|
||||
writeValue(outputDir, "https-proxy", required(proxy.https, "delivery.build.proxy.https"));
|
||||
writeValue(outputDir, "all-proxy", required(proxy.all, "delivery.build.proxy.all"));
|
||||
writeValue(outputDir, "no-proxy", noProxy.join(","));
|
||||
process.stdout.write(`${JSON.stringify({ ok: true, action: "unidesk-host-release-prepare", enabled, serviceRef, valuesPrinted: false })}\n`);
|
||||
process.stdout.write(`${JSON.stringify({ ok: true, phase: "release-prepare", action, reason, enabled, serviceRef, sourceCommit, baselineSourceCommit, changedPaths, valuesPrinted: false })}\n`);
|
||||
}
|
||||
|
||||
if (!process.execArgv.includes("--check")) main();
|
||||
|
||||
@@ -37,10 +37,47 @@ function safeManifestPath(value) {
|
||||
return path;
|
||||
}
|
||||
|
||||
function safeReleaseStatePath(value) {
|
||||
const path = required(value, "delivery.gitops.releaseStatePath");
|
||||
if (path.startsWith("/") || path.split("/").includes("..")) throw new Error("delivery.gitops.releaseStatePath must be a safe relative path");
|
||||
return path;
|
||||
}
|
||||
|
||||
function releaseValue(releaseDir, name) {
|
||||
return required(readFileSync(resolve(releaseDir, name), "utf8").trim(), `${releaseDir}/${name}`);
|
||||
}
|
||||
|
||||
function removeFile(path) {
|
||||
try {
|
||||
unlinkSync(path);
|
||||
} catch (error) {
|
||||
if (error?.code !== "ENOENT") throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function readReleaseState(path, serviceRef) {
|
||||
let value;
|
||||
try {
|
||||
value = record(JSON.parse(readFileSync(path, "utf8")), path);
|
||||
} catch (error) {
|
||||
if (error?.code === "ENOENT") return null;
|
||||
throw error;
|
||||
}
|
||||
if (value.kind !== "UniDeskHostReleaseState") throw new Error(`${path}.kind must be UniDeskHostReleaseState`);
|
||||
if (value.serviceRef !== serviceRef) throw new Error(`${path}.serviceRef must match delivery.serviceRef`);
|
||||
const sourceCommit = required(value.sourceCommit, `${path}.sourceCommit`);
|
||||
const digest = required(value.digest, `${path}.digest`);
|
||||
const digestRef = required(value.digestRef, `${path}.digestRef`);
|
||||
if (!/^[0-9a-f]{40}$/u.test(sourceCommit)) throw new Error(`${path}.sourceCommit must be a full Git commit SHA`);
|
||||
if (!/^sha256:[0-9a-f]{64}$/u.test(digest)) throw new Error(`${path}.digest must be sha256:<64 hex>`);
|
||||
return { sourceCommit, digest, digestRef };
|
||||
}
|
||||
|
||||
function main() {
|
||||
const configPath = resolve(option("--config") ?? "config/unidesk-host-k8s.yaml");
|
||||
const sourceRoot = resolve(option("--source-root") ?? process.cwd());
|
||||
const metadataPath = resolve(required(option("--metadata"), "--metadata"));
|
||||
const releaseDir = resolve(required(option("--release-dir"), "--release-dir"));
|
||||
const sourceCommit = required(option("--source-commit"), "--source-commit");
|
||||
const worktree = resolve(option("--worktree") ?? "/workspace/unidesk-host-gitops");
|
||||
if (!/^[0-9a-f]{40}$/u.test(sourceCommit)) throw new Error("--source-commit must be a full Git commit SHA");
|
||||
@@ -49,6 +86,11 @@ const config = record(Bun.YAML.parse(readFileSync(configPath, "utf8")), configPa
|
||||
const delivery = record(config.delivery, "delivery");
|
||||
if (delivery.enabled !== true && delivery.enabled !== false) throw new Error("delivery.enabled must be boolean");
|
||||
const enabled = delivery.enabled === true;
|
||||
const action = releaseValue(releaseDir, "action");
|
||||
const reason = releaseValue(releaseDir, "reason");
|
||||
const baselineSourceCommit = readFileSync(resolve(releaseDir, "baseline-source-commit"), "utf8").trim() || null;
|
||||
if (!new Set(["build", "skip", "disabled"]).has(action)) throw new Error(`${releaseDir}/action must be build, skip, or disabled`);
|
||||
if ((enabled && action === "disabled") || (!enabled && action !== "disabled")) throw new Error("release action does not match delivery.enabled");
|
||||
const serviceRef = required(delivery.serviceRef, "delivery.serviceRef");
|
||||
const imageConfig = record(delivery.image, "delivery.image");
|
||||
const gitops = record(delivery.gitops, "delivery.gitops");
|
||||
@@ -57,15 +99,18 @@ const readUrl = required(gitops.readUrl, "delivery.gitops.readUrl");
|
||||
const writeUrl = required(gitops.writeUrl, "delivery.gitops.writeUrl");
|
||||
const branch = required(gitops.branch, "delivery.gitops.branch");
|
||||
const manifestPath = safeManifestPath(gitops.manifestPath);
|
||||
const releaseStatePath = safeReleaseStatePath(gitops.releaseStatePath);
|
||||
let digest = null;
|
||||
let digestRef = null;
|
||||
let manifest = null;
|
||||
let runtimeSourceCommit = null;
|
||||
|
||||
if (enabled) {
|
||||
if (action === "build") {
|
||||
const metadata = record(JSON.parse(readFileSync(metadataPath, "utf8")), metadataPath);
|
||||
digest = required(metadata["containerimage.digest"], `${metadataPath}.containerimage.digest`);
|
||||
if (!/^sha256:[0-9a-f]{64}$/u.test(digest)) throw new Error("containerimage.digest must be sha256:<64 hex>");
|
||||
digestRef = `${required(imageConfig.repository, "delivery.image.repository")}@${digest}`;
|
||||
runtimeSourceCommit = sourceCommit;
|
||||
const render = run("bun", [
|
||||
"scripts/native/deploy/render-unidesk-host-service.mjs",
|
||||
"--config",
|
||||
@@ -92,16 +137,30 @@ if (fetched) {
|
||||
}
|
||||
|
||||
const targetPath = resolve(worktree, manifestPath);
|
||||
const statePath = resolve(worktree, releaseStatePath);
|
||||
if (!targetPath.startsWith(`${worktree}/`)) throw new Error("resolved manifest path escaped the GitOps worktree");
|
||||
if (enabled && manifest !== null) {
|
||||
if (!statePath.startsWith(`${worktree}/`)) throw new Error("resolved release state path escaped the GitOps worktree");
|
||||
const existingState = readReleaseState(statePath, serviceRef);
|
||||
if (action === "skip") {
|
||||
if (existingState === null) throw new Error("skip requires an existing GitOps release state");
|
||||
digest = existingState.digest;
|
||||
digestRef = existingState.digestRef;
|
||||
runtimeSourceCommit = existingState.sourceCommit;
|
||||
} else if (action === "build" && manifest !== null) {
|
||||
mkdirSync(dirname(targetPath), { recursive: true });
|
||||
writeFileSync(targetPath, manifest, "utf8");
|
||||
mkdirSync(dirname(statePath), { recursive: true });
|
||||
writeFileSync(statePath, `${JSON.stringify({
|
||||
version: 1,
|
||||
kind: "UniDeskHostReleaseState",
|
||||
serviceRef,
|
||||
sourceCommit,
|
||||
digest,
|
||||
digestRef,
|
||||
}, null, 2)}\n`, "utf8");
|
||||
} else {
|
||||
try {
|
||||
unlinkSync(targetPath);
|
||||
} catch (error) {
|
||||
if (error?.code !== "ENOENT") throw error;
|
||||
}
|
||||
removeFile(targetPath);
|
||||
removeFile(statePath);
|
||||
}
|
||||
|
||||
run("git", ["config", "user.name", required(author.name, "delivery.gitops.author.name")], worktree);
|
||||
@@ -109,8 +168,8 @@ run("git", ["config", "user.email", required(author.email, "delivery.gitops.auth
|
||||
run("git", ["add", "-A"], worktree);
|
||||
const changed = run("git", ["diff", "--cached", "--quiet"], worktree, true).status !== 0;
|
||||
if (changed) {
|
||||
const action = enabled ? "deploy" : "remove";
|
||||
run("git", ["commit", "-m", `unidesk-host: ${action} ${serviceRef} ${sourceCommit.slice(0, 12)}`], worktree);
|
||||
const commitAction = action === "build" ? "deploy" : "remove";
|
||||
run("git", ["commit", "-m", `unidesk-host: ${commitAction} ${serviceRef} ${sourceCommit.slice(0, 12)}`], worktree);
|
||||
}
|
||||
|
||||
run("git", ["remote", "set-url", "origin", writeUrl], worktree);
|
||||
@@ -139,9 +198,13 @@ const gitopsCommit = head.status === 0 ? head.stdout.trim() : null;
|
||||
process.stdout.write(`${JSON.stringify({
|
||||
ok: true,
|
||||
phase: "gitops-publish",
|
||||
status: enabled ? (changed ? "built" : "reused") : "disabled",
|
||||
imageStatus: enabled ? (changed ? "built" : "reused") : "disabled",
|
||||
action,
|
||||
reason,
|
||||
status: action === "build" ? "built" : action === "skip" ? "skipped" : "disabled",
|
||||
imageStatus: action === "build" ? "built" : action === "skip" ? "skipped" : "disabled",
|
||||
sourceCommit,
|
||||
baselineSourceCommit,
|
||||
runtimeSourceCommit,
|
||||
digest,
|
||||
digestRef,
|
||||
gitopsCommit,
|
||||
|
||||
@@ -727,6 +727,10 @@ if (image) {
|
||||
digests: loggedDigests,
|
||||
gitopsCommit,
|
||||
sourceCommit: image.sourceCommit || null,
|
||||
runtimeSourceCommit: image.runtimeSourceCommit || null,
|
||||
baselineSourceCommit: image.baselineSourceCommit || null,
|
||||
action: image.action || null,
|
||||
reason: image.reason || null,
|
||||
valuesPrinted: false,
|
||||
};
|
||||
} else if (humanEnv || gitopsCommit || loggedDigests.length > 0) {
|
||||
@@ -930,13 +934,15 @@ cicd_diagnostics() {
|
||||
printf '%s' "${2:-{}}" >"$artifact_file"
|
||||
printf '%s' "${3:-{}}" >"$argo_file"
|
||||
printf '%s' "${4:-{}}" >"$runtime_file"
|
||||
probe_env=$(node - "$params_file" "$pipelines_file" <<'NODE'
|
||||
probe_env=$(node - "$params_file" "$pipelines_file" "$artifact_file" <<'NODE'
|
||||
const fs = require('node:fs');
|
||||
const params = JSON.parse(fs.readFileSync(process.argv[2], 'utf8') || '{}');
|
||||
const pipelines = JSON.parse(fs.readFileSync(process.argv[3], 'utf8') || '[]');
|
||||
const artifact = JSON.parse(fs.readFileSync(process.argv[4], 'utf8') || '{}');
|
||||
const latest = Array.isArray(pipelines) ? pipelines[0] || {} : {};
|
||||
const sourceCommit = latest.sourceCommit || null;
|
||||
const tag = sourceCommit ? String(sourceCommit).slice(0, 12) : '';
|
||||
const runtimeSourceCommit = artifact.runtimeSourceCommit || sourceCommit;
|
||||
const tag = runtimeSourceCommit ? String(runtimeSourceCommit).slice(0, 12) : '';
|
||||
const prefix = process.env.UNIDESK_PAC_CONSUMER_ID === 'unidesk-host' ? 'unidesk_host_' : '';
|
||||
const param = (name) => params[`${prefix}${name}`] ?? params[name];
|
||||
const imageRepository = typeof param('image_repository') === 'string' ? param('image_repository') : '';
|
||||
@@ -955,6 +961,7 @@ function line(key, value) {
|
||||
line('imageRepository', imageRepository);
|
||||
line('registryProbeBase', probeBase);
|
||||
line('sourceCommit', sourceCommit || '');
|
||||
line('runtimeSourceCommit', runtimeSourceCommit || '');
|
||||
line('tag', tag);
|
||||
line('registryUrl', registryUrl);
|
||||
line('sentinelId', param('sentinel_id') || '');
|
||||
@@ -970,6 +977,7 @@ NODE
|
||||
image_repository=$(printf '%s\n' "$probe_env" | sed -n 's/^imageRepository=//p' | base64 -d 2>/dev/null || true)
|
||||
registry_probe_base=$(printf '%s\n' "$probe_env" | sed -n 's/^registryProbeBase=//p' | base64 -d 2>/dev/null || true)
|
||||
source_commit=$(printf '%s\n' "$probe_env" | sed -n 's/^sourceCommit=//p' | base64 -d 2>/dev/null || true)
|
||||
runtime_source_commit=$(printf '%s\n' "$probe_env" | sed -n 's/^runtimeSourceCommit=//p' | base64 -d 2>/dev/null || true)
|
||||
image_tag=$(printf '%s\n' "$probe_env" | sed -n 's/^tag=//p' | base64 -d 2>/dev/null || true)
|
||||
registry_url=$(printf '%s\n' "$probe_env" | sed -n 's/^registryUrl=//p' | base64 -d 2>/dev/null || true)
|
||||
sentinel_id=$(printf '%s\n' "$probe_env" | sed -n 's/^sentinelId=//p' | base64 -d 2>/dev/null || true)
|
||||
@@ -1017,6 +1025,7 @@ NODE
|
||||
export UNIDESK_PAC_DIAG_IMAGE_REPOSITORY="$image_repository"
|
||||
export UNIDESK_PAC_DIAG_REGISTRY_PROBE_BASE="$registry_probe_base"
|
||||
export UNIDESK_PAC_DIAG_SOURCE_COMMIT="$source_commit"
|
||||
export UNIDESK_PAC_DIAG_RUNTIME_SOURCE_COMMIT="$runtime_source_commit"
|
||||
export UNIDESK_PAC_DIAG_IMAGE_TAG="$image_tag"
|
||||
export UNIDESK_PAC_DIAG_REGISTRY_URL="$registry_url"
|
||||
export UNIDESK_PAC_DIAG_REGISTRY_PRESENT="$registry_present_json"
|
||||
@@ -1062,6 +1071,7 @@ const gitopsRelation = revisionRelation.relation || 'unknown';
|
||||
const gitopsReady = Boolean(artifact.gitopsCommit && argo.revision);
|
||||
const gitopsRevisionAligned = gitopsRelation === 'exact' || gitopsRelation === 'descendant';
|
||||
const deliveryDisabled = artifact.imageStatus === 'disabled';
|
||||
const deliverySkipped = artifact.imageStatus === 'skipped';
|
||||
let code = 'pac-diagnostics-not-applicable';
|
||||
let phase = 'not-applicable';
|
||||
let ok = true;
|
||||
@@ -1089,9 +1099,11 @@ if (deliveryDisabled) {
|
||||
} else if (!healthReady) {
|
||||
ok = false; code = 'pac-health-not-ready'; phase = 'runtime-ready-health-pending'; hint = 'runtime image is aligned but the configured health endpoint is not ready';
|
||||
} else if (artifactDigest || selectedArtifactDigests.length > 0 || process.env.UNIDESK_PAC_DIAG_IMAGE_REPOSITORY) {
|
||||
code = gitopsRelation === 'descendant' ? 'pac-ready-gitops-descendant' : 'pac-ready-gitops-exact';
|
||||
code = deliverySkipped ? 'pac-ready-runtime-unchanged' : gitopsRelation === 'descendant' ? 'pac-ready-gitops-descendant' : 'pac-ready-gitops-exact';
|
||||
phase = 'ready';
|
||||
hint = gitopsRelation === 'descendant'
|
||||
hint = deliverySkipped
|
||||
? 'YAML-declared runtime inputs are unchanged; the existing image, GitOps manifest, runtime and health remain aligned'
|
||||
: gitopsRelation === 'descendant'
|
||||
? 'Argo is on a commit-graph-proven GitOps descendant and the selected artifact, runtime, Argo and health are aligned'
|
||||
: 'Argo is on the exact selected GitOps commit and the artifact, runtime and health are aligned';
|
||||
}
|
||||
@@ -1101,6 +1113,7 @@ process.stdout.write(JSON.stringify({
|
||||
phase,
|
||||
hint,
|
||||
sourceCommit,
|
||||
runtimeSourceCommit: process.env.UNIDESK_PAC_DIAG_RUNTIME_SOURCE_COMMIT || artifact.runtimeSourceCommit || null,
|
||||
imageRepository: process.env.UNIDESK_PAC_DIAG_IMAGE_REPOSITORY || null,
|
||||
registryProbeBase: process.env.UNIDESK_PAC_DIAG_REGISTRY_PROBE_BASE || null,
|
||||
imageTag: process.env.UNIDESK_PAC_DIAG_IMAGE_TAG || null,
|
||||
@@ -1128,6 +1141,7 @@ process.stdout.write(JSON.stringify({
|
||||
health: { url: healthUrl, status: healthStatus, ready: healthReady },
|
||||
pipelineRun: latest.name || null,
|
||||
deliveryDisabled,
|
||||
deliverySkipped,
|
||||
valuesPrinted: false,
|
||||
}));
|
||||
NODE
|
||||
|
||||
Reference in New Issue
Block a user