新增项目发布 gate action plan API
This commit is contained in:
@@ -51,6 +51,7 @@ import {
|
||||
createMachineSessionPersistenceRenderState,
|
||||
createMachineSessionPersistenceSummary,
|
||||
createMachineSessionSnapshotPayload,
|
||||
createProjectReleaseGateActionPlan,
|
||||
createProjectReleaseGateManifest,
|
||||
createProjectReleaseGateResultMatrix,
|
||||
createProjectReleaseReadinessArtifactValidation,
|
||||
@@ -196,11 +197,15 @@ It does not implement or reinterpret LinuxCNC error semantics.
|
||||
commands, expected smoke outputs, and gate count for CI dashboards and external
|
||||
SDK callers. `createProjectReleaseGateResultMatrix()` maps observed gate output
|
||||
and explicit gate results onto that manifest as stable `passed`/`unknown` rows.
|
||||
`createProjectReleaseGateActionPlan()` turns that matrix into pending gate
|
||||
commands, the next gate command, stable display rows, and a shell script that
|
||||
external CI can execute or show without duplicating the manifest order.
|
||||
`createProjectReleaseReadinessReport()` returns a machine-readable release
|
||||
readiness report that embeds the same manifest and result matrix beside the
|
||||
sim-config inventory baseline and blocked runtime families. It is evidence
|
||||
driven: the default report is `ready: false` until the caller supplies observed
|
||||
gate output such as `project_release_gate=ok` or explicit gate results.
|
||||
readiness report that embeds the same manifest, result matrix, and action plan
|
||||
beside the sim-config inventory baseline and blocked runtime families. It is
|
||||
evidence driven: the default report is `ready: false` until the caller supplies
|
||||
observed gate output such as `project_release_gate=ok` or explicit gate
|
||||
results.
|
||||
`createProjectReleaseReadinessSummaryViewModel()` turns the report into stable
|
||||
status text, a status line, and display rows for dashboards without executing
|
||||
any gate.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export { createLinuxCncIniSdk } from "./linuxcnc-ini.js";
|
||||
export { createLinuxCncInterpSdk } from "./linuxcnc-interp.js";
|
||||
export {
|
||||
createProjectReleaseGateActionPlan,
|
||||
createProjectReleaseGateManifest,
|
||||
createProjectReleaseGateResultMatrix,
|
||||
createProjectReleaseReadinessArtifactValidation,
|
||||
|
||||
@@ -145,6 +145,59 @@ export function createProjectReleaseGateResultMatrix({
|
||||
};
|
||||
}
|
||||
|
||||
export function createProjectReleaseGateActionPlan({
|
||||
gateResultMatrix = null,
|
||||
gateResults = {},
|
||||
observedOutputs = [],
|
||||
manifest = createProjectReleaseGateManifest(),
|
||||
} = {}) {
|
||||
const matrix = gateResultMatrix && typeof gateResultMatrix === "object"
|
||||
? gateResultMatrix
|
||||
: createProjectReleaseGateResultMatrix({ gateResults, observedOutputs, manifest });
|
||||
const rows = Array.isArray(matrix.rows) ? matrix.rows : [];
|
||||
const pendingRows = rows.filter(({ passed }) => passed !== true);
|
||||
const completedRows = rows.filter(({ passed }) => passed === true);
|
||||
const commands = pendingRows.map((gate, index) => ({
|
||||
step: index + 1,
|
||||
gateId: gate.id,
|
||||
label: gate.label,
|
||||
command: gate.command,
|
||||
expectedOutput: gate.expectedOutput ?? null,
|
||||
}));
|
||||
const nextGate = commands[0] ?? null;
|
||||
const shellScript = commands.length > 0
|
||||
? [
|
||||
"#!/usr/bin/env bash",
|
||||
"set -euo pipefail",
|
||||
"",
|
||||
...commands.map(({ command }) => command),
|
||||
"",
|
||||
].join("\n")
|
||||
: "# Project release gates are already marked passed.\n";
|
||||
|
||||
return {
|
||||
apiName: "project-release-gate-action-plan",
|
||||
planVersion: 1,
|
||||
phase: commands.length === 0 ? "ready" : "waiting",
|
||||
ready: commands.length === 0,
|
||||
gateCount: rows.length,
|
||||
completedCount: completedRows.length,
|
||||
pendingCount: pendingRows.length,
|
||||
completedGateIds: completedRows.map(({ id }) => id),
|
||||
pendingGateIds: pendingRows.map(({ id }) => id),
|
||||
nextGateId: nextGate?.gateId ?? null,
|
||||
nextCommand: nextGate?.command ?? null,
|
||||
commands,
|
||||
shellScript,
|
||||
rows: commands.map(({ gateId, label, command, expectedOutput }) => ({
|
||||
id: gateId,
|
||||
label,
|
||||
value: command,
|
||||
expectedOutput,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export function createProjectReleaseReadinessReport({
|
||||
gateResults = {},
|
||||
observedOutputs = [],
|
||||
@@ -158,6 +211,10 @@ export function createProjectReleaseReadinessReport({
|
||||
observedOutputs,
|
||||
manifest: gateManifest,
|
||||
});
|
||||
const gateActionPlan = createProjectReleaseGateActionPlan({
|
||||
gateResultMatrix,
|
||||
manifest: gateManifest,
|
||||
});
|
||||
const gateRows = gateResultMatrix.rows;
|
||||
const releaseGatePassed = gateRows.find(({ id }) => id === "project-release-gate")?.passed === true;
|
||||
const inventory = {
|
||||
@@ -193,6 +250,7 @@ export function createProjectReleaseReadinessReport({
|
||||
promotedBlockedFamilies,
|
||||
gateManifest,
|
||||
gateResultMatrix,
|
||||
gateActionPlan,
|
||||
gates: gateRows,
|
||||
rows: [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user