Skip to content

Commit bc374e9

Browse files
[FIX] Address Greptile: report all workflow skip reasons in one pass
- workflow: a workflow blocked by both a skipped tool and a skipped connector now surfaces both reasons instead of only the first (no extra re-run to learn the second blocker). - tests: assert the tool-skip cascade emits its report warning; cover the dual-skip (tool + connector) case. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CsGrHbs5SWmQkKqiimg6CF
1 parent caf700a commit bc374e9

2 files changed

Lines changed: 47 additions & 22 deletions

File tree

src/unstract/clone/phases/workflow.py

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -123,42 +123,37 @@ def _clone_one(
123123
name = src["workflow_name"]
124124
src_id = src["id"]
125125

126+
# Collect every blocking dependency before skipping, so a workflow
127+
# held up by both a skipped tool and a skipped connector reports both
128+
# reasons in one pass rather than one per re-run.
129+
skip_reasons: list[str] = []
126130
src_tool_id = self._wf_to_src_tool_id.get(src_id)
127131
if src_tool_id and src_tool_id in self.ctx.skipped_custom_tool_registry_ids:
128-
logger.warning(
129-
"skipping workflow '%s' src=%s — its tool was skipped in "
130-
"custom_tool phase (frictionless adapter dependence)",
131-
name,
132-
src_id,
132+
skip_reasons.append(
133+
"its tool was skipped (frictionless adapter); wire equivalents "
134+
"on target and re-run"
133135
)
134-
with lock:
135-
result.skipped += 1
136-
result.warnings.append(
137-
f"workflow '{name}' skipped — its tool was skipped "
138-
"(frictionless adapter); wire equivalents on target and re-run"
139-
)
140-
return
141-
142136
skipped_conns = (
143137
self._wf_to_connector_ids.get(src_id, set())
144138
& self.ctx.skipped_connector_ids
145139
)
146140
if skipped_conns:
141+
skip_reasons.append(
142+
"depends on un-clonable connector(s) "
143+
f"({', '.join(sorted(skipped_conns))}); provision them on target "
144+
"with the same name and re-run"
145+
)
146+
if skip_reasons:
147147
logger.warning(
148-
"skipping workflow '%s' src=%s — endpoint connector(s) %s were "
149-
"skipped (OAuth/redacted); cloning it would create pipelines that "
150-
"fail every run",
148+
"skipping workflow '%s' src=%s — %s",
151149
name,
152150
src_id,
153-
", ".join(sorted(skipped_conns)),
151+
"; ".join(skip_reasons),
154152
)
155153
with lock:
156154
result.skipped += 1
157-
result.warnings.append(
158-
f"workflow '{name}' skipped — depends on un-clonable "
159-
"connector(s); provision them on target with the same name "
160-
"and re-run"
161-
)
155+
for reason in skip_reasons:
156+
result.warnings.append(f"workflow '{name}' skipped — {reason}")
162157
return
163158

164159
try:

tests/clone/test_workflow_phase.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,36 @@ def test_cascade_skip_when_workflow_tool_was_skipped():
195195
assert [p["workflow_name"] for p in tgt.posts] == ["OK WF"]
196196
assert ctx.remap.resolve("workflow", "wf-skipped") is None
197197
assert ctx.remap.resolve("workflow", "wf-ok") is not None
198+
assert any("its tool was skipped" in w for w in result.warnings)
199+
200+
201+
def test_dual_skip_reports_both_tool_and_connector_reasons():
202+
"""A workflow blocked by both a skipped tool and a skipped connector
203+
surfaces both reasons in one pass, not one per re-run.
204+
"""
205+
skipped_reg = "skipped-registry-id"
206+
skipped_conn = "oauth-conn-id"
207+
src = FakeClient([_src("wf-both", "Blocked WF")])
208+
src.tool_instances = [{"workflow": "wf-both", "tool_id": skipped_reg}]
209+
src.endpoints = [
210+
{
211+
"workflow": "wf-both",
212+
"endpoint_type": "SOURCE",
213+
"connector_instance": {"id": skipped_conn},
214+
}
215+
]
216+
tgt = FakeClient()
217+
ctx = _ctx(src, tgt)
218+
ctx.skipped_custom_tool_registry_ids.add(skipped_reg)
219+
ctx.skipped_connector_ids.add(skipped_conn)
220+
221+
result = WorkflowPhase(ctx).run(CloneReport())
222+
223+
assert result.skipped == 1
224+
assert tgt.posts == []
225+
assert ctx.remap.resolve("workflow", "wf-both") is None
226+
assert any("its tool was skipped" in w for w in result.warnings)
227+
assert any("un-clonable connector" in w for w in result.warnings)
198228

199229

200230
def test_cascade_skip_when_endpoint_connector_skipped():

0 commit comments

Comments
 (0)