<@ULVA73B9P> How to make the shell script step in ...
# ask-marvin
p
@Marvin How to make the shell script step in the build section to be run only if it is called explicitly in the steps further and not immediately
m
thought for 229.1 seconds
Short answer: you can’t. In Prefect 3.x, steps in the build (and push) sections of prefect.yaml always run sequentially during prefect deploy. There isn’t a built‑in “lazy” step that only runs when referenced later. Workable patterns to achieve the outcome: - Gate the shell step with a flag (custom step) - Create a tiny custom step that returns a default when a flag is false and only runs the shell script when the flag is true. Then reference its output from later steps. - Example:
Copy code
# 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}
Copy code
# 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.
Copy code
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.