workflows-modify

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zapier Workflows Modify

Zapier工作流修改

Modifying a deployed workflow follows a discovery, fetch, edit, publish, verify pattern. There are two ways to publish a change, and the user chooses between them:
  • Direct publish — one
    publish-workflow-version
    call that creates and activates a new version immediately. Fastest path when the user wants the change live now.
  • Through a draft — save the change into the workflow's server draft (the working copy shared with the Zapier editor), then either publish the draft or leave it open for the user to review and publish later.
Publishing writes to the user's Zapier account, so get explicit confirmation before publishing either way.
Use the public SDK CLI experimental command surface. Do not use
zapier-sdk-code-substrate
.
修改已部署的工作流遵循“发现、获取、编辑、发布、验证”的流程。发布变更有两种方式,由用户选择:
  • 直接发布 — 调用一次
    publish-workflow-version
    ,立即创建并激活新版本。当用户希望变更立即生效时,这是最快的路径。
  • 通过草稿发布 — 将变更保存到工作流的服务器草稿(与Zapier编辑器共享的工作副本)中,然后可以选择发布草稿,或者留待用户稍后审阅并发布。
发布操作会写入用户的Zapier账户,因此无论采用哪种方式,都需要先获得用户的明确确认。
使用公开的SDK CLI实验性命令接口。请勿使用
zapier-sdk-code-substrate

Compatibility Gate

兼容性检查

Before using this skill, run the
workflows-doctor
bundle compatibility check. If
workflows-doctor
is not installed or cannot be loaded, run
workflows-install
or install
workflows-doctor
from
zapier/agent-skills
before continuing. If
workflows-doctor
reports SDK/skill drift, follow its refresh instructions, stop this skill invocation, reload the agent workspace if needed, and ask the user to rerun the original request.
使用此技能前,运行
workflows-doctor
包兼容性检查。如果未安装或无法加载
workflows-doctor
,请先运行
workflows-install
或从
zapier/agent-skills
安装
workflows-doctor
,然后再继续。如果
workflows-doctor
报告SDK/技能版本不一致,请按照其刷新说明操作,停止当前技能调用,必要时重新加载代理工作区,并请用户重新发起原始请求。

Step 1: Identify The Workflow

步骤1:确定工作流

If the user provides a workflow ID, use it directly. Otherwise list workflows and find the matching one by name or description:
bash
zapier-sdk --experimental list-workflows --json
If multiple workflows match, show candidates and ask the user which one to modify.
如果用户提供了工作流ID,直接使用该ID。否则,列出所有工作流,通过名称或描述找到匹配的工作流:
bash
zapier-sdk --experimental list-workflows --json
如果有多个匹配的工作流,展示候选列表并询问用户要修改哪一个。

Step 2: Check For Open Drafts And Pick The Path

步骤2:检查未完成草稿并选择发布路径

bash
zapier-sdk --experimental list-workflow-drafts <workflow-id> --json
The list returns open drafts, most recently edited first. An open draft always holds unpublished work (publishing consumes drafts, so a leftover one was never published).
  • An open draft exists: work through the draft. It holds the user's in-progress edits and your change applies on top of it — and a direct publish would be rejected by the server's open-draft guard anyway (see Step 6A). If several are open, tell the user and confirm which to use.
  • No open draft: both paths are available. If the user's request already implies immediate publish ("fix it and ship it"), direct publish is the shorter path. If they want to review first, work incrementally, or hand off to the editor, use a draft. When the intent is unclear, ask: publish directly once the change is ready, or stage it as a draft to review/publish later?
bash
zapier-sdk --experimental list-workflow-drafts <workflow-id> --json
该列表会返回未完成的草稿,按最近编辑时间排序。未完成的草稿始终包含未发布的工作内容(发布操作会消耗草稿,因此剩余的草稿一定是从未发布过的)。
  • 存在未完成草稿:基于草稿进行操作。草稿包含用户正在进行的编辑,你的变更将基于此进行——而且服务器的未完成草稿防护机制会直接拒绝直接发布请求(见步骤6A)。如果存在多个未完成草稿,告知用户并确认使用哪一个。
  • 无未完成草稿:两种路径都可用。如果用户的请求明确要求立即发布(如“修复并上线”),直接发布是更短的路径。如果用户希望先审阅、逐步操作或移交到编辑器处理,则使用草稿路径。如果用户意图不明确,询问用户:变更完成后直接发布,还是先保存为草稿供稍后审阅/发布?

Step 3: Fetch The Current Source

步骤3:获取当前源代码

