虚拟HAL完全满足Web数控仿真
结论:虚拟HAL功能来源于LinuxCNC源程序,并已通过source compliance、sim-config coverage、halcmd fixture、OPFS/session、browser diagnostics与release URL workflow验证,完全满足Web方式数控系统仿真范围;不声明Linux kernel hard-realtime ABI、外部硬件驱动ABI或native HAL module ABI。
This commit is contained in:
@@ -88,6 +88,97 @@ const BLOCKED_RUNTIME_FAMILIES = [
|
||||
const PROJECT_RELEASE_READINESS_ARTIFACT_API = "project-release-readiness-report";
|
||||
const PROJECT_RELEASE_READINESS_ARTIFACT_VERSION = 1;
|
||||
|
||||
function isVirtualHalSimConfigSourceCoverageReady(report) {
|
||||
const coverage = objectOrEmpty(report);
|
||||
return coverage.apiName === "linuxcnc-wasm-virtual-hal-sim-config-source-coverage-report" &&
|
||||
coverage.complete === true &&
|
||||
coverage.webSimulationSatisfied === true &&
|
||||
arrayOrEmpty(coverage.missingTargets).length === 0 &&
|
||||
arrayOrEmpty(coverage.missingCapabilities).length === 0 &&
|
||||
arrayOrEmpty(coverage.sourceFiles).includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini") &&
|
||||
arrayOrEmpty(coverage.sourceFiles).includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc");
|
||||
}
|
||||
|
||||
export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifact = {}) {
|
||||
const artifactObject = objectOrEmpty(artifact);
|
||||
const sourceCompliance = objectOrEmpty(artifactObject.virtualHalSourceCompliance);
|
||||
const simConfigSourceCoverage = objectOrEmpty(artifactObject.virtualHalSimConfigSourceCoverage);
|
||||
const commandScriptFixtures = objectOrEmpty(artifactObject.virtualHalCommandScriptFixtures);
|
||||
const replacement = objectOrEmpty(artifactObject.virtualHalSimulationReplacement);
|
||||
const virtualHal = objectOrEmpty(artifactObject.virtualHal);
|
||||
const sourceComplianceReady = sourceCompliance.complete === true &&
|
||||
sourceCompliance.webSimulationSatisfied === true &&
|
||||
arrayOrEmpty(sourceCompliance.sourceFiles).includes("linuxcnc/src/hal/utils/halcmd_commands.cc");
|
||||
const simConfigSourceCoverageReady = isVirtualHalSimConfigSourceCoverageReady(simConfigSourceCoverage);
|
||||
const commandScriptFixturesReady = commandScriptFixtures.complete === true &&
|
||||
commandScriptFixtures.webSimulationSatisfied === true &&
|
||||
arrayOrEmpty(commandScriptFixtures.coveredActions).includes("loadusr") &&
|
||||
arrayOrEmpty(commandScriptFixtures.coveredActions).includes("stop") &&
|
||||
arrayOrEmpty(commandScriptFixtures.sourceFiles).includes("linuxcnc/src/hal/utils/halcmd_commands.cc");
|
||||
const replacementReady = replacement.ready === true &&
|
||||
replacement.replacesHostRuntimeForSimulation === true &&
|
||||
objectOrEmpty(replacement.sourceCompliance).webSimulationSatisfied === true;
|
||||
const virtualHalReady = virtualHal.source === "browser-virtual-hal";
|
||||
const missing = [
|
||||
...(artifactObject.apiName === "real-browser-simulation-diagnostics-artifact" ? [] : ["apiName"]),
|
||||
...(virtualHalReady ? [] : ["virtualHal"]),
|
||||
...(replacementReady ? [] : ["virtualHalSimulationReplacement"]),
|
||||
...(sourceComplianceReady ? [] : ["virtualHalSourceCompliance"]),
|
||||
...(simConfigSourceCoverageReady ? [] : ["virtualHalSimConfigSourceCoverage"]),
|
||||
...(commandScriptFixturesReady ? [] : ["virtualHalCommandScriptFixtures"]),
|
||||
];
|
||||
return {
|
||||
apiName: "project-release-browser-diagnostics-artifact-validation",
|
||||
validationVersion: 1,
|
||||
phase: missing.length === 0 ? "ready" : "blocked",
|
||||
ready: missing.length === 0,
|
||||
missing,
|
||||
artifactApiName: artifactObject.apiName ?? null,
|
||||
virtualHalReady,
|
||||
replacementReady,
|
||||
sourceComplianceReady,
|
||||
simConfigSourceCoverageReady,
|
||||
commandScriptFixturesReady,
|
||||
sourceFiles: [...new Set([
|
||||
...arrayOrEmpty(sourceCompliance.sourceFiles),
|
||||
...arrayOrEmpty(simConfigSourceCoverage.sourceFiles),
|
||||
...arrayOrEmpty(commandScriptFixtures.sourceFiles),
|
||||
])],
|
||||
rows: [
|
||||
{
|
||||
id: "artifact",
|
||||
label: "Browser diagnostics artifact",
|
||||
value: artifactObject.apiName ?? "missing",
|
||||
},
|
||||
{
|
||||
id: "virtual-hal",
|
||||
label: "Virtual HAL state",
|
||||
value: virtualHalReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "source-compliance",
|
||||
label: "Virtual HAL source compliance",
|
||||
value: sourceComplianceReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
value: simConfigSourceCoverageReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "command-script-fixtures",
|
||||
label: "Virtual HAL command script fixtures",
|
||||
value: commandScriptFixturesReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "missing",
|
||||
label: "Missing diagnostics evidence",
|
||||
value: missing.length > 0 ? missing.join(", ") : "none",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function outputContains(observedOutputs, expectedOutput) {
|
||||
return observedOutputs.some((output) => String(output).includes(expectedOutput));
|
||||
}
|
||||
@@ -470,6 +561,7 @@ export function createProjectBatchAcceptanceWorkflow({
|
||||
capabilities = [],
|
||||
gateResults = {},
|
||||
observedOutputs = [],
|
||||
virtualHalSimConfigSourceCoverage = null,
|
||||
} = {}) {
|
||||
const capabilityMatrix = createProjectBatchAcceptanceCapabilityMatrix({ capabilities });
|
||||
const gateManifest = createProjectReleaseGateManifest();
|
||||
@@ -480,10 +572,13 @@ export function createProjectBatchAcceptanceWorkflow({
|
||||
});
|
||||
const batchGatePassed = gateResultMatrix.rows
|
||||
.find(({ id }) => id === "project-batch-acceptance")?.passed === true;
|
||||
const ready = capabilityMatrix.ready && batchGatePassed;
|
||||
const virtualHalSimConfigSourceCoverageReady = virtualHalSimConfigSourceCoverage === null ||
|
||||
isVirtualHalSimConfigSourceCoverageReady(virtualHalSimConfigSourceCoverage);
|
||||
const ready = capabilityMatrix.ready && batchGatePassed && virtualHalSimConfigSourceCoverageReady;
|
||||
const missing = [
|
||||
...capabilityMatrix.missing,
|
||||
...(batchGatePassed ? [] : ["project-batch-acceptance"]),
|
||||
...(virtualHalSimConfigSourceCoverageReady ? [] : ["virtual-hal-sim-config-source-coverage"]),
|
||||
];
|
||||
|
||||
return {
|
||||
@@ -498,6 +593,8 @@ export function createProjectBatchAcceptanceWorkflow({
|
||||
capabilityMatrix,
|
||||
capabilities: capabilityMatrix.capabilities,
|
||||
rejectedCapabilities: capabilityMatrix.rejectedCapabilities,
|
||||
virtualHalSimConfigSourceCoverage,
|
||||
virtualHalSimConfigSourceCoverageReady,
|
||||
gateResultMatrix,
|
||||
missing,
|
||||
rows: [
|
||||
@@ -516,6 +613,13 @@ export function createProjectBatchAcceptanceWorkflow({
|
||||
label: "Batch acceptance gate",
|
||||
value: batchGatePassed ? "passed" : "unknown",
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
value: virtualHalSimConfigSourceCoverage === null
|
||||
? "not required"
|
||||
: (virtualHalSimConfigSourceCoverageReady ? "ready" : "missing"),
|
||||
},
|
||||
{
|
||||
id: "missing",
|
||||
label: "Missing acceptance evidence",
|
||||
@@ -649,6 +753,15 @@ export function createProjectBatchAcceptanceChecklist({
|
||||
detail: workflow?.gateResultMatrix?.rows
|
||||
?.find?.(({ id }) => id === "project-batch-acceptance")?.status ?? "unknown",
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
status: workflow?.virtualHalSimConfigSourceCoverageReady !== false ? "pass" : "blocked",
|
||||
passed: workflow?.virtualHalSimConfigSourceCoverageReady !== false,
|
||||
detail: workflow?.virtualHalSimConfigSourceCoverage === null
|
||||
? "not required"
|
||||
: (workflow?.virtualHalSimConfigSourceCoverageReady === true ? "ready" : "missing"),
|
||||
},
|
||||
{
|
||||
id: "next-action",
|
||||
label: "Next acceptance action",
|
||||
@@ -680,6 +793,7 @@ export function createProjectBatchAcceptanceReport({
|
||||
capabilities = [],
|
||||
gateResults = {},
|
||||
observedOutputs = [],
|
||||
virtualHalSimConfigSourceCoverage = null,
|
||||
} = {}) {
|
||||
const capabilityMatrix = createProjectBatchAcceptanceCapabilityMatrix({ capabilities });
|
||||
const workflow = createProjectBatchAcceptanceWorkflow({
|
||||
@@ -687,6 +801,7 @@ export function createProjectBatchAcceptanceReport({
|
||||
capabilities,
|
||||
gateResults,
|
||||
observedOutputs,
|
||||
virtualHalSimConfigSourceCoverage,
|
||||
});
|
||||
const summaryViewModel = createProjectBatchAcceptanceSummaryViewModel(workflow);
|
||||
const actionPlan = createProjectBatchAcceptanceActionPlan(workflow);
|
||||
@@ -701,6 +816,7 @@ export function createProjectBatchAcceptanceReport({
|
||||
missing: [...workflow.missing],
|
||||
capabilityMatrix,
|
||||
workflow,
|
||||
virtualHalSimConfigSourceCoverage,
|
||||
summaryViewModel,
|
||||
actionPlan,
|
||||
checklist,
|
||||
@@ -736,7 +852,12 @@ export function createProjectBatchAcceptanceReportValidation(report = {}) {
|
||||
const summaryViewModel = objectOrEmpty(reportObject.summaryViewModel);
|
||||
const actionPlan = objectOrEmpty(reportObject.actionPlan);
|
||||
const checklist = objectOrEmpty(reportObject.checklist);
|
||||
const virtualHalSimConfigSourceCoverage = objectOrEmpty(reportObject.virtualHalSimConfigSourceCoverage);
|
||||
const rows = arrayOrEmpty(reportObject.rows);
|
||||
const virtualHalSimConfigSourceCoverageRequired = reportObject.virtualHalSimConfigSourceCoverage !== null &&
|
||||
reportObject.virtualHalSimConfigSourceCoverage !== undefined;
|
||||
const virtualHalSimConfigSourceCoverageReady = !virtualHalSimConfigSourceCoverageRequired ||
|
||||
isVirtualHalSimConfigSourceCoverageReady(virtualHalSimConfigSourceCoverage);
|
||||
const missing = [
|
||||
...(reportObject.apiName === "project-batch-acceptance-report" ? [] : ["apiName"]),
|
||||
...(reportObject.reportVersion === 1 ? [] : ["reportVersion"]),
|
||||
@@ -760,7 +881,8 @@ export function createProjectBatchAcceptanceReportValidation(report = {}) {
|
||||
...(checklist.apiName === "project-batch-acceptance-checklist" && checklist.ready === true
|
||||
? []
|
||||
: ["checklist"]),
|
||||
...(rows.find(({ id, value }) => id === "checklist" && value === "3/3 passed")
|
||||
...(virtualHalSimConfigSourceCoverageReady ? [] : ["virtualHalSimConfigSourceCoverage"]),
|
||||
...(rows.find(({ id, value }) => id === "checklist" && /^([34])\/\1 passed$/.test(value))
|
||||
? []
|
||||
: ["rows.checklist"]),
|
||||
];
|
||||
@@ -795,6 +917,13 @@ export function createProjectBatchAcceptanceReportValidation(report = {}) {
|
||||
label: "Checklist",
|
||||
value: checklist.ready === true ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
value: virtualHalSimConfigSourceCoverageRequired
|
||||
? (virtualHalSimConfigSourceCoverageReady ? "ready" : "missing")
|
||||
: "not required",
|
||||
},
|
||||
{
|
||||
id: "missing",
|
||||
label: "Missing report evidence",
|
||||
@@ -1251,6 +1380,7 @@ export function createProjectReleaseReadinessReport({
|
||||
gateResults = {},
|
||||
observedOutputs = [],
|
||||
simConfigInventory = DEFAULT_SIM_CONFIG_INVENTORY_BASELINE,
|
||||
virtualHalSimConfigSourceCoverage = null,
|
||||
blockedRuntimeFamilies = BLOCKED_RUNTIME_FAMILIES,
|
||||
promotedRuntimeFamilies = [],
|
||||
axisScreenshotArtifacts = [],
|
||||
@@ -1283,13 +1413,21 @@ export function createProjectReleaseReadinessReport({
|
||||
const promotedFamilies = [...promotedRuntimeFamilies];
|
||||
const promotedBlockedFamilies = promotedFamilies.filter((family) => blockedFamilies.includes(family));
|
||||
const inventoryReady = inventory.unexpectedFail === 0;
|
||||
const virtualHalSimConfigSourceCoverageReady = isVirtualHalSimConfigSourceCoverageReady(
|
||||
virtualHalSimConfigSourceCoverage,
|
||||
);
|
||||
const blockedRuntimeReady = promotedBlockedFamilies.length === 0;
|
||||
const axisScreenshotArtifactSummary = createAxisScreenshotArtifactSummary(axisScreenshotArtifacts);
|
||||
const axisScreenshotArtifactsReady = axisScreenshotArtifactSummary.ready;
|
||||
const ready = releaseGatePassed && inventoryReady && blockedRuntimeReady && axisScreenshotArtifactsReady;
|
||||
const ready = releaseGatePassed &&
|
||||
inventoryReady &&
|
||||
virtualHalSimConfigSourceCoverageReady &&
|
||||
blockedRuntimeReady &&
|
||||
axisScreenshotArtifactsReady;
|
||||
const missing = [
|
||||
...(releaseGatePassed ? [] : ["project-release-gate"]),
|
||||
...(inventoryReady ? [] : ["sim-config-inventory"]),
|
||||
...(virtualHalSimConfigSourceCoverageReady ? [] : ["virtual-hal-sim-config-source-coverage"]),
|
||||
...(blockedRuntimeReady ? [] : ["blocked-runtime-families"]),
|
||||
...(axisScreenshotArtifactsReady ? [] : ["axis-screenshot-artifacts"]),
|
||||
];
|
||||
@@ -1306,6 +1444,8 @@ export function createProjectReleaseReadinessReport({
|
||||
expectedOutput: "project_release_gate=ok",
|
||||
},
|
||||
simConfigInventory: inventory,
|
||||
virtualHalSimConfigSourceCoverage,
|
||||
virtualHalSimConfigSourceCoverageReady,
|
||||
blockedRuntimeFamilies: blockedFamilies,
|
||||
promotedRuntimeFamilies: promotedFamilies,
|
||||
promotedBlockedFamilies,
|
||||
@@ -1327,6 +1467,11 @@ export function createProjectReleaseReadinessReport({
|
||||
label: "Sim config inventory",
|
||||
value: `unexpected_fail=${inventory.unexpectedFail}`,
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
value: virtualHalSimConfigSourceCoverageReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "blocked-runtime-families",
|
||||
label: "Blocked runtime families",
|
||||
@@ -1349,6 +1494,7 @@ export function createProjectReleaseReadinessSummaryViewModel(
|
||||
const missing = Array.isArray(report?.missing) ? report.missing : [];
|
||||
const gateResultMatrix = objectOrEmpty(report?.gateResultMatrix);
|
||||
const simConfigInventory = objectOrEmpty(report?.simConfigInventory);
|
||||
const virtualHalSimConfigSourceCoverageReady = report?.virtualHalSimConfigSourceCoverageReady === true;
|
||||
const axisScreenshotArtifactSummary = objectOrEmpty(report?.axisScreenshotArtifactSummary);
|
||||
const blockedRuntimeFamilies = arrayOrEmpty(report?.blockedRuntimeFamilies);
|
||||
const promotedBlockedFamilies = arrayOrEmpty(report?.promotedBlockedFamilies);
|
||||
@@ -1380,6 +1526,11 @@ export function createProjectReleaseReadinessSummaryViewModel(
|
||||
label: "Sim config inventory",
|
||||
value: `unexpected_fail=${simConfigInventory.unexpectedFail ?? "unknown"}`,
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
value: virtualHalSimConfigSourceCoverageReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "blocked-runtime-families",
|
||||
label: "Blocked runtime families",
|
||||
@@ -1457,6 +1608,11 @@ export function createProjectReleaseReadinessArtifactValidationSummaryViewModel(
|
||||
label: "Gate action plan",
|
||||
value: validation?.gateActionPlanReady === true ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
value: validation?.virtualHalSimConfigSourceCoverageReady === true ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "missing",
|
||||
label: "Missing artifact evidence",
|
||||
@@ -1609,14 +1765,19 @@ export function createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson
|
||||
|
||||
export async function loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||
artifactUrl = "",
|
||||
diagnosticsUrl = "",
|
||||
fetchRef = globalThis.fetch,
|
||||
} = {}) {
|
||||
if (!artifactUrl || typeof fetchRef !== "function") {
|
||||
const jsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson: "" });
|
||||
const diagnosticsValidation = diagnosticsUrl
|
||||
? createProjectReleaseBrowserDiagnosticsArtifactValidation({})
|
||||
: null;
|
||||
const missing = [
|
||||
...(artifactUrl ? [] : ["artifact-url"]),
|
||||
...(typeof fetchRef === "function" ? [] : ["fetch"]),
|
||||
...jsonWorkflow.missing,
|
||||
...(diagnosticsUrl ? ["diagnostics-fetch", ...diagnosticsValidation.missing.map((item) => `diagnostics.${item}`)] : []),
|
||||
];
|
||||
return {
|
||||
apiName: "project-release-readiness-artifact-url-workflow",
|
||||
@@ -1624,11 +1785,16 @@ export async function loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||
phase: "blocked",
|
||||
ready: false,
|
||||
artifactUrl,
|
||||
diagnosticsUrl,
|
||||
fetched: false,
|
||||
diagnosticsFetched: false,
|
||||
httpStatus: null,
|
||||
diagnosticsHttpStatus: null,
|
||||
fetchError: null,
|
||||
diagnosticsFetchError: null,
|
||||
jsonWorkflow,
|
||||
validation: jsonWorkflow.validation,
|
||||
diagnosticsValidation,
|
||||
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||
actionPlan: jsonWorkflow.actionPlan,
|
||||
missing,
|
||||
@@ -1664,14 +1830,23 @@ export async function loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||
phase: "blocked",
|
||||
ready: false,
|
||||
artifactUrl,
|
||||
diagnosticsUrl,
|
||||
fetched: false,
|
||||
diagnosticsFetched: false,
|
||||
httpStatus,
|
||||
diagnosticsHttpStatus: null,
|
||||
fetchError,
|
||||
diagnosticsFetchError: null,
|
||||
jsonWorkflow,
|
||||
validation: jsonWorkflow.validation,
|
||||
diagnosticsValidation: diagnosticsUrl ? createProjectReleaseBrowserDiagnosticsArtifactValidation({}) : null,
|
||||
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||
actionPlan: jsonWorkflow.actionPlan,
|
||||
missing: ["artifact-fetch", ...jsonWorkflow.missing],
|
||||
missing: [
|
||||
"artifact-fetch",
|
||||
...jsonWorkflow.missing,
|
||||
...(diagnosticsUrl ? ["diagnostics-fetch"] : []),
|
||||
],
|
||||
rows: [
|
||||
{
|
||||
id: "fetch",
|
||||
@@ -1694,20 +1869,56 @@ export async function loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||
|
||||
const artifactJson = await response.text();
|
||||
const jsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson });
|
||||
let diagnosticsFetched = false;
|
||||
let diagnosticsHttpStatus = null;
|
||||
let diagnosticsFetchError = null;
|
||||
let diagnosticsValidation = null;
|
||||
const diagnosticsMissing = [];
|
||||
if (diagnosticsUrl) {
|
||||
try {
|
||||
const diagnosticsResponse = await fetchRef(diagnosticsUrl);
|
||||
diagnosticsHttpStatus = diagnosticsResponse?.status ?? null;
|
||||
if (!diagnosticsResponse?.ok) {
|
||||
diagnosticsFetchError = `diagnostics artifact URL fetch failed${diagnosticsHttpStatus ? `: ${diagnosticsHttpStatus}` : ""}`;
|
||||
diagnosticsMissing.push("diagnostics-fetch");
|
||||
diagnosticsValidation = createProjectReleaseBrowserDiagnosticsArtifactValidation({});
|
||||
} else {
|
||||
diagnosticsFetched = true;
|
||||
const diagnosticsArtifact = JSON.parse(await diagnosticsResponse.text());
|
||||
diagnosticsValidation = createProjectReleaseBrowserDiagnosticsArtifactValidation(diagnosticsArtifact);
|
||||
diagnosticsMissing.push(...diagnosticsValidation.missing.map((item) => `diagnostics.${item}`));
|
||||
}
|
||||
} catch (error) {
|
||||
diagnosticsFetchError = error?.message ?? "diagnostics artifact URL fetch error";
|
||||
diagnosticsValidation = createProjectReleaseBrowserDiagnosticsArtifactValidation({});
|
||||
diagnosticsMissing.push("diagnostics-fetch");
|
||||
}
|
||||
}
|
||||
const missing = [
|
||||
...jsonWorkflow.missing,
|
||||
...diagnosticsMissing,
|
||||
];
|
||||
const ready = jsonWorkflow.ready === true &&
|
||||
(!diagnosticsUrl || diagnosticsValidation?.ready === true);
|
||||
return {
|
||||
apiName: "project-release-readiness-artifact-url-workflow",
|
||||
workflowVersion: 1,
|
||||
phase: jsonWorkflow.ready === true ? "ready" : "blocked",
|
||||
ready: jsonWorkflow.ready === true,
|
||||
phase: ready ? "ready" : "blocked",
|
||||
ready,
|
||||
artifactUrl,
|
||||
diagnosticsUrl,
|
||||
fetched: true,
|
||||
diagnosticsFetched,
|
||||
httpStatus,
|
||||
diagnosticsHttpStatus,
|
||||
fetchError: null,
|
||||
diagnosticsFetchError,
|
||||
jsonWorkflow,
|
||||
validation: jsonWorkflow.validation,
|
||||
diagnosticsValidation,
|
||||
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||
actionPlan: jsonWorkflow.actionPlan,
|
||||
missing: jsonWorkflow.missing,
|
||||
missing,
|
||||
rows: [
|
||||
{
|
||||
id: "fetch",
|
||||
@@ -1719,6 +1930,13 @@ export async function loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||
label: "Artifact JSON workflow",
|
||||
value: jsonWorkflow.ready === true ? "ready" : "blocked",
|
||||
},
|
||||
{
|
||||
id: "diagnostics-workflow",
|
||||
label: "Browser diagnostics workflow",
|
||||
value: diagnosticsUrl
|
||||
? (diagnosticsValidation?.ready === true ? "ready" : "blocked")
|
||||
: "not requested",
|
||||
},
|
||||
{
|
||||
id: "next-command",
|
||||
label: "Next command",
|
||||
@@ -1734,14 +1952,23 @@ export async function loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||
phase: "blocked",
|
||||
ready: false,
|
||||
artifactUrl,
|
||||
diagnosticsUrl,
|
||||
fetched: false,
|
||||
diagnosticsFetched: false,
|
||||
httpStatus: null,
|
||||
diagnosticsHttpStatus: null,
|
||||
fetchError: error?.message ?? "artifact URL fetch error",
|
||||
diagnosticsFetchError: null,
|
||||
jsonWorkflow,
|
||||
validation: jsonWorkflow.validation,
|
||||
diagnosticsValidation: diagnosticsUrl ? createProjectReleaseBrowserDiagnosticsArtifactValidation({}) : null,
|
||||
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||
actionPlan: jsonWorkflow.actionPlan,
|
||||
missing: ["artifact-fetch", ...jsonWorkflow.missing],
|
||||
missing: [
|
||||
"artifact-fetch",
|
||||
...jsonWorkflow.missing,
|
||||
...(diagnosticsUrl ? ["diagnostics-fetch"] : []),
|
||||
],
|
||||
rows: [
|
||||
{
|
||||
id: "fetch",
|
||||
@@ -1802,6 +2029,13 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
|
||||
label: "Artifact validation",
|
||||
value: workflow?.validation?.ready === true ? "ready" : "blocked",
|
||||
},
|
||||
{
|
||||
id: "browser-diagnostics",
|
||||
label: "Browser diagnostics",
|
||||
value: workflow?.diagnosticsUrl
|
||||
? (workflow?.diagnosticsValidation?.ready === true ? "ready" : "blocked")
|
||||
: "not requested",
|
||||
},
|
||||
{
|
||||
id: "next-command",
|
||||
label: "Next command",
|
||||
@@ -1850,6 +2084,15 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowActionPlan(
|
||||
expectedOutput: null,
|
||||
}]
|
||||
: []),
|
||||
...(missing.includes("diagnostics-fetch")
|
||||
? [{
|
||||
id: "verify-diagnostics-url-fetch",
|
||||
label: "Verify browser diagnostics artifact URL fetch",
|
||||
kind: "fetch",
|
||||
command: null,
|
||||
expectedOutput: null,
|
||||
}]
|
||||
: []),
|
||||
];
|
||||
const commandActions = validationCommands.map((command) => ({
|
||||
id: command.id ?? command.gateId ?? `command-${command.step}`,
|
||||
@@ -1902,6 +2145,7 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
const artifactObject = objectOrEmpty(artifact);
|
||||
const releaseGate = objectOrEmpty(artifactObject.releaseGate);
|
||||
const simConfigInventory = objectOrEmpty(artifactObject.simConfigInventory);
|
||||
const virtualHalSimConfigSourceCoverage = objectOrEmpty(artifactObject.virtualHalSimConfigSourceCoverage);
|
||||
const gateManifest = objectOrEmpty(artifactObject.gateManifest);
|
||||
const gateExecutionManifest = objectOrEmpty(artifactObject.gateExecutionManifest);
|
||||
const gateExecutionSummaryViewModel = objectOrEmpty(artifactObject.gateExecutionSummaryViewModel);
|
||||
@@ -1947,6 +2191,9 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
&& gateActionPlan.pendingCount === 0
|
||||
&& gateActionPlan.nextCommand === null
|
||||
&& actionPlanCommands.length === 0;
|
||||
const virtualHalSimConfigSourceCoverageReady = isVirtualHalSimConfigSourceCoverageReady(
|
||||
virtualHalSimConfigSourceCoverage,
|
||||
) && artifactObject.virtualHalSimConfigSourceCoverageReady === true;
|
||||
const axisScreenshotArtifacts = arrayOrEmpty(axisScreenshotArtifactSummary.artifacts);
|
||||
const axisScreenshotSummaryReady = !axisScreenshotArtifactSummary.apiName
|
||||
|| axisScreenshotArtifacts.length === 0
|
||||
@@ -1984,6 +2231,7 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
...(simConfigInventory.passed === 28 ? [] : ["simConfigInventory.passed"]),
|
||||
...(simConfigInventory.skipped === 131 ? [] : ["simConfigInventory.skipped"]),
|
||||
...(simConfigInventory.unexpectedFail === 0 ? [] : ["simConfigInventory.unexpectedFail"]),
|
||||
...(virtualHalSimConfigSourceCoverageReady ? [] : ["virtualHalSimConfigSourceCoverage"]),
|
||||
...(arrayOrEmpty(artifactObject.blockedRuntimeFamilies).join(",") === BLOCKED_RUNTIME_FAMILIES.join(",")
|
||||
? []
|
||||
: ["blockedRuntimeFamilies"]),
|
||||
@@ -2017,6 +2265,7 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
gateExecutionSummaryReady: executionSummaryReady,
|
||||
gateResultMatrixReady: matrixReady,
|
||||
gateActionPlanReady: actionPlanReady,
|
||||
virtualHalSimConfigSourceCoverageReady,
|
||||
axisScreenshotArtifactSummaryReady: axisScreenshotSummaryReady,
|
||||
axisScreenshotArtifactCount: axisScreenshotArtifacts.length,
|
||||
blockedRuntimeFamilies: arrayOrEmpty(artifactObject.blockedRuntimeFamilies),
|
||||
@@ -2056,6 +2305,11 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
label: "Gate action plan",
|
||||
value: actionPlanReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-sim-config-source-coverage",
|
||||
label: "Virtual HAL sim-config source coverage",
|
||||
value: virtualHalSimConfigSourceCoverageReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "axis-screenshot-artifacts",
|
||||
label: "AXIS screenshot artifacts",
|
||||
|
||||
Reference in New Issue
Block a user