Skip to content

Commit 71b6f10

Browse files
authored
[miniflare] Align workflow status endpoint schema with production (#15483)
1 parent f2b3a6d commit 71b6f10

16 files changed

Lines changed: 1363 additions & 798 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"miniflare": minor
3+
"wrangler": patch
4+
---
5+
6+
Align Local Explorer Workflow instance status requests with production
7+
8+
Local Explorer and Wrangler local mode now use the production-compatible `status` request field for pausing, resuming, restarting, and terminating Workflow instances. Direct Local Explorer API consumers must replace the previous `action` field with `status`.
9+
10+
Successful Local Explorer status updates now return the production-compatible instance `status` and response `timestamp` instead of the local-only `result.success` acknowledgement.

‎packages/local-explorer-ui/src/routes/workflows/$workflowName/$instanceId.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
} from "@tanstack/react-router";
2222
import { memo, useCallback, useEffect, useRef, useState } from "react";
2323
import {
24-
workflowsChangeInstanceStatus,
24+
worChangeStatusWorkflowInstance,
2525
workflowsDeleteInstance,
2626
workflowsGetInstanceDetails,
2727
workflowsSendInstanceEvent,
@@ -462,12 +462,12 @@ function InstanceDetailView() {
462462
setActionInProgress(action);
463463
setError(null);
464464
try {
465-
await workflowsChangeInstanceStatus({
465+
await worChangeStatusWorkflowInstance({
466466
path: {
467467
workflow_name: params.workflowName,
468468
instance_id: instanceId,
469469
},
470-
body: { action },
470+
body: { status: action },
471471
});
472472
await fetchDetails();
473473
} catch (err) {
@@ -490,13 +490,13 @@ function InstanceDetailView() {
490490
setRestartingFromStep(true);
491491
setError(null);
492492
try {
493-
await workflowsChangeInstanceStatus({
493+
await worChangeStatusWorkflowInstance({
494494
path: {
495495
workflow_name: params.workflowName,
496496
instance_id: instanceId,
497497
},
498498
body: {
499-
action: "restart",
499+
status: "restart",
500500
from: getRestartFromStepParam(restartFromStepTarget),
501501
},
502502
});

‎packages/local-explorer-ui/src/routes/workflows/$workflowName/index.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
type JSX,
2828
} from "react";
2929
import {
30-
workflowsChangeInstanceStatus,
30+
worChangeStatusWorkflowInstance,
3131
workflowsDeleteInstance,
3232
workflowsDeleteWorkflow,
3333
workflowsListInstances,
@@ -217,12 +217,12 @@ const InstanceRow = memo(function InstanceRow({
217217
e.stopPropagation(); // Don't navigate when clicking action buttons
218218
setActionInProgress(action);
219219
try {
220-
await workflowsChangeInstanceStatus({
220+
await worChangeStatusWorkflowInstance({
221221
path: {
222222
workflow_name: workflowName,
223223
instance_id: instance.id ?? "",
224224
},
225-
body: { action },
225+
body: { status: action },
226226
});
227227
onActionComplete();
228228
} catch {

‎packages/miniflare/scripts/check-generate-api.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { mkdtempSync, writeFileSync } from "node:fs";
1414
import { tmpdir } from "node:os";
1515
import { join } from "node:path";
1616

17-
const OPENAPI_COMMIT = "5a81015dd2d335664a2dd2dcabd3fd666334c9c2";
17+
const OPENAPI_COMMIT = "45402b29f339d77551c8cdfd269378d7b36c4775";
1818
const OPENAPI_RAW_URL = `https://raw.githubusercontent.com/cloudflare/api-schemas/${OPENAPI_COMMIT}/openapi.json`;
1919

2020
const GENERATED_PATHS = [

‎packages/miniflare/scripts/openapi-filter-config.ts‎

Lines changed: 8 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ const config = {
4343
methods: ["post"],
4444
},
4545

46+
// Workflows endpoints
47+
{
48+
path: "/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/status",
49+
methods: ["patch"],
50+
},
51+
4652
// Durable Objects endpoints
4753
{
4854
path: "/accounts/{account_id}/workers/durable_objects/namespaces",
@@ -170,8 +176,8 @@ const config = {
170176

171177
// Schema properties not returned by local implementation
172178
schemaProperties: {
173-
// Namespace response doesn't include supports_url_encoding locally
174-
"workers-kv_namespace": ["supports_url_encoding"],
179+
// Namespace response doesn't include jurisdiction or supports_url_encoding locally
180+
"workers-kv_namespace": ["jurisdiction", "supports_url_encoding"],
175181
// D1 database response doesn't include created_at locally
176182
"d1_database-response": ["created_at"],
177183
// D1 query meta doesn't include served_by fields locally
@@ -1512,119 +1518,6 @@ const config = {
15121518
tags: ["Workflows"],
15131519
},
15141520
},
1515-
"/workflows/{workflow_name}/instances/{instance_id}/status": {
1516-
patch: {
1517-
description:
1518-
"Changes the status of a workflow instance (pause, resume, restart, terminate).",
1519-
operationId: "workflows-change-instance-status",
1520-
parameters: [
1521-
{
1522-
in: "path",
1523-
name: "workflow_name",
1524-
required: true,
1525-
schema: {
1526-
$ref: "#/components/schemas/workflows_workflow-name",
1527-
},
1528-
},
1529-
{
1530-
in: "path",
1531-
name: "instance_id",
1532-
required: true,
1533-
schema: {
1534-
$ref: "#/components/schemas/workflows_instance-id",
1535-
},
1536-
},
1537-
],
1538-
requestBody: {
1539-
required: true,
1540-
content: {
1541-
"application/json": {
1542-
schema: {
1543-
type: "object",
1544-
required: ["action"],
1545-
properties: {
1546-
action: {
1547-
type: "string",
1548-
enum: ["pause", "resume", "restart", "terminate"],
1549-
description:
1550-
"The action to perform on the workflow instance.",
1551-
},
1552-
from: {
1553-
type: "object",
1554-
description:
1555-
"The step to restart the instance from. Only valid when action is restart.",
1556-
required: ["name"],
1557-
properties: {
1558-
name: {
1559-
type: "string",
1560-
description: "The name of the step.",
1561-
},
1562-
count: {
1563-
type: "integer",
1564-
minimum: 1,
1565-
description:
1566-
"The 1-based index of the step when multiple steps share the same name and type. Defaults to 1.",
1567-
},
1568-
type: {
1569-
type: "string",
1570-
enum: ["do", "sleep", "waitForEvent"],
1571-
description: "The step type. Defaults to do.",
1572-
},
1573-
},
1574-
},
1575-
rollback: {
1576-
type: "boolean",
1577-
description:
1578-
"The option to trigger rollbacks when terminating the workflow instance.",
1579-
},
1580-
},
1581-
},
1582-
},
1583-
},
1584-
},
1585-
responses: {
1586-
"200": {
1587-
content: {
1588-
"application/json": {
1589-
schema: {
1590-
allOf: [
1591-
{
1592-
$ref: "#/components/schemas/workers_api-response-common",
1593-
},
1594-
{
1595-
properties: {
1596-
result: {
1597-
type: "object",
1598-
properties: {
1599-
success: {
1600-
type: "boolean",
1601-
},
1602-
},
1603-
},
1604-
},
1605-
type: "object",
1606-
},
1607-
],
1608-
},
1609-
},
1610-
},
1611-
description: "Change Workflow Instance Status response.",
1612-
},
1613-
"4XX": {
1614-
content: {
1615-
"application/json": {
1616-
schema: {
1617-
$ref: "#/components/schemas/workers_api-response-common-failure",
1618-
},
1619-
},
1620-
},
1621-
description: "Change Workflow Instance Status response failure.",
1622-
},
1623-
},
1624-
summary: "Change Workflow Instance Status",
1625-
tags: ["Workflows"],
1626-
},
1627-
},
16281521
"/workflows/{workflow_name}/instances/{instance_id}/events/{event_type}":
16291522
{
16301523
post: {

‎packages/miniflare/src/workers/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export type {
77
EmailHandlerResult,
88
} from "./email/storage";
99
export * from "./kv";
10+
export * from "./local-explorer";
1011
export * from "./queues";
1112
export * from "./shared";

‎packages/miniflare/src/workers/local-explorer/explorer.worker.ts‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import { Hono } from "hono/tiny";
55
import mime from "mime";
6+
import { z } from "miniflare:zod";
67
import { CorePaths } from "../core";
78
import { fetchFromPeer, getPeerUrlsIfAggregating } from "./aggregation";
89
import { errorResponse, validateQuery, validateRequestBody } from "./common";
@@ -24,7 +25,7 @@ import {
2425
zWorkersKvNamespaceWriteMultipleKeyValuePairsData,
2526
zObservabilityQueryData,
2627
zWorkflowsBatchDeleteInstancesData,
27-
zWorkflowsChangeInstanceStatusData,
28+
zWorChangeStatusWorkflowInstanceData,
2829
zWorkflowsListInstancesData,
2930
} from "./generated/zod.gen";
3031
import openApiSpec from "./openapi.local.json";
@@ -78,6 +79,23 @@ import type { WorkerdDebugPortConnector } from "../core/dev-registry-proxy-share
7879
import type { EmailStoreService } from "../email/storage";
7980
import type { LocalExplorerWorker } from "./generated";
8081

82+
// Generated object schemas strip unknown keys, so reject invalid rollback
83+
// combinations before parsing rather than silently dropping the option.
84+
const zWorkflowInstanceStatusBody = z.preprocess((value, ctx) => {
85+
if (
86+
typeof value === "object" &&
87+
value !== null &&
88+
Object.hasOwn(value, "rollback") &&
89+
(value as { status?: unknown }).status !== "terminate"
90+
) {
91+
ctx.addIssue({
92+
code: "custom",
93+
message: "'rollback' is only valid when terminating.",
94+
});
95+
}
96+
return value;
97+
}, zWorChangeStatusWorkflowInstanceData.shape.body);
98+
8199
export type Env = {
82100
[key: string]: unknown;
83101
[CoreBindings.JSON_LOCAL_EXPLORER_BINDING_MAP]: BindingIdMap;
@@ -376,7 +394,7 @@ app.get("/api/workflows/:workflow_name/instances/:instance_id", (c) =>
376394

377395
app.patch(
378396
"/api/workflows/:workflow_name/instances/:instance_id/status",
379-
validateRequestBody(zWorkflowsChangeInstanceStatusData.shape.body),
397+
validateRequestBody(zWorkflowInstanceStatusBody),
380398
(c) =>
381399
changeWorkflowInstanceStatus(
382400
c,

‎packages/miniflare/src/workers/local-explorer/generated/index.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ export type {
136136
R2V4Response,
137137
R2V4ResponseFailure,
138138
R2V4ResponseList,
139+
WorChangeStatusWorkflowInstanceData,
140+
WorChangeStatusWorkflowInstanceError,
141+
WorChangeStatusWorkflowInstanceErrors,
142+
WorChangeStatusWorkflowInstanceResponse,
143+
WorChangeStatusWorkflowInstanceResponses,
139144
WorkersApiResponseCollection,
140145
WorkersApiResponseCommon,
141146
WorkersApiResponseCommonFailure,
@@ -220,11 +225,6 @@ export type {
220225
WorkflowsBatchDeleteInstancesErrors,
221226
WorkflowsBatchDeleteInstancesResponse,
222227
WorkflowsBatchDeleteInstancesResponses,
223-
WorkflowsChangeInstanceStatusData,
224-
WorkflowsChangeInstanceStatusError,
225-
WorkflowsChangeInstanceStatusErrors,
226-
WorkflowsChangeInstanceStatusResponse,
227-
WorkflowsChangeInstanceStatusResponses,
228228
WorkflowsCreateInstanceData,
229229
WorkflowsCreateInstanceError,
230230
WorkflowsCreateInstanceErrors,

0 commit comments

Comments
 (0)