新增 release artifact URL workflow SDK API
This commit is contained in:
@@ -9,7 +9,7 @@ turn-by-turn continuation notes and next-batch execution records.
|
|||||||
## Current Status
|
## Current Status
|
||||||
|
|
||||||
- Active continuation file: `text14.txt`
|
- Active continuation file: `text14.txt`
|
||||||
- Latest completed batch: project release readiness artifact JSON workflow API
|
- Latest completed batch: project release readiness artifact URL workflow SDK API
|
||||||
- Latest relevant commit: use `git log -1 --oneline` after each committed batch
|
- Latest relevant commit: use `git log -1 --oneline` after each committed batch
|
||||||
- Working tree at tracker creation: clean
|
- Working tree at tracker creation: clean
|
||||||
- Required policy: LinuxCNC remains the only CNC semantic source
|
- Required policy: LinuxCNC remains the only CNC semantic source
|
||||||
@@ -43,7 +43,7 @@ The project is complete for the current scope when all of the following are true
|
|||||||
| Native nc_files baseline | Stable | Last recorded Layer 1: `total 107`, `pass 101`, `expected_fail 6`, `unexpected_fail 0`. |
|
| Native nc_files baseline | Stable | Last recorded Layer 1: `total 107`, `pass 101`, `expected_fail 6`, `unexpected_fail 0`. |
|
||||||
| Native sim configs baseline | Stable | Last recorded Layer 2: `total 159`, `pass 151`, `expected_fail 8`, `unexpected_fail 0`. |
|
| Native sim configs baseline | Stable | Last recorded Layer 2: `total 159`, `pass 151`, `expected_fail 8`, `unexpected_fail 0`. |
|
||||||
| OPFS/session persistence | Stable for current scope | Browser smoke passes, SDK re-exports OPFS/session helpers including `readMachineSessionReadiness()` and `createMachineSessionPersistenceSummary()`, the UI exposes `getMachineSessionPersistenceSummary()`, and `docs/opfs-session-persistence.md` defines the project-level release gate. |
|
| OPFS/session persistence | Stable for current scope | Browser smoke passes, SDK re-exports OPFS/session helpers including `readMachineSessionReadiness()` and `createMachineSessionPersistenceSummary()`, the UI exposes `getMachineSessionPersistenceSummary()`, and `docs/opfs-session-persistence.md` defines the project-level release gate. |
|
||||||
| SDK/API surface | Stable for current scope | SDK re-exports core, OPFS/session readiness/load helpers, sim-config staging, project release gate manifest/result matrix/action-plan/readiness summary view-model, project release readiness report/artifact JSON workflow/artifact validation summary/action-plan plus URL loading workflow, INI panel entry/launcher/control-page/shell/workflow overview helpers, the session readiness workflow report, and the shell API surface inventory with a Node surface smoke. |
|
| SDK/API surface | Stable for current scope | SDK re-exports core, OPFS/session readiness/load helpers, sim-config staging, project release gate manifest/result matrix/action-plan/readiness summary view-model, project release readiness report/artifact JSON workflow/artifact URL workflow/artifact validation summary/action-plan plus URL loading workflow, INI panel entry/launcher/control-page/shell/workflow overview helpers, the session readiness workflow report, and the shell API surface inventory with a Node surface smoke. |
|
||||||
| Browser/UI workflow | Stable for current scope | Workflow overview embedding mount DOM closure is complete, and INI panel session workflows plus read-only control/shell handoff expose, render, fetch, validate, summarize, and report OPFS/session readiness, OPFS/session persistence summary, release readiness artifact validation/rendering/URL workflow summaries, and API surface inventory before loading or reading WASM session state. |
|
| Browser/UI workflow | Stable for current scope | Workflow overview embedding mount DOM closure is complete, and INI panel session workflows plus read-only control/shell handoff expose, render, fetch, validate, summarize, and report OPFS/session readiness, OPFS/session persistence summary, release readiness artifact validation/rendering/URL workflow summaries, and API surface inventory before loading or reading WASM session state. |
|
||||||
| Workflow overview embedding | Stable for current scope | Report/display/render, DOM contract/readiness/renderer, mount result/display/render, mount DOM contract/readiness/renderer/wrapper exist. |
|
| Workflow overview embedding | Stable for current scope | Report/display/render, DOM contract/readiness/renderer, mount result/display/render, mount DOM contract/readiness/renderer/wrapper exist. |
|
||||||
| Host/runtime boundary proof | Stable blocked state | Host smoke passes; runtime families remain blocked and `docs/host-runtime-boundary-handoff.md` records host readiness, promotion blockers, dispatch, and evidence gates. |
|
| Host/runtime boundary proof | Stable blocked state | Host smoke passes; runtime families remain blocked and `docs/host-runtime-boundary-handoff.md` records host readiness, promotion blockers, dispatch, and evidence gates. |
|
||||||
|
|||||||
63
text14.txt
63
text14.txt
@@ -3308,6 +3308,69 @@ ui_node_smokes=ok
|
|||||||
继续只做实质能力推进。优先选择可执行 gate、SDK/API surface、或真实 browser workflow;
|
继续只做实质能力推进。优先选择可执行 gate、SDK/API surface、或真实 browser workflow;
|
||||||
不要做只整理断言或局部常量化的批次。
|
不要做只整理断言或局部常量化的批次。
|
||||||
|
|
||||||
|
五十三、2026-06-16 继续执行记录:project release readiness artifact URL workflow SDK API
|
||||||
|
|
||||||
|
本轮继续按“每批必须产出可调用 API、可验证 workflow、可执行 gate、或真实 UI/browser 能力”推进,
|
||||||
|
把 release readiness artifact 从 JSON 文本 workflow 推进到 SDK 侧 URL workflow。外部 CI/dashboard
|
||||||
|
现在可以传入 artifact URL 和 caller-provided fetch,一次得到 fetch 状态、JSON workflow、artifact
|
||||||
|
validation、summary view-model、action-plan、missing 和 display rows。
|
||||||
|
|
||||||
|
完成内容:
|
||||||
|
|
||||||
|
- `runtime/sdk/src/project-release-readiness.js` 新增:
|
||||||
|
- `loadProjectReleaseReadinessArtifactUrlWorkflow()`;
|
||||||
|
- 新 URL workflow 返回:
|
||||||
|
- `apiName: project-release-readiness-artifact-url-workflow`;
|
||||||
|
- `workflowVersion: 1`;
|
||||||
|
- `phase/ready`;
|
||||||
|
- `artifactUrl/fetched/httpStatus/fetchError`;
|
||||||
|
- `jsonWorkflow`;
|
||||||
|
- `validation`;
|
||||||
|
- `summaryViewModel`;
|
||||||
|
- `actionPlan`;
|
||||||
|
- `missing`;
|
||||||
|
- display `rows[]`;
|
||||||
|
- ready URL fetch 返回 ready workflow、ready JSON workflow 和空 action-plan commands;
|
||||||
|
- missing URL/fetch 返回 blocked workflow 和结构化 missing;
|
||||||
|
- HTTP failure 返回 blocked workflow、`artifact-fetch` missing 和 next-command action-plan;
|
||||||
|
- thrown fetch error 返回 blocked workflow,不向外抛异常;
|
||||||
|
- `runtime/sdk/src/index.js` re-export 新 URL workflow API;
|
||||||
|
- `verify_project_release_gate_manifest.mjs` 覆盖 ready URL、missing URL/fetch 和 HTTP failure;
|
||||||
|
- `verify_sdk_surface.mjs` 覆盖 SDK export、README 可发现性、ready summary 和 HTTP failure missing;
|
||||||
|
- `runtime/sdk/README.md`、`docs/project-release-handoff.md`、`verify_project_release_handoff_docs.mjs`
|
||||||
|
记录 URL workflow API;
|
||||||
|
- `PROJECT_COMPLETION_TRACKER.md` 同步 latest completed batch 和 SDK/API surface 状态;
|
||||||
|
- 未新增控制按钮;
|
||||||
|
- 未执行 release gate/action-plan;
|
||||||
|
- 未解析 G-code;
|
||||||
|
- 未解释 canonical events;
|
||||||
|
- 未新增 JS CNC 语义;
|
||||||
|
- 未运行 opt-in runtime probes;
|
||||||
|
- 未 promotion blocked runtime family;
|
||||||
|
- 未改变 LinuxCNC interpreter、tool、parameter、planner、kinematics、remap 或 LinuxCNC-owned
|
||||||
|
runtime semantics。
|
||||||
|
|
||||||
|
验证已通过(先行 targeted):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wasm-port/tests/sdk/node/verify_project_release_gate_manifest.sh
|
||||||
|
wasm-port/tests/sdk/node/verify_sdk_surface.sh
|
||||||
|
wasm-port/tests/docs/node/verify_project_release_handoff_docs.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
关键输出:
|
||||||
|
|
||||||
|
```text
|
||||||
|
project_release_gate_manifest_node_smoke=ok
|
||||||
|
sdk_surface_node_smoke=ok
|
||||||
|
project_release_handoff_docs_node_smoke=ok
|
||||||
|
```
|
||||||
|
|
||||||
|
下一步工作计划:
|
||||||
|
|
||||||
|
继续只做实质能力推进。优先选择可执行 gate、SDK/API surface、或真实 browser workflow;
|
||||||
|
不要做只整理断言或局部常量化的批次。
|
||||||
|
|
||||||
五十二、2026-06-16 继续执行记录:project release readiness artifact JSON workflow API
|
五十二、2026-06-16 继续执行记录:project release readiness artifact JSON workflow API
|
||||||
|
|
||||||
本轮继续按“每批必须产出可调用 API、可验证 workflow、可执行 gate、或真实 UI/browser 能力”推进,
|
本轮继续按“每批必须产出可调用 API、可验证 workflow、可执行 gate、或真实 UI/browser 能力”推进,
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ continuation records are in `../text14.txt`.
|
|||||||
`createProjectReleaseReadinessArtifactJsonWorkflow()` is the one-call
|
`createProjectReleaseReadinessArtifactJsonWorkflow()` is the one-call
|
||||||
non-throwing JSON text workflow for dashboards that need parse, validation,
|
non-throwing JSON text workflow for dashboards that need parse, validation,
|
||||||
summary, and action-plan output from the readiness artifact.
|
summary, and action-plan output from the readiness artifact.
|
||||||
|
`loadProjectReleaseReadinessArtifactUrlWorkflow()` provides the same
|
||||||
|
SDK-side workflow from an artifact URL and caller-provided fetch
|
||||||
|
implementation, including fetch status and next-command output.
|
||||||
Browser shells can also pass the JSON to
|
Browser shells can also pass the JSON to
|
||||||
`linuxCncIniPanelWorkflowOverviewApi.validateWorkflowOverviewReleaseReadinessArtifactJson()`
|
`linuxCncIniPanelWorkflowOverviewApi.validateWorkflowOverviewReleaseReadinessArtifactJson()`
|
||||||
through the workflow overview iframe and receive stable validation rows. They
|
through the workflow overview iframe and receive stable validation rows. They
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ import {
|
|||||||
isSupportedIniPanelLaunchApiManifest,
|
isSupportedIniPanelLaunchApiManifest,
|
||||||
isSupportedIniPanelShellIntegrationManifest,
|
isSupportedIniPanelShellIntegrationManifest,
|
||||||
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
||||||
|
loadProjectReleaseReadinessArtifactUrlWorkflow,
|
||||||
loadMachineSessionFromOpfs,
|
loadMachineSessionFromOpfs,
|
||||||
loadMachineSessionSnapshot,
|
loadMachineSessionSnapshot,
|
||||||
loadMachineTextFiles,
|
loadMachineTextFiles,
|
||||||
@@ -243,6 +244,10 @@ one-call wrapper for dashboards that receive artifact JSON text. It parses,
|
|||||||
validates, builds the validation summary, and builds the action plan. Invalid
|
validates, builds the validation summary, and builds the action plan. Invalid
|
||||||
JSON returns a blocked workflow with `parsed: false` and the same next-command
|
JSON returns a blocked workflow with `parsed: false` and the same next-command
|
||||||
action plan instead of throwing.
|
action plan instead of throwing.
|
||||||
|
`loadProjectReleaseReadinessArtifactUrlWorkflow()` is the SDK-side URL workflow
|
||||||
|
for callers that supply a `fetch` implementation. It fetches the artifact URL,
|
||||||
|
runs the JSON workflow, and returns fetch status, validation, summary, and
|
||||||
|
action-plan output without executing release gates.
|
||||||
|
|
||||||
## OPFS/session persistence exports
|
## OPFS/session persistence exports
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export {
|
|||||||
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
||||||
createProjectReleaseReadinessReport,
|
createProjectReleaseReadinessReport,
|
||||||
createProjectReleaseReadinessSummaryViewModel,
|
createProjectReleaseReadinessSummaryViewModel,
|
||||||
|
loadProjectReleaseReadinessArtifactUrlWorkflow,
|
||||||
parseProjectReleaseReadinessArtifactJson,
|
parseProjectReleaseReadinessArtifactJson,
|
||||||
} from "./project-release-readiness.js";
|
} from "./project-release-readiness.js";
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -518,6 +518,162 @@ export function createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||||
|
artifactUrl = "",
|
||||||
|
fetchRef = globalThis.fetch,
|
||||||
|
} = {}) {
|
||||||
|
if (!artifactUrl || typeof fetchRef !== "function") {
|
||||||
|
const jsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson: "" });
|
||||||
|
const missing = [
|
||||||
|
...(artifactUrl ? [] : ["artifact-url"]),
|
||||||
|
...(typeof fetchRef === "function" ? [] : ["fetch"]),
|
||||||
|
...jsonWorkflow.missing,
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
apiName: "project-release-readiness-artifact-url-workflow",
|
||||||
|
workflowVersion: 1,
|
||||||
|
phase: "blocked",
|
||||||
|
ready: false,
|
||||||
|
artifactUrl,
|
||||||
|
fetched: false,
|
||||||
|
httpStatus: null,
|
||||||
|
fetchError: null,
|
||||||
|
jsonWorkflow,
|
||||||
|
validation: jsonWorkflow.validation,
|
||||||
|
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||||
|
actionPlan: jsonWorkflow.actionPlan,
|
||||||
|
missing,
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
id: "fetch",
|
||||||
|
label: "Artifact URL fetch",
|
||||||
|
value: "blocked",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "json-workflow",
|
||||||
|
label: "Artifact JSON workflow",
|
||||||
|
value: "blocked",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "next-command",
|
||||||
|
label: "Next command",
|
||||||
|
value: jsonWorkflow.actionPlan.nextCommand ?? "none",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetchRef(artifactUrl);
|
||||||
|
const httpStatus = response?.status ?? null;
|
||||||
|
if (!response?.ok) {
|
||||||
|
const jsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson: "" });
|
||||||
|
const fetchError = `artifact URL fetch failed${httpStatus ? `: ${httpStatus}` : ""}`;
|
||||||
|
return {
|
||||||
|
apiName: "project-release-readiness-artifact-url-workflow",
|
||||||
|
workflowVersion: 1,
|
||||||
|
phase: "blocked",
|
||||||
|
ready: false,
|
||||||
|
artifactUrl,
|
||||||
|
fetched: false,
|
||||||
|
httpStatus,
|
||||||
|
fetchError,
|
||||||
|
jsonWorkflow,
|
||||||
|
validation: jsonWorkflow.validation,
|
||||||
|
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||||
|
actionPlan: jsonWorkflow.actionPlan,
|
||||||
|
missing: ["artifact-fetch", ...jsonWorkflow.missing],
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
id: "fetch",
|
||||||
|
label: "Artifact URL fetch",
|
||||||
|
value: "blocked",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "json-workflow",
|
||||||
|
label: "Artifact JSON workflow",
|
||||||
|
value: "blocked",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "next-command",
|
||||||
|
label: "Next command",
|
||||||
|
value: jsonWorkflow.actionPlan.nextCommand ?? "none",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const artifactJson = await response.text();
|
||||||
|
const jsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson });
|
||||||
|
return {
|
||||||
|
apiName: "project-release-readiness-artifact-url-workflow",
|
||||||
|
workflowVersion: 1,
|
||||||
|
phase: jsonWorkflow.ready === true ? "ready" : "blocked",
|
||||||
|
ready: jsonWorkflow.ready === true,
|
||||||
|
artifactUrl,
|
||||||
|
fetched: true,
|
||||||
|
httpStatus,
|
||||||
|
fetchError: null,
|
||||||
|
jsonWorkflow,
|
||||||
|
validation: jsonWorkflow.validation,
|
||||||
|
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||||
|
actionPlan: jsonWorkflow.actionPlan,
|
||||||
|
missing: jsonWorkflow.missing,
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
id: "fetch",
|
||||||
|
label: "Artifact URL fetch",
|
||||||
|
value: "ready",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "json-workflow",
|
||||||
|
label: "Artifact JSON workflow",
|
||||||
|
value: jsonWorkflow.ready === true ? "ready" : "blocked",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "next-command",
|
||||||
|
label: "Next command",
|
||||||
|
value: jsonWorkflow.actionPlan.nextCommand ?? "none",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
const jsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson: "" });
|
||||||
|
return {
|
||||||
|
apiName: "project-release-readiness-artifact-url-workflow",
|
||||||
|
workflowVersion: 1,
|
||||||
|
phase: "blocked",
|
||||||
|
ready: false,
|
||||||
|
artifactUrl,
|
||||||
|
fetched: false,
|
||||||
|
httpStatus: null,
|
||||||
|
fetchError: error?.message ?? "artifact URL fetch error",
|
||||||
|
jsonWorkflow,
|
||||||
|
validation: jsonWorkflow.validation,
|
||||||
|
summaryViewModel: jsonWorkflow.summaryViewModel,
|
||||||
|
actionPlan: jsonWorkflow.actionPlan,
|
||||||
|
missing: ["artifact-fetch", ...jsonWorkflow.missing],
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
id: "fetch",
|
||||||
|
label: "Artifact URL fetch",
|
||||||
|
value: "blocked",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "json-workflow",
|
||||||
|
label: "Artifact JSON workflow",
|
||||||
|
value: "blocked",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "next-command",
|
||||||
|
label: "Next command",
|
||||||
|
value: jsonWorkflow.actionPlan.nextCommand ?? "none",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||||
const artifactObject = objectOrEmpty(artifact);
|
const artifactObject = objectOrEmpty(artifact);
|
||||||
const releaseGate = objectOrEmpty(artifactObject.releaseGate);
|
const releaseGate = objectOrEmpty(artifactObject.releaseGate);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ for (const phrase of [
|
|||||||
"createProjectReleaseReadinessArtifactValidation()",
|
"createProjectReleaseReadinessArtifactValidation()",
|
||||||
"createProjectReleaseReadinessArtifactValidationActionPlan()",
|
"createProjectReleaseReadinessArtifactValidationActionPlan()",
|
||||||
"createProjectReleaseReadinessArtifactValidationSummaryViewModel()",
|
"createProjectReleaseReadinessArtifactValidationSummaryViewModel()",
|
||||||
|
"loadProjectReleaseReadinessArtifactUrlWorkflow()",
|
||||||
"embedded gate manifest, result matrix, and action plan",
|
"embedded gate manifest, result matrix, and action plan",
|
||||||
"validateWorkflowOverviewReleaseReadinessArtifactJson()",
|
"validateWorkflowOverviewReleaseReadinessArtifactJson()",
|
||||||
"loadWorkflowOverviewReleaseReadinessArtifactUrl()",
|
"loadWorkflowOverviewReleaseReadinessArtifactUrl()",
|
||||||
@@ -119,6 +120,7 @@ for (const phrase of [
|
|||||||
"gateResultMatrixReady",
|
"gateResultMatrixReady",
|
||||||
"gateActionPlanReady",
|
"gateActionPlanReady",
|
||||||
"loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()",
|
"loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()",
|
||||||
|
"loadProjectReleaseReadinessArtifactUrlWorkflow()",
|
||||||
"build/project-release-readiness.json",
|
"build/project-release-readiness.json",
|
||||||
"INI panel shell handoff exports",
|
"INI panel shell handoff exports",
|
||||||
"createIniPanelShellApiSurfaceInventory()",
|
"createIniPanelShellApiSurfaceInventory()",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
||||||
createProjectReleaseReadinessReport,
|
createProjectReleaseReadinessReport,
|
||||||
createProjectReleaseReadinessSummaryViewModel,
|
createProjectReleaseReadinessSummaryViewModel,
|
||||||
|
loadProjectReleaseReadinessArtifactUrlWorkflow,
|
||||||
} from "../../../runtime/sdk/src/index.js";
|
} from "../../../runtime/sdk/src/index.js";
|
||||||
|
|
||||||
const manifest = createProjectReleaseGateManifest();
|
const manifest = createProjectReleaseGateManifest();
|
||||||
@@ -184,6 +185,14 @@ const artifactValidationActionPlan = createProjectReleaseReadinessArtifactValida
|
|||||||
const artifactJsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({
|
const artifactJsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({
|
||||||
artifactJson: JSON.stringify(report),
|
artifactJson: JSON.stringify(report),
|
||||||
});
|
});
|
||||||
|
const artifactUrlWorkflow = await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||||
|
artifactUrl: "/project-release-readiness.json",
|
||||||
|
fetchRef: async () => ({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
text: async () => JSON.stringify(report),
|
||||||
|
}),
|
||||||
|
});
|
||||||
assert.equal(
|
assert.equal(
|
||||||
artifactValidationSummary.apiName,
|
artifactValidationSummary.apiName,
|
||||||
"project-release-readiness-artifact-validation-summary-view-model",
|
"project-release-readiness-artifact-validation-summary-view-model",
|
||||||
@@ -249,6 +258,26 @@ assert.deepEqual(
|
|||||||
["next-command", "none"],
|
["next-command", "none"],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
assert.equal(artifactUrlWorkflow.apiName, "project-release-readiness-artifact-url-workflow");
|
||||||
|
assert.equal(artifactUrlWorkflow.workflowVersion, 1);
|
||||||
|
assert.equal(artifactUrlWorkflow.phase, "ready");
|
||||||
|
assert.equal(artifactUrlWorkflow.ready, true);
|
||||||
|
assert.equal(artifactUrlWorkflow.artifactUrl, "/project-release-readiness.json");
|
||||||
|
assert.equal(artifactUrlWorkflow.fetched, true);
|
||||||
|
assert.equal(artifactUrlWorkflow.httpStatus, 200);
|
||||||
|
assert.equal(artifactUrlWorkflow.fetchError, null);
|
||||||
|
assert.equal(artifactUrlWorkflow.jsonWorkflow.ready, true);
|
||||||
|
assert.equal(artifactUrlWorkflow.validation.ready, true);
|
||||||
|
assert.equal(artifactUrlWorkflow.summaryViewModel.statusLine, "Ready: Artifact evidence complete");
|
||||||
|
assert.equal(artifactUrlWorkflow.actionPlan.commandCount, 0);
|
||||||
|
assert.deepEqual(
|
||||||
|
artifactUrlWorkflow.rows.map(({ id, value }) => [id, value]),
|
||||||
|
[
|
||||||
|
["fetch", "ready"],
|
||||||
|
["json-workflow", "ready"],
|
||||||
|
["next-command", "none"],
|
||||||
|
],
|
||||||
|
);
|
||||||
const staleArtifactValidationSummary = createProjectReleaseReadinessArtifactValidationSummaryViewModel(
|
const staleArtifactValidationSummary = createProjectReleaseReadinessArtifactValidationSummaryViewModel(
|
||||||
createProjectReleaseReadinessArtifactValidation({}),
|
createProjectReleaseReadinessArtifactValidation({}),
|
||||||
);
|
);
|
||||||
@@ -260,6 +289,18 @@ const staleArtifactJsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkf
|
|||||||
const invalidArtifactJsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({
|
const invalidArtifactJsonWorkflow = createProjectReleaseReadinessArtifactJsonWorkflow({
|
||||||
artifactJson: "{not-json",
|
artifactJson: "{not-json",
|
||||||
});
|
});
|
||||||
|
const missingArtifactUrlWorkflow = await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||||
|
artifactUrl: "",
|
||||||
|
fetchRef: null,
|
||||||
|
});
|
||||||
|
const failedArtifactUrlWorkflow = await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||||
|
artifactUrl: "/missing.json",
|
||||||
|
fetchRef: async () => ({
|
||||||
|
ok: false,
|
||||||
|
status: 404,
|
||||||
|
text: async () => "",
|
||||||
|
}),
|
||||||
|
});
|
||||||
assert.equal(staleArtifactValidationSummary.phase, "blocked");
|
assert.equal(staleArtifactValidationSummary.phase, "blocked");
|
||||||
assert.match(staleArtifactValidationSummary.statusLine, /^Blocked: apiName, reportVersion/);
|
assert.match(staleArtifactValidationSummary.statusLine, /^Blocked: apiName, reportVersion/);
|
||||||
assert.equal(staleArtifactValidationSummary.rows.find(({ id }) => id === "gate-action-plan")?.value, "missing");
|
assert.equal(staleArtifactValidationSummary.rows.find(({ id }) => id === "gate-action-plan")?.value, "missing");
|
||||||
@@ -304,5 +345,17 @@ assert.deepEqual(
|
|||||||
["next-command", "wasm-port/tests/host/verify_project_release_gate.sh"],
|
["next-command", "wasm-port/tests/host/verify_project_release_gate.sh"],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
assert.equal(missingArtifactUrlWorkflow.ready, false);
|
||||||
|
assert.equal(missingArtifactUrlWorkflow.fetched, false);
|
||||||
|
assert.deepEqual(missingArtifactUrlWorkflow.missing.slice(0, 2), ["artifact-url", "fetch"]);
|
||||||
|
assert.equal(failedArtifactUrlWorkflow.ready, false);
|
||||||
|
assert.equal(failedArtifactUrlWorkflow.fetched, false);
|
||||||
|
assert.equal(failedArtifactUrlWorkflow.httpStatus, 404);
|
||||||
|
assert.match(failedArtifactUrlWorkflow.fetchError, /404/);
|
||||||
|
assert.equal(failedArtifactUrlWorkflow.missing[0], "artifact-fetch");
|
||||||
|
assert.equal(
|
||||||
|
failedArtifactUrlWorkflow.actionPlan.nextCommand,
|
||||||
|
"wasm-port/tests/host/verify_project_release_gate.sh",
|
||||||
|
);
|
||||||
|
|
||||||
console.log("project_release_gate_manifest_node_smoke=ok");
|
console.log("project_release_gate_manifest_node_smoke=ok");
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import {
|
|||||||
isSupportedIniPanelLaunchApiManifest,
|
isSupportedIniPanelLaunchApiManifest,
|
||||||
isSupportedIniPanelShellIntegrationManifest,
|
isSupportedIniPanelShellIntegrationManifest,
|
||||||
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
||||||
|
loadProjectReleaseReadinessArtifactUrlWorkflow,
|
||||||
loadMachineSessionFromOpfs,
|
loadMachineSessionFromOpfs,
|
||||||
loadMachineSessionSnapshot,
|
loadMachineSessionSnapshot,
|
||||||
loadMachineTextFiles,
|
loadMachineTextFiles,
|
||||||
@@ -116,6 +117,7 @@ const requiredExports = [
|
|||||||
"loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl",
|
"loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl",
|
||||||
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
||||||
],
|
],
|
||||||
|
["loadProjectReleaseReadinessArtifactUrlWorkflow", loadProjectReleaseReadinessArtifactUrlWorkflow],
|
||||||
["planIniFileContextStaging", planIniFileContextStaging],
|
["planIniFileContextStaging", planIniFileContextStaging],
|
||||||
["planSimConfigStaging", planSimConfigStaging],
|
["planSimConfigStaging", planSimConfigStaging],
|
||||||
["analyzeIniRuntimeBoundaries", analyzeIniRuntimeBoundaries],
|
["analyzeIniRuntimeBoundaries", analyzeIniRuntimeBoundaries],
|
||||||
@@ -355,6 +357,24 @@ assert.equal(
|
|||||||
createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson: "not-json" }).parsed,
|
createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson: "not-json" }).parsed,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
assert.equal(
|
||||||
|
(await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||||
|
artifactUrl: "/project-release-readiness.json",
|
||||||
|
fetchRef: async () => ({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
text: async () => JSON.stringify(releaseReadinessArtifact),
|
||||||
|
}),
|
||||||
|
})).summaryViewModel.statusLine,
|
||||||
|
"Ready: Artifact evidence complete",
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
(await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
||||||
|
artifactUrl: "/missing.json",
|
||||||
|
fetchRef: async () => ({ ok: false, status: 404, text: async () => "" }),
|
||||||
|
})).missing[0],
|
||||||
|
"artifact-fetch",
|
||||||
|
);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
createProjectReleaseReadinessArtifactValidation({}).missing,
|
createProjectReleaseReadinessArtifactValidation({}).missing,
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user