Direct-publish path: fetch the live version's content:
bash
zapier-sdk --experimental list-workflow-versions <workflow-id> --json
zapier-sdk --experimental get-workflow-version <workflow-id> <newest-version-id> --json
Draft path: create the draft if none exists (it forks from the workflow's current live version), then fetch it:
bash
zapier-sdk --experimental create-workflow-draft <workflow-id> --json
zapier-sdk --experimental get-workflow-draft <workflow-id> <draft-id> --json
Capture from the fetched draft:
  • source_files
    , especially
    source_files["workflow.ts"]
    — this may contain unpublished edits; treat it as the user's in-progress work, not stale data.
  • draft_revision
    — needed for optimistic concurrency on every write.
  • dependencies
    ,
    zapier_durable_version
    ,
    trigger
    ,
    connections
    , and
    app_versions
    .
On either path, also fetch the workflow itself for its name, enabled state, and metadata:
bash
zapier-sdk --experimental get-workflow <workflow-id> --json
Determine the current start mode from this read-back — a modify must never silently change it. A workflow has one of two start modes, and re-publishing without carrying it forward is exactly how a triggered workflow silently becomes triggerless:
  • trigger
    either signal shows a trigger: the fetched version/draft source carries a
    trigger
    object, or
    get-workflow
    's
    triggers[]
    is non-empty. Capture the full
    trigger
    config verbatim; it must be re-passed on publish (Step 6) or the new version drops the trigger.
  • manual
    both signals are absent: no
    trigger
    object in the fetched source and an empty
    triggers[]
    . It runs on-demand only.
If the two signals disagree — most importantly a saved
trigger
config but an empty or stale live
triggers[]
(a claim that failed, is pending, or was disabled) — do not label it manual. Preserve the trigger and stop to reconcile with the user: dropping a saved trigger is the silent-triggerless regression this determination guards against.
triggers[]
and the fetched trigger config are the authority for the current mode — the platform's start-mode input (the write-only
manual
flag) is never surfaced on any read-back, so do not look for it. Unless the user's request is explicitly to change the start mode (add a trigger to a manual workflow, or remove one), the modify preserves it — carry the captured mode through the edit, publish, and verification.
The remaining checks in this step apply only when building on a pre-existing draft (skip them for the direct path or a draft you just created — a fresh fork is identical to its base):
Check for unpublished draft changes. Publishing the draft publishes everything in it, not just your edit — so you must know whether the draft already diverges from what's live. Fetch the draft's base version and compare:
bash
zapier-sdk --experimental get-workflow-version <workflow-id> <base_version_id from the draft> --json
If the draft's
source_files
, trigger, connections, or app versions differ from the base version, the draft holds unpublished work. Note a short summary of the differences — you'll surface it at confirmation time in Step 6. Never silently publish it and never silently discard it.
Check the draft isn't stale. A draft forks from the live version at creation, but the live version can move past it — another draft may have published, or a direct publish went through. Publishing a stale draft ships its old base content over everything the newer versions changed. Compare the newest version's
id
(from
list-workflow-versions
) to the draft's
base_version_id
:
  • Base is the newest version: not stale — continue.
  • Stale, with no unpublished changes (the divergence check above found none): the draft is a leftover shell of an old version. Do not build on it — discard it, fork a fresh draft from live, tell the user you did, and continue on the fresh draft:
    bash
    zapier-sdk --experimental discard-workflow-draft <workflow-id> <draft-id> --json
    zapier-sdk --experimental create-workflow-draft <workflow-id> --json
  • Stale, with unpublished changes: stop and tell the user. Publishing this draft as-is would revert everything in the versions published since it was forked. The safe path is forking a fresh draft from live and porting the draft's unpublished changes (plus your edit) onto it — offer to do that, and get an explicit choice between porting and publishing the stale draft anyway. Never pick for them.
直接发布路径:获取当前在线版本的内容:
bash
zapier-sdk --experimental list-workflow-versions <workflow-id> --json
zapier-sdk --experimental get-workflow-version <workflow-id> <newest-version-id> --json
草稿路径:如果不存在草稿则创建(从工作流当前在线版本分支),然后获取草稿内容:
bash
zapier-sdk --experimental create-workflow-draft <workflow-id> --json
zapier-sdk --experimental get-workflow-draft <workflow-id> <draft-id> --json
从获取的草稿中捕获以下信息:
  • source_files
    ,尤其是
    source_files["workflow.ts"]
    — 其中可能包含未发布的编辑内容;将其视为用户正在进行的工作,而非过时数据。
  • draft_revision
    — 每次写入操作都需要此参数以实现乐观并发控制。
  • dependencies
    zapier_durable_version
    trigger
    connections
    app_versions
无论采用哪种路径,还需要获取工作流本身的名称、启用状态和元数据:
bash
zapier-sdk --experimental get-workflow <workflow-id> --json
从此回读信息中确定当前启动模式 — 修改操作绝不能静默更改此模式。 工作流有两种启动模式,如果重新发布时未保留该模式,恰好会导致触发式工作流静默变为无触发式:
  • trigger
    (触发式)
    — 以下任一信号表明是触发式:获取的版本/草稿源代码包含
    trigger
    对象,
    get-workflow
    返回的
    triggers[]
    不为空。完整保留
    trigger
    配置;发布时(步骤6)必须重新传递该配置,否则新版本会丢失触发器。
  • manual
    (手动式)
    — 以下两个信号均不存在:获取的源代码中无
    trigger
    对象,
    triggers[]
    为空。该工作流仅可按需运行。
