Skip to content

feat(mlops): Add run conditions to step dependencies - #6475

Merged
rsareddy0329 merged 2 commits into
aws:masterfrom
nayan3107:feat/run-conditions
Oct 15, 2026
Merged

rsareddy0329 merged 2 commits into
aws:masterfrom
nayan3107:feat/run-conditions

Conversation

@nayan3107

Copy link
Copy Markdown
Contributor

Add StepDependency and TriggerCondition so a step can run when an upstream step fails, stops, or reaches any terminal state. Completed dependencies are still emitted as plain step names, so existing pipeline definitions are unchanged. Local mode rejects non-Completed triggers because it stops on the first failed step.

Integ test passed against a production region.

X-AI-Prompt: Add backward compatible Run Conditions support to the PySDK and raise a PR against master
X-AI-Tool: kiro-cli

Issue #, if available:

Description of changes:

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Add StepDependency and TriggerCondition so a step can run when an
upstream step fails, stops, or reaches any terminal state. Completed
dependencies are still emitted as plain step names, so existing
pipeline definitions are unchanged. Local mode rejects non-Completed
triggers because it stops on the first failed step.

Integ test passed against a production region.
---
X-AI-Prompt: Add backward compatible Run Conditions support to the
PySDK and raise a PR against master
X-AI-Tool: kiro-cli
dependencies = {}
for item in step.depends_on or []:
if not isinstance(item, StepDependency):
continue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make sure we have unit tests for all possible combinations here of mixed StepDependency + str and pure types? I think some cases are not raising "conflicting triggers" when they should

depends_on= emitted DependsOn
["A"] ['A'] expected
[a] ['A'] expected
[a, "A"] ['A'] expected
[SD(a)] ['A'] expected
[SD(a, COMPLETED)] ['A'] expected
[SD(a, FAILED)] [{'Step':'A','Trigger':'Failed'}] expected
[SD(a, ANY)] [{'Step':'A','Trigger':'Any'}] expected
[SD(a,COMPLETED), SD(a,FAILED)] RAISES "conflicting triggers" expected
[SD(a,FAILED), SD("A",FAILED)] [{'Step':'A','Trigger':'Failed'}] expected
["A", SD(a,FAILED)] [{'Step':'A','Trigger':'Failed'}] incorrect?
[a, SD(a,FAILED)] [{'Step':'A','Trigger':'Failed'}] incorrect?
[SD(a,FAILED), "A"] [{'Step':'A','Trigger':'Failed'}] incorrect?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Plain entries are implicit Completed dependencies, but the conflict check skipped them, so ["A", SD(a, FAILED)] silently emitted Failed. Plain entries are now normalized to StepDependency(item) before the check, so those three cases raise conflicting triggers. Added parametrized tests covering every row in your table.

A plain step or step name listed next to a StepDependency on the same
step with a non-Completed trigger was ignored by the conflict check,
so the Completed dependency was silently dropped. Plain entries now
count as Completed and such combinations raise.
---
X-AI-Prompt: Address jkasiraj review on PR 6475 about mixed depends_on
conflict cases
X-AI-Tool: kiro-cli
@nayan3107
nayan3107 deployed to manual-approval October 15, 2026 19:25 — with GitHub Actions Active
@nayan3107
nayan3107 deployed to manual-approval October 15, 2026 19:25 — with GitHub Actions Active
@nayan3107
nayan3107 deployed to manual-approval October 15, 2026 19:25 — with GitHub Actions Active

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI code review

This PR adds StepDependency and TriggerCondition so a step's depends_on entry can be wired to run on an upstream step's failure, stop, or any terminal state. Completed dependencies are still emitted as plain step names, keeping existing pipeline definitions byte-identical, and local mode rejects non-Completed triggers. The implementation threads the new types cleanly through the compiler (_to_depends_on_request), Step._find_dependencies_in_depends_on_list, and the local executor, and is backed by thorough unit tests plus an integ test. Overall this looks correct and well-tested; I only have minor observations.

Reviewed commit 184a4ac. Automated review; verify before acting.

"""
if not isinstance(trigger, TriggerCondition):
raise TypeError(f"trigger must be a TriggerCondition, got {type(trigger).__name__}.")
self.step = get_step(step) if isinstance(step, StepOutput) else step

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Low: step_name returns self.step.name for the wrapped object. The base Step.depends_on type hint and _find_dependencies_in_depends_on_list both accept StepCollection, and for a StepCollection the real dependency target is steps[-1].name, not the collection's name. If someone wraps a StepCollection in a StepDependency, step_name/to_request would emit the collection name and produce an inconsistent DependsOn entry. The __init__ docstring only advertises Union[str, Step, StepOutput], so this is likely intentional scope — but consider either rejecting StepCollection explicitly or resolving it to steps[-1].name to avoid a silently wrong edge.


return list(depends_on), upstream_step_in_args

def _to_depends_on_request(self, step: Step, depends_on: List[Step]) -> List[Union[str, dict]]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Low: _to_depends_on_request calls self._simplify_step_list([item])[0].name once per entry in step.depends_on, giving O(n^2) resolution over the dependency list. Dependency lists are small so this is not a real performance concern, but resolving names into the dependencies map in a single pass (and only once per unique item) would be a touch cleaner.

@rsareddy0329
rsareddy0329 merged commit ce3ac25 into aws:master Oct 15, 2026
29 of 30 checks passed

This branch was successfully deployed

1 active deployment
manual-approval — 184a4ac3 Deployed Oct 15, 2026 by nayan3107 via wait-for-approval #2039
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants