Parvez Mohammed
10/28/2025, 8:17 AMMarvin
10/28/2025, 8:17 AMMarvin
10/28/2025, 8:21 AM# my_steps.py
import os
import subprocess
def maybe_run_shell(script: str, run: bool = False):
if not run:
return {"stdout": "", "skipped": True}
res = subprocess.run(script, shell=True, check=True, capture_output=True, text=True)
return {"stdout": res.stdout.strip(), "skipped": False}
# prefect.yaml
build:
- my_steps:maybe_run_shell:
id: get_sha
script: git rev-parse --short HEAD
run: "{{ env.RUN_GET_SHA | default(false) }}"
- prefect_docker.deployments.steps:build_docker_image:
image_name: my-image
tag: "{{ get_sha.stdout if not get_sha.skipped else 'latest' }}"
- When RUN_GET_SHA is not set/false, the shell doesn’t run and your later step uses a default.
- Run at runtime instead of deploy time
- If the goal is simply “don’t run during prefect deploy”, move the shell step to the pull section so it executes at flow run time (the worker), not at build time.
- Split or override deployments
- Define two deployments (or per‑deployment overrides) in prefect.yaml: one that includes the shell step and one that doesn’t. Use the appropriate deployment when you need the step.
- Template to conditionally include the step
- If you prefer templating, you can conditionally include the list item using Jinja and an env/variable flag. This effectively prevents the step from existing unless enabled.
build:
{% if env.RUN_GET_SHA | default(false) %}
- prefect.deployments.steps.utility:run_shell_script:
id: get_sha
script: git rev-parse --short HEAD
{% endif %}
- prefect_docker.deployments.steps:build_docker_image:
image_name: my-image
tag: "{{ get_sha.stdout if get_sha is defined else 'latest' }}"
References:
- prefect.yaml structure and steps
- run_shell_script step API
If you can share what “called explicitly in the steps further” means in your case (e.g., computing a Docker tag, writing a file, etc.), I can suggest the cleanest variant for your setup.