如果两个信号不一致 — 最重要的情况是保存了
trigger
配置,但
triggers[]
为空或过时(声明失败、待处理或已禁用) — 请勿将其标记为手动式。保留触发器并停止操作,与用户协调:丢弃已保存的触发器正是此判断机制要防止的“静默无触发回归”问题。
triggers[]
和获取的触发器配置是当前模式的权威依据 — 平台的启动模式输入(仅写的
manual
标志)不会在任何回读信息中显示,因此无需查找该标志。除非用户明确要求更改启动模式(为手动工作流添加触发器,或移除触发器),否则修改操作需保留原模式 — 在编辑、发布和验证过程中保持捕获的模式不变。
本步骤的剩余检查仅适用于基于已存在的草稿进行操作的情况(直接路径或刚创建的草稿可跳过这些检查 — 新分支的草稿与其基础版本完全一致):
检查草稿中的未发布变更。 发布草稿会发布其中的所有内容,而不仅仅是你的编辑 — 因此你必须了解草稿是否已与在线版本存在差异。获取草稿的基础版本并进行比较:
bash
zapier-sdk --experimental get-workflow-version <workflow-id> <base_version_id from the draft> --json
如果草稿的
source_files
、触发器、连接或应用版本与基础版本不同,则草稿包含未发布的工作内容。记录差异的简短摘要 — 在步骤6的确认环节需要告知用户。绝不能静默发布或丢弃这些内容。
检查草稿是否过时。 草稿创建时会从在线版本分支,但在线版本可能已更新 — 可能已有其他草稿发布,或已进行过直接发布。发布过时的草稿会将其旧基础内容覆盖所有新版本的变更。将最新版本的
id
(来自
list-workflow-versions
)与草稿的
base_version_id
进行比较:
  • 基础版本是最新版本:未过时 — 继续操作。
  • 过时且无未发布变更(上述差异检查未发现任何差异):草稿是旧版本的残留空壳。请勿基于此草稿操作 — 丢弃它,从在线版本分支创建新草稿,告知用户此操作,然后基于新草稿继续:
    bash
    zapier-sdk --experimental discard-workflow-draft <workflow-id> <draft-id> --json
    zapier-sdk --experimental create-workflow-draft <workflow-id> --json
  • 过时且有未发布变更:停止操作并告知用户。按原样发布此草稿会恢复自其分支以来所有已发布版本的变更。安全的做法是从在线版本分支创建新草稿,并将草稿中的未发布变更(加上你的编辑)迁移到新草稿中 — 向用户提供此选项,并获取明确选择:是迁移变更还是仍要发布过时草稿。绝不能替用户做选择。

Step 4: Make The Edit

步骤4:进行编辑

Prefer editing an existing local workflow file if one exists. Otherwise, write
source_files["workflow.ts"]
into a local
workflow.ts
in a workflow-specific directory and edit that copy.
Apply the requested change narrowly. Preserve existing Zod schemas,
ctx.step
boundaries, connection aliases, dependency pins, durable runtime version, connection bindings, app-version bindings, trigger configuration, and visibility/enabled state unless there is a reason to change them. On the draft path, preserve any unpublished draft content that isn't part of the requested change.
When the edit adds a new AI/LLM step, follow
workflows-create
Phase 2: always use "AI by Zapier" (
AICLIAPI
, action
get_completion
) and select the model with
model_id
— the user's named provider/model if they gave one, otherwise the default
"advanced/auto"
with built-in credentials (
authentication_id: "0"
). Only use a raw-provider AI app if the user explicitly asks for that standalone app or needs a capability AI by Zapier lacks.
如果存在本地工作流文件,优先编辑该文件。否则,将
source_files["workflow.ts"]
写入工作流专属目录下的本地
workflow.ts
文件,并编辑该副本。
仅进行用户请求的窄范围变更。保留现有的Zod模式、
ctx.step
边界、连接别名、依赖项固定版本、持久化运行时版本、连接绑定、应用版本绑定、触发器配置以及可见性/启用状态,除非有明确的修改理由。在草稿路径下,保留草稿中所有不属于用户请求变更的未发布内容。
当编辑操作添加新的AI/LLM步骤时,遵循
workflows-create
的第二阶段:始终使用“AI by Zapier”(
AICLIAPI
,动作
get_completion
),并通过
model_id
选择模型 — 如果用户指定了提供商/模型,则使用用户指定的名称,否则使用默认的
"advanced/auto"
及内置凭据(
authentication_id: "0"
)。仅当用户明确要求使用独立应用或需要“AI by Zapier”不具备的功能时,才使用原始提供商的AI应用。

Step 5: Optional Synthetic Test

步骤5:可选的模拟测试

For non-trivial changes, propose a test run before publishing. This may run real downstream actions, so summarize side effects and wait for confirmation.
Build
source_files
from the local file:
bash
SOURCE_FILES="$(jq -n --rawfile workflow workflow.ts '{"workflow.ts": $workflow}')"
Run the workflow:
bash
zapier-sdk --experimental run-durable "$SOURCE_FILES" \
  --dependencies '<deps from the fetched source>' \
  --zapier-durable-version '<durable version from the fetched source>' \
  --connections '<connection bindings JSON if needed>' \
  --input '<synthetic input JSON>' \
  --private
