# 发布工作流

创建工作流，或在提供 `workflow_id` 时发布该工作流的新定义。发布只保存工作流定义，不表示该工作流已执行。

```text
POST https://moi.matrixorigin.cn/newmoi/workflow/v2/workflow-deployments
```

## 调用前准备

准备有目标工作区访问权限且具有创建工作流权限的个人访问令牌、目标工作区 ID 和工作流 DSL。

下方示例使用：

- `$AI_STUDIO_API_KEY`：实际个人访问令牌，通过 `X-API-Key` Header 传递。
- `$WORKSPACE_ID`：要发布工作流的工作区 ID，通过 `X-Workspace-ID` Header 传递。

请求体不能包含运行时上下文字段。

## 请求体

创建或更新发布时，需要同时指定名称和 DSL；其余字段按执行模式和触发方式提供。

| 字段 | 类型 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `name` | string | 是 | 工作流名称。 |
| `dsl_yaml` | string | 是 | 工作流 DSL 的 YAML 文本。 |
| `workflow_id` | string | 否 | 已有工作流 ID；提供时更新该工作流的部署定义。 |
| `description` | string | 否 | 工作流说明。 |
| `source_type` | string | 否 | 工作流来源类型；省略时为 `manual_dsl`。发布 Memory Governance 模板时必须传 `memory_governance`。 |
| `execution_mode` | string | 否 | 执行模式。可选值为 `one_shot`（默认）、`dynamic_service`、`stream`、`cron`、`volume_trigger`；`cron` 必须同时提供 `cron_expression`，不支持 `manual`。 |
| `cron_expression` | string | 否 | 定时执行的 Cron 表达式。 |
| `compute_resource_id` | string | 否 | 工作流关联的计算资源 ID。 |
| `runtime_fields` | object | 否 | 运行时输入表单定义。 |
| `runtime_layout` | object | 否 | 运行时输入表单布局。 |
| `default_values` | object | 否 | 运行时输入的默认值。 |
| `volume_trigger` | object | 否 | 卷触发器配置。 |
| `dynamic_service` | object | 否 | 动态服务配置。 |
| `design_graph` | object | 否 | 工作流设计图。 |

## 请求示例

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/workflow/v2/workflow-deployments" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "<WORKFLOW_NAME>",
    "dsl_yaml": "<WORKFLOW_DSL_YAML>",
    "execution_mode": "<EXECUTION_MODE>"
  }'
```

## 成功响应

成功时返回 `200`。`data.workflow` 是已发布工作流的摘要；`data.deployment` 仅在服务返回部署信息时出现。保存 `data.workflow.id`，用于后续管理和运行。发布成功不表示该工作流已执行。

```json
{
  "code": "OK",
  "msg": "OK",
  "data": {
    "workflow": {
      "id": "wf-001",
      "name": "daily-import",
      "source_type": "manual_dsl",
      "execution_mode": "cron",
      "cron_expression": "0 2 * * *",
      "status": "ready"
    },
    "warnings": []
  }
}
```

响应字段如下。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `code` | string | 成功时为 `OK`。 |
| `msg` | string | 成功时为 `OK`。 |
| `data.workflow` | object | 已发布工作流摘要。 |
| `data.workflow.id` | string | 工作流 ID。 |
| `data.workflow.name` | string | 工作流名称。 |
| `data.workflow.source_type` | string | 工作流来源类型。 |
| `data.workflow.execution_mode` | string | 已发布的执行模式。 |
| `data.workflow.cron_expression` | string | Cron 表达式；仅定时模式返回。 |
| `data.workflow.draft_id` | string | 草稿标识；服务端提供时返回。 |
| `data.workflow.candidate_id` | string | 候选标识；服务端提供时返回。 |
| `data.workflow.status` | string | 当前工作流状态。 |
| `data.deployment` | object | 服务返回的部署信息；仅在服务返回时出现。 |
| `data.warnings` | string（字符串数组） | 发布成功但需要调用方关注的警告；仅在有警告时返回。 |

## 执行模式说明

- **单次运行：** 手工从 API 启动一次工作流时，使用 `one_shot`，或省略 `execution_mode`。不要传 `manual`；该值会返回 `ErrParamInvalid`。
- **定时触发：** 使用 `cron` 描述持久化的定时触发，并同时提供 `cron_expression`。仍可通过作业启动接口手动运行一次。
- **卷触发：** 使用 `volume_trigger` 描述持久化的卷触发。仍可通过作业启动接口手动运行一次。

## 错误响应

```json
{
  "code": "ErrParamInvalid",
  "msg": "请求参数无效",
  "data": null
}
```

### 常见 HTTP 错误

```{list-table}
:header-rows: 1
:widths: 12 22 32 34

* - HTTP 状态码
  - 错误代码
  - 常见原因
  - 建议操作
* - `400`
  - `ErrParamInvalid`
  - 请求体、DSL、执行模式、触发器或计算资源配置不符合要求。
  - 修正请求字段和 DSL 后重新提交。
* - `401`
  - `ErrUnauthorized`
  - 缺少或无效的访问凭据。
  - 检查 API Key 和工作区 Header。
* - `403`
  - `ErrForbidden`
  - 当前身份没有创建工作流或使用依赖资源的权限。
  - 请求授予所需权限。
* - `404`
  - `ErrNotFound`
  - 请求引用的资源不存在。
  - 核对资源 ID 与当前工作区。
* - `409`
  - `ErrConflict`
  - 工作流标识或发布操作与已有状态冲突。
  - 读取现有工作流后按最新状态重试。
* - `500`
  - `ErrServer`
  - 服务端发布失败。
  - 稍后重试。
```

## 后续操作

[查询工作流详情](get-workflow.md)或[启动工作流作业](../workflow-jobs/start-workflow-job.md)。
