Skip to content

feat(mlops): Add CleanupStep pipeline step - #6468

Open
nayan3107 wants to merge 5 commits into
aws:masterfrom
nayan3107:feat/cleanup-step
Open

nayan3107 wants to merge 5 commits into
aws:masterfrom
nayan3107:feat/cleanup-step

Conversation

@nayan3107

Copy link
Copy Markdown
Contributor

What: Add CleanupStep and S3CleanupSource to sagemaker.mlops.workflow. A Cleanup step deletes the S3 outputs of upstream steps: StepName-only for Training/Athena sources, StepName + exact S3Uris for Processing/Transform sources. depends_on defaults to the source steps.

Why: SageMaker Pipelines adds a Cleanup step type; this exposes it in the PySDK. Source-type rules, URI limits and VpcConfig checks are left to the service, which validates them at CreatePipeline.

Test:

7 unit tests, including a full Pipeline.definition() shape check; all 366 tests in sagemaker-mlops/tests/unit/workflow pass.
Integ test test_cleanup_step_deletes_processing_output passed in us-west-2: a Processing step writes two objects, Cleanup deletes one, and the test asserts Metadata.Cleanup.CleanedSteps and the resulting S3 state.

Add a CleanupStep that deletes the Amazon S3 outputs of upstream steps.
Each S3CleanupSource names a source step and, for Processing and
Transform steps, the exact object URIs to delete. Other rules (supported
source types, URI limits, VpcConfig) are left to the service, which
validates them at CreatePipeline. depends_on defaults to the source
steps since only outputs of completed steps can be deleted.

Integ test passed against a production region.
---
X-AI-Prompt: Add a PySDK CleanupStep with unit and integration tests and
raise a PR
X-AI-Tool: kiro-cli
# The service can only delete outputs of steps that already ran, so the
# sources are the natural dependencies.
if depends_on is None:
depends_on = [source.step for source in s3_sources]

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.

shouldn't we add these as additional dependencies if depends_on is not None?

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, agreed. The service doesn't enforce that a Cleanup step's DependsOn includes its sources, and StepName isn't a property reference, so an explicit depends_on could let Cleanup run before its source finished. The source steps are now always appended to any caller-provided depends_on (deduplicated by name), and the unit test covers the merge.

The service does not require a Cleanup step's DependsOn to include its
sources, so an explicit depends_on could let Cleanup run before its
source steps finished.
---
X-AI-Prompt: Address jkasiraj's PR comment to merge sources into depends_on
X-AI-Tool: kiro-cli
depends_on = [source.step for source in s3_sources]
# sources are always dependencies, in addition to any the caller passes.
depends_on = list(depends_on or [])
dependency_names = {dep if isinstance(dep, str) else dep.name for dep in depends_on}

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.

Does this handle all cases? We should add tests that cover each type of case. And use something like:

def _dependency_name(dep: Union[str, Step, StepCollection, StepOutput]) -> str:
    """The name of the step a `depends_on` entry refers to."""
    if isinstance(dep, str):
        return dep
    if isinstance(dep, StepCollection):
        return dep.steps[-1].name
    if isinstance(dep, StepOutput):
        return get_step(dep).name
    return dep.name

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 call, it didn't. A StepOutput entry raised AttributeError (no .name), and a StepCollection was matched by its own name rather than its last step. Switched to _dependency_name as suggested, with parametrized tests over str / Step / StepCollection / StepOutput (043d0c7). Since #6475 merged, I also merged master and taught it StepDependency, so depends_on=[StepDependency(train, TriggerCondition.ANY)] keeps the caller's trigger instead of adding a conflicting Completed edge (b9132bf).

nayan3107 added 3 commits October 15, 2026 14:45
A StepOutput entry raised AttributeError and a StepCollection was
matched by its own name instead of its last step, so the source could
be appended twice.
---
X-AI-Prompt: Address jkasiraj's PR comment to handle all depends_on types
X-AI-Tool: kiro-cli
A source listed with a run condition was not recognized, so a second
plain Completed edge was appended and compilation failed on
conflicting triggers.
---
X-AI-Prompt: Fix CleanupStep for the merged run conditions PR
X-AI-Tool: kiro-cli

This branch is waiting to be deployed

1 waiting deployment
manual-approval — b9132bf5 Waiting Oct 16, 2026 by nayan3107 via wait-for-approval #2053
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.

2 participants