For synthetic
run-durable
tests, reuse the fetched connection bindings as-is — they're already the nested object shape
{ "alias": { "connectionId": "..." } }
that
run-durable
accepts. Do not flatten to a bare string like
{ "alias": "id" }
; that fails with
expected object, received string
.
If the run returns a run ID, inspect it when needed:
bash
zapier-sdk --experimental get-durable-run <run-id> --json
对于非 trivial 的变更,建议在发布前进行测试运行。这可能会触发真实的下游操作,因此需总结可能的副作用并等待用户确认。
从本地文件构建
source_files
bash
SOURCE_FILES="$(jq -n --rawfile workflow workflow.ts '{"workflow.ts": $workflow}')"
运行工作流:
bash
zapier-sdk --experimental run-durable "$SOURCE_FILES" \
  --dependencies '<deps from the fetched source>' \
  --zapier-durable-version '<durable version from the fetched source>' \
  --connections '<connection bindings JSON if needed>' \
  --input '<synthetic input JSON>' \
  --private
对于模拟
run-durable
测试,直接复用获取的连接绑定 — 它们已经是
run-durable
接受的嵌套对象格式
{ "alias": { "connectionId": "..." } }
。请勿扁平化为
{ "alias": "id" }
这样的字符串格式,否则会报错
expected object, received string
如果运行返回了运行ID,必要时可查看该运行的详情:
bash
zapier-sdk --experimental get-durable-run <run-id> --json

Step 6: Confirm, Then Publish

步骤6:确认后发布

Before writing anything, summarize for the user:
  1. The diagnosis.
  2. The code or config change.
  3. The workflow ID (and draft, on the draft path) being updated.
  4. The values being preserved, including dependencies, durable version, enabled state, connections, app versions, and trigger configuration.
  5. The start mode captured in Step 3 (
    trigger
    or
    manual
    ) and that it is unchanged by this edit — or, if the request is to change it, state the change explicitly (adding a trigger to a manual workflow, or removing one). A modify never changes the start mode as a side effect.
  6. The publish path chosen in Step 2, and — on the draft path — any unpublished draft changes found in Step 3 (publishing the draft ships those too; see 6B).
Wait for explicit confirmation, then build
source_files
:
bash
SOURCE_FILES="$(jq -n --rawfile workflow workflow.ts '{"workflow.ts": $workflow}')"
Before publishing on either path, confirm the version you are about to publish matches the start mode captured in Step 3: a
trigger
-mode workflow's published version must carry its trigger and be published without
--manual
; a
manual
-mode workflow's must carry no trigger and be published with
--manual
(unless the request is explicitly to change the mode, in which case match the intended new mode). Pass exactly one of trigger /
--manual
— the platform contract is a discriminated union and rejects both together as a contradiction. A
trigger
-mode republish that loses its trigger is a silent-triggerless regression. How you pass this differs by path — the trigger is a
--trigger
flag on a direct publish but lives in the stored draft on the draft path — so see the path-specific check in 6A and 6B below.
在执行任何写入操作前,向用户总结以下信息:
  1. 诊断结果。
  2. 代码或配置变更内容。
  3. 要更新的工作流ID(以及草稿路径下的草稿ID)。
  4. 要保留的值,包括依赖项、持久化版本、启用状态、连接、应用版本和触发器配置。
  5. 在步骤3中捕获的启动模式
    trigger
    manual
    ),以及此编辑操作不会更改该模式 — 如果用户请求更改启动模式,则明确说明变更内容(为手动工作流添加触发器,或移除触发器)。修改操作绝不能作为副作用更改启动模式。
  6. 在步骤2中选择的发布路径,以及 — 在草稿路径下 — 在步骤3中发现的任何未发布草稿变更(发布草稿会同时发布这些变更;见6B)。
等待用户明确确认后,构建
source_files
bash
SOURCE_FILES="$(jq -n --rawfile workflow workflow.ts '{"workflow.ts": $workflow}')"
无论采用哪种路径,发布前请确认即将发布的版本与步骤3中捕获的启动模式匹配:
trigger
模式工作流的发布版本必须包含触发器,且发布时不添加
--manual
参数;
manual
模式工作流的发布版本必须无触发器,且发布时添加
--manual
参数(除非用户明确要求更改模式,此时匹配预期的新模式)。必须仅传递触发器/
--manual
中的一个 — 平台约定为互斥联合,同时传递两者会被视为矛盾而拒绝。
trigger
模式重新发布时丢失触发器会导致“静默无触发回归”问题。传递方式因路径而异 — 直接发布时使用
--trigger
标志,而草稿路径下触发器存储在草稿中 — 因此请查看6A和6B中的路径特定检查。

Step 6A: Direct Publish

步骤6A:直接发布

Publish the variant matching the start mode from Step 3. Pass exactly one of
--trigger
/
--manual
.
trigger
-mode
— carry the trigger, omit
--manual
:
bash
zapier-sdk --experimental publish-workflow-version <workflow-id> "$SOURCE_FILES" \
  --dependencies '<deps from fetched version>' \
  --zapier-durable-version '<durable version from fetched version>' \
  --connections '<connection bindings from fetched version>' \
  --app-versions '<app version bindings from fetched version>' \
  --trigger '<trigger config from fetched version>' \
  --json
manual
-mode
— omit
--trigger
, declare
--manual
:
bash
zapier-sdk --experimental publish-workflow-version <workflow-id> "$SOURCE_FILES" \
  --dependencies '<deps from fetched version>' \
  --zapier-durable-version '<durable version from fetched version>' \
  --connections '<connection bindings from fetched version>' \
  --app-versions '<app version bindings from fetched version>' \
  --manual \
  --json
Use the fetched workflow's enabled state when publishing. If the workflow was enabled before the edit, either omit
--enabled
or pass bare
--enabled
because publish defaults to enabled. If the workflow was disabled before the edit, add
--enabled false
; do not use
--enabled=false
or
--no-enabled
. Do not accidentally re-enable a disabled workflow.
Omit
--connections
,
--app-versions
, or
--trigger
only when the fetched metadata confirms the workflow version does not use that field. If the fetched metadata includes trigger, connection, or app-version configuration but the shape cannot be mapped to the current publish flags, stop before publishing and tell the user the workflow needs SDK confirmation rather than silently dropping metadata.
Start-mode check (direct publish): a
trigger
-mode workflow must include
--trigger
(and not
--manual
) in this call — omitting
--trigger
publishes a triggerless version and silently drops the trigger. A
manual
-mode workflow must omit
--trigger
and pass
--manual
instead. Never pass both
--trigger
and
--manual
; the platform contract rejects the combination. (When the request is to change the mode, match the intended new mode instead.)
On a 409 open-draft conflict: the server rejects direct publishes when the workflow has open draft(s) — publishing past a draft would let the draft's later publish silently revert your change. The error lists the blocking drafts (
meta.open_drafts
). A draft appearing here after Step 2 found none means someone (likely the user, in the editor) opened one mid-flight. Tell the user and offer:
  • Fold the change into the draft — switch to the draft path: fetch the draft, run the Step 3 divergence/staleness checks, re-apply your edit on top of its content, and continue at 6B.
  • Discard the draft and retry — only with explicit confirmation, since this drops the draft's unpublished work:
    discard-workflow-draft
    , then retry the direct publish.
Never pick for them, and never discard a draft silently.
发布与步骤3中启动模式匹配的版本。必须仅传递
--trigger
/
--manual
中的一个。
trigger
模式
— 保留触发器,省略
--manual
bash
zapier-sdk --experimental publish-workflow-version <workflow-id> "$SOURCE_FILES" \
  --dependencies '<deps from fetched version>' \
  --zapier-durable-version '<durable version from fetched version>' \
  --connections '<connection bindings from fetched version>' \
  --app-versions '<app version bindings from fetched version>' \
  --trigger '<trigger config from fetched version>' \
  --json
manual
模式
— 省略
--trigger
,添加
--manual
bash
zapier-sdk --experimental publish-workflow-version <workflow-id> "$SOURCE_FILES" \
  --dependencies '<deps from fetched version>' \
  --zapier-durable-version '<durable version from fetched version>' \
  --connections '<connection bindings from fetched version>' \
  --app-versions '<app version bindings from fetched version>' \
  --manual \
  --json
发布时使用获取的工作流启用状态。如果编辑前工作流已启用,可省略
--enabled
或仅传递
--enabled
,因为发布默认启用。如果编辑前工作流已禁用,添加
--enabled false
;请勿使用
--enabled=false
--no-enabled
。请勿意外重新启用已禁用的工作流。
仅当获取的元数据确认工作流版本未使用该字段时,才可省略
--connections
--app-versions
--trigger
。如果获取的元数据包含触发器、连接或应用版本配置,但无法映射到当前发布标志的格式,请停止发布并告知用户该工作流需要SDK确认,而非静默丢弃元数据。
启动模式检查(直接发布):
trigger
模式工作流的此调用必须包含
--trigger
(且不能包含
--manual
) — 省略
--trigger
会发布无触发版本并静默丢弃触发器。
manual
模式工作流必须省略
--trigger
并传递
--manual
。绝不能同时传递
--trigger
--manual
;平台约定会拒绝此组合。(如果用户请求更改模式,则匹配预期的新模式。)
遇到409未完成草稿冲突: 当工作流存在未完成草稿时,服务器会拒绝直接发布请求 — 跳过草稿发布会导致后续草稿发布时静默覆盖你的变更。错误信息会列出阻塞的草稿(
meta.open_drafts
)。如果步骤2未发现草稿,但此时出现草稿,意味着有人(很可能是用户在编辑器中)在操作过程中创建了草稿。告知用户并提供以下选项:
  • 将变更合并到草稿中 — 切换到草稿路径:获取草稿,运行步骤3的差异/过时检查,将你的编辑重新应用到草稿内容之上,然后继续到6B。
  • 丢弃草稿并重试 — 仅在获得明确确认后执行,因为这会丢弃草稿中的未发布工作:调用
    discard-workflow-draft
    ,然后重试直接发布。
