# 创建和部署工作流

将一份工作流 DSL 部署为工作区中可见、可运行的工作流。部署成功后，保存工作流 ID；后续运行、更新、暂停和删除都使用该值。

## 前提条件

- 已准备 Product API Base URL、个人访问令牌和目标工作区 ID。
- 当前身份具有在目标工作区创建工作流的权限。
- 已准备通过当前工作流 DSL 校验的 YAML 定义。

工作流 DSL 描述算子、依赖关系和输入输出。开始编写业务工作流前，先通过 WorkItem Catalog 取得当前工作区可用的 WorkItem ID，不要从其他环境或旧示例复制 ID。

## 相关接口

以下路径相对于 Product API Base URL：

| 方法与路径 | 用途 |
| --- | --- |
| `GET /workflow/v2/workitems/catalog` | 列出当前工作区可用的 WorkItem。 |
| `POST /workflow/v2/workflow-deployments` | 校验 DSL，并创建或部署工作流。 |
| `GET /workflow/v2/workflow-apps` | 列出工作区中的工作流。 |
| `GET /workflow/v2/workflow-apps/{workflow_id}` | 获取一个工作流的当前定义和状态。 |
| `PATCH /workflow/v2/workflow-apps/{workflow_id}` | 更新工作流名称、DSL、运行配置或状态。 |
| `POST /workflow/v2/workflow-apps/{workflow_id}/pause` | 暂停接受新的运行。 |
| `POST /workflow/v2/workflow-apps/{workflow_id}/resume` | 恢复接受新的运行。 |
| `DELETE /workflow/v2/workflow-apps/{workflow_id}` | 删除工作流。 |

## 1. 查询可用 WorkItem

```bash
curl "$PRODUCT_API_BASE_URL/workflow/v2/workitems/catalog" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Accept: application/json"
```

从响应中选择符合任务的 WorkItem，并保存其 ID、版本、输入 Schema 和输出 Schema。部署时使用 WorkItem ID，不使用界面显示名称代替。

## 2. 部署工作流

下面的 DSL 使用 Catalog 列表 WorkItem 展示最小结构。可用性仍以当前工作区的 WorkItem Catalog 为准。

```bash
curl -X POST "$PRODUCT_API_BASE_URL/workflow/v2/workflow-deployments" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "<WORKFLOW_ID>",
    "name": "catalog-list-workflow",
    "description": "List catalog resources",
    "dsl_yaml": "workflow:\n  name: catalog-list-workflow\n  root: root\nroot:\n  chain:\n    - work_item:\n        name: list_catalog\n        id: catalog:catalog.list\n"
  }'
```

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| `workflow_id` | string | 否 | 调用方指定的工作流 ID。省略时由服务端分配；提供时应在工作区中保持唯一。 |
| `name` | string | 是 | 工作流名称。名称用于识别，后续 API 仍使用工作流 ID。 |
| `description` | string | 否 | 工作流用途和输入输出说明。 |
| `dsl_yaml` | string | 是 | 完整工作流 DSL。服务端会校验 YAML、WorkItem 和模板表达式。 |
| `execution_mode` | string | 否 | 运行模式。只使用当前接口或已有工作流返回的受支持值。 |
| `cron_expression` | string | 否 | 定时运行表达式。仅在相应运行模式下设置。 |
| `runtime_fields` | object | 否 | 运行表单字段定义。字段 ID 与运行接口 `values` 的键对应。 |
| `runtime_layout` | object | 否 | 运行表单布局。 |
| `default_values` | object | 否 | 工作流运行输入的默认值。键必须与 DSL 和运行表单约定一致。 |
| `compute_resource_id` | string | 否 | 工作流默认使用的计算实例 ID。 |

不要仅为了通过部署而删除 DSL 中的必需输入或依赖。需要运行时输入时，应同时检查 DSL 模板路径、`runtime_fields` 和 `default_values` 是否一致。

## 3. 检查部署结果

成功响应的工作流摘要位于 `data.workflow`：

```json
{
  "code": "OK",
  "msg": "OK",
  "data": {
    "workflow": {
      "id": "<WORKFLOW_ID>",
      "name": "catalog-list-workflow",
      "source_type": "<SOURCE_TYPE>",
      "execution_mode": "<EXECUTION_MODE>",
      "draft_id": "<DRAFT_ID>",
      "candidate_id": "<CANDIDATE_ID>",
      "status": "<STATUS>"
    },
    "warnings": []
  }
}
```

| 字段 | 返回条件 | 说明 |
| --- | --- | --- |
| `data.workflow.id` | 部署成功时返回 | 工作流 ID。运行、读取、更新或删除时保存并继续使用。 |
| `data.workflow.status` | 部署成功时返回 | 当前工作流状态。运行前重新读取，确认当前状态允许运行。 |
| `data.workflow.execution_mode` | 部署成功时返回 | 实际运行模式。 |
| `data.workflow.draft_id` | 部署成功时返回 | 当前草稿标识。不要用它代替工作流 ID 调用运行接口。 |
| `data.workflow.candidate_id` | 存在候选版本时返回 | 当前候选版本标识。 |
| `data.warnings` | 有警告时返回 | 不阻止部署的提示。部署成功后仍应逐项评估。 |

保存 `data.workflow.id` 后，再调用工作流详情确认 DSL、输入表单、计算实例和状态符合预期。部署成功不表示工作流已经运行。

## 更新、暂停和删除

- 更新前先读取工作流详情，避免用旧 DSL 覆盖他人的新版本。
- 暂停工作流只阻止新的运行，不能推断已有工作流作业已经停止。
- 删除前检查现有工作流作业、定时配置、产物和下游依赖。删除成功也不会自动撤销外部系统中已经产生的副作用。

## 常见问题

| 现象 | 先检查 | 下一步 |
| --- | --- | --- |
| DSL 校验失败 | YAML 结构、根算子、WorkItem ID 和模板表达式 | 使用 WorkItem Catalog 的当前定义修正 DSL，再重新部署。 |
| 提示缺少运行输入 | DSL 模板路径、`runtime_fields` 和 `default_values` | 使用相同字段 ID 补齐定义和默认值，不用显示标签代替。 |
| 找不到计算实例 | `compute_resource_id` 和工作区 | 从当前工作区重新获取计算实例 ID。 |
| 部署成功但不能运行 | 工作流状态、警告和当前权限 | 重新读取工作流详情，确认状态和 `available_actions`，不要重复部署同一 ID。 |

## 下一步

- [运行、查询与取消](run-query-cancel.md)
- [定时运行工作流](schedule-workflows.md)
- [重新运行算子](rerun-nodes.md)