绝不能替用户做选择,也不能静默丢弃草稿。

Step 6B: Through The Draft

步骤6B:通过草稿发布

If Step 3 found unpublished draft changes, resolve them first — ask the user explicitly: include them in this change, or start clean?
  • Include: proceed as written — the draft content plus your edit ships together.
  • Start clean: discard the draft and fork a fresh one from the live version, then re-apply your edit on the fresh draft (re-run Steps 3–4 against it):
    bash
    zapier-sdk --experimental discard-workflow-draft <workflow-id> <draft-id> --json
    zapier-sdk --experimental create-workflow-draft <workflow-id> --json
    Discard-and-refork is the only sanctioned way to drop unpublished work — never overwrite draft content in place to get rid of it.
Save the edit into the draft, passing the
draft_revision
from your read:
bash
zapier-sdk --experimental update-workflow-draft <workflow-id> <draft-id> "$SOURCE_FILES" \
  --draft-revision <draft_revision from Step 3> \
  --json
Omitted fields keep their stored draft values, so only pass
--trigger
,
--connections
,
--app-versions
,
--dependencies
, or
--zapier-durable-version
when the edit changes them. Passing
null
for
--trigger
,
--connections
, or
--app-versions
clears the stored value — never do that to "skip" a field.
Start-mode check (draft path): the trigger lives in the stored draft and
publish-workflow-draft
takes no
--trigger
flag — it publishes whatever the draft holds. So a correct
trigger
-mode draft publish has no
--trigger
at publish time; that is expected, not a dropped trigger. First confirm, immediately before
publish-workflow-draft
, that the draft's stored
trigger
still matches the captured (or intended) start mode — a
trigger
-mode draft still carries its trigger, a
manual
-mode draft none (read it back with
get-workflow-draft
if unsure). Then declare the start mode at publish: a
manual
-mode workflow passes
--manual
on
publish-workflow-draft
(below); a
trigger
-mode workflow's draft already holds its trigger, so publish without
--manual
. Never combine a stored trigger with
--manual
— the platform contract rejects both together. Clearing the trigger with
--trigger null
on the
update-workflow-draft
above is exactly how a
trigger
-mode workflow silently becomes manual.
If the user chose to publish later, stop here: report the draft ID and the draft's editor link —
https://zapier.com/durables-editor/<workflow-id>/draft/<draft-slug>/workflow.ts
, using the
slug
from the draft response — so they can review and publish from the editor, or ask you to publish in a follow-up. The final segment is one of the draft's
source_files
keys (
workflow.ts
in this skill's flow).
Otherwise publish now. The update response returns the new
draft_revision
; publish the variant matching the start mode (the draft already holds the trigger — the difference is only whether you pass
--manual
):
trigger
-mode
— the stored trigger is the signal, omit
--manual
:
bash
zapier-sdk --experimental publish-workflow-draft <workflow-id> <draft-id> \
  --draft-revision <draft_revision from the update response> \
  --json
manual
-mode
— the draft holds no trigger, declare
--manual
:
bash
zapier-sdk --experimental publish-workflow-draft <workflow-id> <draft-id> \
  --draft-revision <draft_revision from the update response> \
  --manual \
  --json
Publishing the draft creates a new immutable version, advances the live pointer, and discards the draft — publish consumes it, so an open draft always means unpublished work. The response contains both the new
version
and the consumed
draft
(
status: "discarded"
). Any further modification starts back at Step 2.
Publish preserves the workflow's current enabled state when
--enabled
is omitted. Omit it unless the user asked to change the enabled state.
On a conflict (revision mismatch): someone edited the draft between your read and your write — likely the user, in the editor. Never blind-overwrite. Re-read the draft (
get-workflow-draft
), re-apply your change on top of the fresh
source_files
, and retry with the new
draft_revision
. If the fresh content conflicts materially with your change, stop and ask the user.
如果步骤3发现未发布草稿变更,先解决这些变更 — 明确询问用户:是将这些变更包含在本次更改中,还是重新开始?
  • 包含:按原计划进行 — 草稿内容与你的编辑将一同发布。
  • 重新开始:丢弃草稿并从在线版本分支创建新草稿,然后将你的编辑重新应用到新草稿上(针对新草稿重新运行步骤3-4):
    bash
    zapier-sdk --experimental discard-workflow-draft <workflow-id> <draft-id> --json
    zapier-sdk --experimental create-workflow-draft <workflow-id> --json
    “丢弃并重新分支”是丢弃未发布工作的唯一认可方式 — 绝不能通过直接覆盖草稿内容来丢弃未发布工作。
将编辑保存到草稿中,传递步骤3中获取的
draft_revision
bash
zapier-sdk --experimental update-workflow-draft <workflow-id> <draft-id> "$SOURCE_FILES" \
  --draft-revision <draft_revision from Step 3> \
  --json
省略的字段会保留草稿中的存储值,因此仅当编辑操作更改了这些字段时,才传递
--trigger
--connections
--app-versions
--dependencies
--zapier-durable-version
。传递
null
作为
--trigger
--connections
--app-versions
的值会清除存储值 — 绝不能为了“跳过”某个字段而这样做。
启动模式检查(草稿路径): 触发器存储在草稿中,
publish-workflow-draft
不接受
--trigger
标志 — 它会发布草稿中的所有内容。因此,正确的
trigger
模式草稿发布在发布时不包含
--trigger
参数;这是预期行为,而非丢失触发器。在调用
publish-workflow-draft
前,先确认草稿中存储的
trigger
仍与捕获的(或预期的)启动模式匹配 —
trigger
模式草稿仍包含触发器,
manual
模式草稿无触发器(如果不确定,可通过
get-workflow-draft
回读确认)。然后在发布时声明启动模式:
manual
模式工作流在调用
publish-workflow-draft
时传递
--manual
(如下);
trigger
模式工作流的草稿已包含触发器,因此发布时不添加
--manual
。绝不能将存储的触发器与
--manual
结合使用 — 平台约定会拒绝此组合。在上述
update-workflow-draft
调用中使用
--trigger null
清除触发器,正是
trigger
模式工作流静默变为手动模式的原因。
如果用户选择稍后发布,在此停止:报告草稿ID和草稿编辑器链接 —
https://zapier.com/durables-editor/<workflow-id>/draft/<draft-slug>/workflow.ts
,使用草稿响应中的
slug
— 以便用户从编辑器审阅并发布,或在后续请求中让你发布。最后一段是草稿
source_files
中的一个键(本技能流程中为
workflow.ts
)。
否则立即发布。更新响应会返回新的
draft_revision
;发布与启动模式匹配的版本(草稿已包含触发器 — 差异仅在于是否传递
--manual
):
trigger
模式
— 存储的触发器是信号,省略
--manual
bash
zapier-sdk --experimental publish-workflow-draft <workflow-id> <draft-id> \
  --draft-revision <draft-revision from the update response> \
  --json
manual
模式
— 草稿无触发器,添加
--manual
bash
zapier-sdk --experimental publish-workflow-draft <workflow-id> <draft-id> \
  --draft-revision <draft-revision from the update response> \
  --manual \
  --json
发布草稿会创建新的不可变版本,更新在线指针,并丢弃草稿 — 发布操作会消耗草稿,因此未完成的草稿始终意味着存在未发布工作。响应包含新的
version
和已消耗的
draft
status: "discarded"
)。任何后续修改都需从步骤2重新开始。
省略
--enabled
时,发布操作会保留工作流当前的启用状态。除非用户要求更改启用状态,否则省略该参数。
遇到冲突(版本不匹配): 在你读取和写入之间有人编辑了草稿 — 很可能是用户在编辑器中操作。绝不能盲目覆盖。重新读取草稿(
get-workflow-draft
),将你的编辑重新应用到最新的
source_files
上,并使用新的
draft_revision
重试。如果最新内容与你的编辑存在实质性冲突,请停止操作并询问用户。

Step 7: Verify

步骤7:验证

If the change was published (either path), read back the workflow and versions:
bash
zapier-sdk --experimental get-workflow <workflow-id> --json
zapier-sdk --experimental list-workflow-versions <workflow-id> --json
Confirm the newest version reflects the publish, the workflow is still enabled if it should be, and trigger/connection/app-version metadata was preserved.
Gate on start-mode preservation. Compare the deployed start mode against the one captured in Step 3. The
enabled
state and the trigger's presence are independent — an
enabled
check alone will not catch a dropped trigger, so inspect
triggers[]
directly:
  • Captured mode
    trigger
    (and the edit was not meant to remove it) → require the read-back to still show a non-empty
    triggers[]
    , and
    enabled
    to match the workflow's preserved enabled state (Step 6A), not
    enabled: true
    unconditionally. A workflow that was disabled before the edit stays disabled and still passes this gate; only require
    enabled: true
    when the workflow was enabled before the edit (or the user asked to enable it). An empty
    triggers[]
    means the republish dropped the trigger (most often
    --trigger
    was not re-passed with the fetched config) — do not report the change as done; re-publish with the preserved
    --trigger
    and re-check. The
    triggers[]
    check, not the
    enabled
    state, is what proves the trigger survived: a triggered workflow can be legitimately disabled, and a disabled workflow that lost its trigger would still read back
    enabled: false
    .
  • Captured mode
    manual
    (and the edit was not meant to add a trigger) → require
    triggers[]
    to remain empty. A trigger appearing unexpectedly is also a mismatch — stop and reconcile with the user.
  • If the request was explicitly to change the start mode, verify the read-back matches the intended new mode instead.
    triggers[]
    is the authority for this comparison; the platform's write-only
    manual
    flag is never surfaced on a read-back, so do not look for it.
Check the matching entry in
triggers[]
for
details.webhook_url
, regardless of trigger type — if present, it's the catch URL external services call and is meant to be shared, unlike the workflow-level
trigger_url
; most triggers have none, and that is normal. If the change is hard to validate without a live trigger fire, tell the user exactly what test event to send and what result to expect.
Finish by reporting:
  • Workflow name and ID.
  • Whether the requested change was published, or saved to a draft for later publishing (include the draft ID).
  • The start mode (
    trigger
    or
    manual
    ) and that it was preserved (or, if the change was to alter it, its new value), confirmed by the Step 7 gate.
  • Whether trigger, connection, and app-version metadata were preserved.
  • Whether the workflow is enabled.
  • The trigger's
    webhook_url
    , if present.
  • The Zapier editor link:
    https://zapier.com/durables-editor/<workflow-id>
    — or, when the change was staged as a draft, the draft link
    https://zapier.com/durables-editor/<workflow-id>/draft/<draft-slug>/workflow.ts
    .
如果已发布变更(无论哪种路径),回读工作流和版本:
bash
zapier-sdk --experimental get-workflow <workflow-id> --json
zapier-sdk --experimental list-workflow-versions <workflow-id> --json
确认最新版本反映了发布操作,工作流仍处于应有的启用状态,且触发器/连接/应用版本元数据已保留。
以启动模式保留为检查标准。 将部署后的启动模式与步骤3中捕获的模式进行比较。
enabled
状态与触发器的存在是独立的 — 仅检查
enabled
无法发现触发器丢失的情况,因此需直接检查
triggers[]
  • 捕获的模式为**
    trigger
    (且编辑操作并非要移除触发器) → 要求回读信息仍显示非空的
    triggers[]
    ,且
    enabled
    状态与工作流
    保留的**启用状态(步骤6A)一致,而非无条件要求
    enabled: true
    。编辑前已禁用的工作流仍保持禁用状态,且仍通过此检查;仅当编辑前工作流已启用(或用户要求启用)时,才要求
    enabled: true
    triggers[]
    为空意味着重新发布时丢失了触发器(最常见的原因是未重新传递获取的
    --trigger
    配置) — 请勿报告变更已完成;重新发布并保留
    --trigger
    ,然后重新检查。
    triggers[]
    检查而非
    enabled
    状态,是验证触发器是否保留的依据:触发式工作流可能合法处于禁用状态,而丢失触发器的禁用工作流仍会回读
    enabled: false
  • 捕获的模式为**
    manual
    **(且编辑操作并非要添加触发器) → 要求
    triggers[]
    保持为空。如果意外出现触发器,也是不匹配的情况 — 停止操作并与用户协调。
  • 如果用户明确要求更改启动模式,则验证回读信息是否与预期的新模式匹配。
    triggers[]
    是此比较的权威依据;平台的仅写
    manual
    标志不会在回读信息中显示,因此无需查找该标志。
无论触发器类型如何,检查
triggers[]
匹配项中的
details.webhook_url
— 如果存在,这是外部服务调用的捕获URL,可共享,与工作流级别的
trigger_url
不同;大多数触发器没有此URL,这是正常的。如果变更难以通过触发事件验证,请明确告知用户要发送的测试事件以及预期结果。
最后向用户报告以下信息:
  • 工作流名称和ID。
  • 请求的变更已发布,还是保存为草稿供稍后发布(包含草稿ID)。
  • 启动模式(
    trigger
    manual
    ),以及该模式已保留(如果是更改模式的操作,则说明新模式),并已通过步骤7的检查确认。
  • 触发器、连接和应用版本元数据是否已保留。
  • 工作流是否已启用。
  • 触发器的
    webhook_url
    (如果存在)。
  • Zapier编辑器链接:
    https://zapier.com/durables-editor/<workflow-id>
    — 如果变更保存为草稿,则提供草稿链接
    https://zapier.com/durables-editor/<workflow-id>/draft/<draft-slug>/workflow.ts

Reverting

回滚

Previous versions remain available as read-only history. To revert, fetch the prior version's source:
bash
zapier-sdk --experimental list-workflow-versions <workflow-id> --json
zapier-sdk --experimental get-workflow-version <workflow-id> <version-id> --json
Then publish it like any other change through Step 6 — either path works: direct publish with the prior version's
source_files
and metadata, or load them into the draft with
update-workflow-draft
and publish the draft. Same confirmation and conflict handling as Step 6.
历史版本仍以只读形式保留。要回滚,获取先前版本的源代码:
bash
zapier-sdk --experimental list-workflow-versions <workflow-id> --json
zapier-sdk --experimental get-workflow-version <workflow-id> <version-id> --json
然后按照步骤6的流程发布该版本 — 两种路径都适用:使用先前版本的
source_files
和元数据直接发布,或通过
update-workflow-draft
将其加载到草稿中并发布草稿。确认和冲突处理与步骤6相同。