This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 72e5a31825 Add release management command that generates SHOM 
information (#31835)
72e5a31825 is described below

commit 72e5a318257d813784f89dab7fa86f1a9111abbb
Author: Jarek Potiuk <[email protected]>
AuthorDate: Wed Jun 14 09:50:12 2023 +0200

    Add release management command that generates SHOM information (#31835)
    
    We should generate machine-readable SBOM information for our
    users to consume, therefore we need to have an automated process
    to generate dependency information. We are using cyclonedx standard
    to generate the information from two sources:
    
    * constraints of airlfow for PyPI dependencies
    * yarn.lock to generate npm dependencies
    
    The script uses officially published docker container of the
    CycloneDX organisation that parses both constraints of ours
    and yarn lock and produces standard-compliant json output.
    
    The SBOM information is published on our website under
    the URL scheme:
    
    
https://airflow.apache.org/docs/apache-airflow/<version>/sbom/apache-airflow-sbom-pythonX.Y.json
    
    Since there are different versions for different Python versions,
    we are publishing SBOM files for all Python
---
 BREEZE.rst                                         |  15 ++
 .../src/airflow_breeze/commands/ci_commands.py     |   3 +-
 .../commands/release_management_commands.py        | 188 +++++++++++++++++++-
 .../commands/release_management_commands_config.py |  22 +++
 dev/breeze/src/airflow_breeze/global_constants.py  |   4 +
 dev/breeze/src/airflow_breeze/utils/cdxgen.py      | 190 +++++++++++++++++++++
 dev/breeze/src/airflow_breeze/utils/github.py      | 110 ++++++++++++
 .../src/airflow_breeze/utils/github_actions.py     |  30 ----
 dev/breeze/src/airflow_breeze/utils/parallel.py    |   6 +
 dev/breeze/src/airflow_breeze/utils/path_utils.py  |   1 +
 .../src/airflow_breeze/utils/selective_checks.py   |   3 +-
 images/breeze/output-commands-hash.txt             |   9 +-
 images/breeze/output_release-management.svg        |  14 +-
 ..._release-management_update-sbom-information.svg | 182 ++++++++++++++++++++
 .../output_setup_check-all-params-in-groups.svg    |  10 +-
 .../output_setup_regenerate-command-images.svg     |  36 ++--
 16 files changed, 759 insertions(+), 64 deletions(-)

diff --git a/BREEZE.rst b/BREEZE.rst
index 1c19c53dd7..4d7e474601 100644
--- a/BREEZE.rst
+++ b/BREEZE.rst
@@ -1955,6 +1955,21 @@ These are all of the available flags for the 
``release-prod-images`` command:
   :width: 100%
   :alt: Breeze release management release prod images
 
+Generating SBOM information
+...........................
+
+Thanks to our constraints captured for all versions of Airflow we can easily 
generate SBOM information for
+Apache Airflow. SBOM information contains information about Airflow 
dependencies that are possible to consume
+by our users and allow them to determine whether security issues in 
dependencies affect them. The SBOM
+information is written directly to ``docs-archive`` in airflow-site repository.
+
+These are all of the available flags for the ``update-sbom-information`` 
command:
+
+.. image:: 
./images/breeze/output_release-management_update-sbom-information.svg
+  :target: 
https://raw.githubusercontent.com/apache/airflow/main/images/breeze/output_release-management_update-sbom-information.svg
+  :width: 100%
+  :alt: Breeze release management update sbom information
+
 
 Details of Breeze usage
 =======================
diff --git a/dev/breeze/src/airflow_breeze/commands/ci_commands.py 
b/dev/breeze/src/airflow_breeze/commands/ci_commands.py
index 30f3fd123f..c35fa34302 100644
--- a/dev/breeze/src/airflow_breeze/commands/ci_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/ci_commands.py
@@ -53,7 +53,6 @@ from airflow_breeze.utils.docker_command_utils import (
     fix_ownership_using_docker,
     perform_environment_checks,
 )
-from airflow_breeze.utils.github_actions import get_ga_output
 from airflow_breeze.utils.path_utils import AIRFLOW_SOURCES_ROOT, 
MSSQL_TMP_DIR_NAME
 from airflow_breeze.utils.run_utils import run_command
 
@@ -283,6 +282,8 @@ class WorkflowInfo(NamedTuple):
     pr_number: int | None
 
     def get_all_ga_outputs(self) -> Iterable[str]:
+        from airflow_breeze.utils.github import get_ga_output
+
         yield get_ga_output(name="pr_labels", 
value=str(self.pull_request_labels))
         yield get_ga_output(name="target_repo", value=self.target_repo)
         yield get_ga_output(name="head_repo", value=self.head_repo)
diff --git 
a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py 
b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index c9bf21589e..1cc0c3a8e0 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -17,6 +17,7 @@
 from __future__ import annotations
 
 import os
+import pathlib
 import re
 import shlex
 import sys
@@ -37,6 +38,7 @@ from airflow_breeze.commands.minor_release_command import 
create_minor_version_b
 from airflow_breeze.commands.release_candidate_command import 
publish_release_candidate
 from airflow_breeze.commands.release_command import airflow_release
 from airflow_breeze.global_constants import (
+    ALL_HISTORICAL_PYTHON_VERSIONS,
     ALLOWED_PLATFORMS,
     APACHE_AIRFLOW_GITHUB_REPOSITORY,
     CURRENT_PYTHON_MAJOR_MINOR_VERSIONS,
@@ -46,6 +48,7 @@ from airflow_breeze.global_constants import (
     MULTI_PLATFORM,
 )
 from airflow_breeze.params.shell_params import ShellParams
+from airflow_breeze.utils.cdxgen import SbomApplicationJob, 
get_cdxgen_port_mapping
 from airflow_breeze.utils.ci_group import ci_group
 from airflow_breeze.utils.click_utils import BreezeGroup
 from airflow_breeze.utils.common_options import (
@@ -84,11 +87,17 @@ from airflow_breeze.utils.docker_command_utils import (
 )
 from airflow_breeze.utils.parallel import (
     GenericRegexpProgressMatcher,
+    ShowLastLineProgressMatcher,
     SummarizeAfter,
     check_async_run_results,
     run_with_pool,
 )
-from airflow_breeze.utils.path_utils import AIRFLOW_SOURCES_ROOT, DIST_DIR, 
cleanup_python_generated_files
+from airflow_breeze.utils.path_utils import (
+    AIRFLOW_SOURCES_ROOT,
+    AIRFLOW_TMP_DIR_PATH,
+    DIST_DIR,
+    cleanup_python_generated_files,
+)
 from airflow_breeze.utils.provider_dependencies import DEPENDENCIES, 
get_related_providers
 from airflow_breeze.utils.python_versions import get_python_version_list
 from airflow_breeze.utils.run_utils import (
@@ -97,7 +106,7 @@ from airflow_breeze.utils.run_utils import (
     run_command,
     run_compile_www_assets,
 )
-from airflow_breeze.utils.shared_options import get_forced_answer
+from airflow_breeze.utils.shared_options import get_dry_run, get_forced_answer
 from airflow_breeze.utils.suspended_providers import get_suspended_provider_ids
 
 option_debug_release_management = click.option(
@@ -1103,6 +1112,181 @@ def generate_issue_content_providers(
         get_console().print(" ".join(users))
 
 
+SBOM_INDEX_TEMPLATE = """
+<html>
+<head><title>CycloneDX SBOMs for Apache Airflow {{ version }}</title></head>
+<body>
+    <h1>CycloneDX SBOMs for Apache Airflow {{ version }}</h1>
+    <ul>
+    {% for sbom_file in sbom_files %}
+        <li><a href="{{ sbom_file.name }}">{{ sbom_file.name }}</a></li>
+    {% endfor %}
+    </ul>
+</body>
+</html>
+"""
+
+
+@release_management.command(
+    name="update-sbom-information", help="Update SBOM information in 
airflow-site project."
+)
[email protected](
+    "--airflow-site-dir",
+    type=click.Path(file_okay=False, dir_okay=True, path_type=pathlib.Path, 
exists=True),
+    required=True,
+    envvar="AIRFLOW_SITE_DIR",
+    help="Directory where airflow-site directory is located.",
+)
[email protected](
+    "--airflow-version",
+    type=str,
+    required=False,
+    envvar="AIRFLOW_VERSION",
+    help="Version of airflow to update sbom from. (defaulted to all active 
airflow versions)",
+)
[email protected](
+    "--python",
+    type=BetterChoice(ALL_HISTORICAL_PYTHON_VERSIONS),
+    required=False,
+    envvar="PYTHON_VERSION",
+    help="Python version to update sbom from. (defaults to all python 
versions)",
+)
[email protected](
+    "--include-provider-dependencies",
+    is_flag=True,
+    help="Whether to include provider dependencies in SBOM generation.",
+)
+@option_run_in_parallel
+@option_parallelism
+@option_debug_resources
+@option_include_success_outputs
+@option_skip_cleanup
[email protected](
+    "--force",
+    is_flag=True,
+    help="Force update of sbom even if it already exists.",
+)
+@option_verbose
+@option_dry_run
+@option_answer
+def update_sbom_information(
+    airflow_site_dir: Path,
+    airflow_version: str | None,
+    python: str | None,
+    include_provider_dependencies: bool,
+    run_in_parallel: bool,
+    parallelism: int,
+    debug_resources: bool,
+    include_success_outputs: bool,
+    skip_cleanup: bool,
+    force: bool,
+):
+    import jinja2
+    from jinja2 import StrictUndefined
+
+    from airflow_breeze.utils.cdxgen import (
+        produce_sbom_for_application_via_cdxgen_server,
+        start_cdxgen_server,
+    )
+    from airflow_breeze.utils.github import get_active_airflow_versions
+
+    if airflow_version is None:
+        airflow_versions = get_active_airflow_versions()
+    else:
+        airflow_versions = [airflow_version]
+    if python is None:
+        python_versions = ALL_HISTORICAL_PYTHON_VERSIONS
+    else:
+        python_versions = [python]
+    application_root_path = AIRFLOW_TMP_DIR_PATH
+    start_cdxgen_server(application_root_path, run_in_parallel, parallelism)
+
+    jobs_to_run: list[SbomApplicationJob] = []
+
+    apache_airflow_dir = airflow_site_dir / "docs-archive" / "apache-airflow"
+
+    for airflow_v in airflow_versions:
+        airflow_version_dir = apache_airflow_dir / airflow_v
+        if not airflow_version_dir.exists():
+            get_console().print(f"[warning]The {airflow_version_dir} does not 
exist. Skipping")
+            continue
+        destination_dir = airflow_version_dir / "sbom"
+        destination_dir.mkdir(parents=True, exist_ok=True)
+        if destination_dir.exists():
+            if not force:
+                get_console().print(f"[warning]The {destination_dir} already 
exists. Skipping")
+                continue
+            else:
+                get_console().print(f"[warning]The {destination_dir} already 
exists. Forcing update")
+        get_console().print(f"[info]Attempting to update sbom for 
{airflow_v}.")
+        get_console().print(f"[success]The {destination_dir} exists. 
Proceeding.")
+        for python_version in python_versions:
+            target_sbom_file_name = 
f"apache-airflow-sbom-{airflow_v}-python{python_version}.json"
+            target_sbom_path = destination_dir / target_sbom_file_name
+            if target_sbom_path.exists():
+                if not force:
+                    get_console().print(f"[warning]The {target_sbom_path} 
already exists. Skipping")
+                    continue
+                else:
+                    get_console().print(f"[warning]The {target_sbom_path} 
already exists. Forcing update")
+            jobs_to_run.append(
+                SbomApplicationJob(
+                    airflow_version=airflow_v,
+                    python_version=python_version,
+                    application_root_path=application_root_path,
+                    
include_provider_dependencies=include_provider_dependencies,
+                    target_path=target_sbom_path,
+                )
+            )
+    if run_in_parallel:
+        parallelism = min(parallelism, len(jobs_to_run))
+        get_console().print(f"[info]Running {len(jobs_to_run)} jobs in 
parallel")
+        with ci_group(f"Generating SBoMs for 
{airflow_versions}:{python_versions}"):
+            all_params = [f"CI {job.airflow_version}:{job.python_version}" for 
job in jobs_to_run]
+            with run_with_pool(
+                parallelism=parallelism,
+                all_params=all_params,
+                debug_resources=debug_resources,
+                progress_matcher=ShowLastLineProgressMatcher(),
+            ) as (pool, outputs):
+                port_map = get_cdxgen_port_mapping(parallelism, pool)
+                results = [
+                    pool.apply_async(
+                        produce_sbom_for_application_via_cdxgen_server,
+                        kwds={
+                            "job": job,
+                            "output": outputs[index],
+                            "port_map": port_map,
+                        },
+                    )
+                    for index, job in enumerate(jobs_to_run)
+                ]
+        check_async_run_results(
+            results=results,
+            success="All SBoMs were generated successfully",
+            outputs=outputs,
+            include_success_outputs=include_success_outputs,
+            skip_cleanup=skip_cleanup,
+        )
+    else:
+        for job in jobs_to_run:
+            produce_sbom_for_application_via_cdxgen_server(job, output=None)
+
+    for airflow_v in airflow_versions:
+        airflow_version_dir = apache_airflow_dir / airflow_v
+        destination_dir = airflow_version_dir / "sbom"
+        destination_index_path = destination_dir / "index.html"
+        get_console().print(f"[info]Generating index for {destination_dir}")
+        sbom_files = sorted(destination_dir.glob("apache-airflow-sbom-*"))
+        html_template = SBOM_INDEX_TEMPLATE
+        if not get_dry_run():
+            destination_index_path.write_text(
+                jinja2.Template(html_template, autoescape=True, 
undefined=StrictUndefined).render(
+                    version=airflow_v, sbom_files=sbom_files
+                )
+            )
+
+
 # AIRFLOW RELEASE COMMANDS
 release_management.add_command(publish_release_candidate)
 release_management.add_command(airflow_release)
diff --git 
a/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py 
b/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
index a5076365e9..e3cf5605eb 100644
--- 
a/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
+++ 
b/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
@@ -151,6 +151,28 @@ RELEASE_MANAGEMENT_PARAMETERS: dict[str, list[dict[str, 
str | list[str]]]] = {
             ],
         }
     ],
+    "breeze release-management update-sbom-information": [
+        {
+            "name": "Update SBOM information flags",
+            "options": [
+                "--airflow-site-dir",
+                "--airflow-version",
+                "--python",
+                "--include-provider-dependencies",
+                "--force",
+            ],
+        },
+        {
+            "name": "Parallel running",
+            "options": [
+                "--run-in-parallel",
+                "--parallelism",
+                "--skip-cleanup",
+                "--debug-resources",
+                "--include-success-outputs",
+            ],
+        },
+    ],
     "breeze release-management start-rc-process": [
         {
             "name": "Start RC process flags",
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py 
b/dev/breeze/src/airflow_breeze/global_constants.py
index a4f2652d7b..3d0e7cb72b 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -138,9 +138,13 @@ ALLOWED_BUILD_CACHE = ["registry", "local", "disabled"]
 MULTI_PLATFORM = "linux/amd64,linux/arm64"
 SINGLE_PLATFORMS = ["linux/amd64", "linux/arm64"]
 ALLOWED_PLATFORMS = [*SINGLE_PLATFORMS, MULTI_PLATFORM]
+
 ALLOWED_USE_AIRFLOW_VERSIONS = ["none", "wheel", "sdist"]
 
 
+ALL_HISTORICAL_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
+
+
 def get_available_documentation_packages(short_version=False) -> list[str]:
     provider_names: list[str] = 
list(json.loads(DEPENDENCIES_JSON_FILE_PATH.read_text()).keys())
     doc_provider_names = [provider_name.replace(".", "-") for provider_name in 
provider_names]
diff --git a/dev/breeze/src/airflow_breeze/utils/cdxgen.py 
b/dev/breeze/src/airflow_breeze/utils/cdxgen.py
new file mode 100644
index 0000000000..acc713d4cc
--- /dev/null
+++ b/dev/breeze/src/airflow_breeze/utils/cdxgen.py
@@ -0,0 +1,190 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import atexit
+import multiprocessing
+import os
+import signal
+import sys
+import time
+from dataclasses import dataclass
+from multiprocessing.pool import Pool
+from pathlib import Path
+
+from airflow_breeze.utils.console import Output, get_console
+from airflow_breeze.utils.github import download_file_from_github
+from airflow_breeze.utils.run_utils import run_command
+from airflow_breeze.utils.shared_options import get_dry_run
+
+
+def start_cdxgen_server(application_root_path: Path, run_in_parallel: bool, 
parallelism: int) -> None:
+    """
+    Start cdxgen server that is used to perform cdxgen scans of applications 
in child process
+    :param run_in_parallel: run parallel servers
+    :param parallelism: parallelism to use
+    :param application_root_path: path where the application to scan is located
+    """
+    run_command(
+        [
+            "docker",
+            "pull",
+            "ghcr.io/cyclonedx/cdxgen",
+        ],
+        check=True,
+    )
+    if not run_in_parallel:
+        fork_cdxgen_server(application_root_path)
+    else:
+        for i in range(parallelism):
+            fork_cdxgen_server(application_root_path, port=9091 + i)
+    time.sleep(1)
+    get_console().print("[info]Waiting for cdxgen server to start")
+    time.sleep(3)
+
+
+def fork_cdxgen_server(application_root_path, port=9090):
+    pid = os.fork()
+    if pid:
+        # Parent process - send signal to process group of the child process
+        atexit.register(os.killpg, pid, signal.SIGTERM)
+        # Give the server child process some time to start
+    else:
+        # Check if we are not a group leader already (We should not be)
+        if os.getpid() != os.getsid(0):
+            # and create a new process group where we are the leader
+            os.setpgid(0, 0)
+        run_command(
+            [
+                "docker",
+                "run",
+                "--init",
+                "--rm",
+                "-p",
+                f"{port}:{port}",
+                "-v",
+                "/tmp:/tmp",
+                "-v",
+                f"{application_root_path}:/app",
+                "-t",
+                "ghcr.io/cyclonedx/cdxgen",
+                "--server",
+                "--server-host",
+                "0.0.0.0",
+                "--server-port",
+                str(port),
+            ],
+            check=True,
+        )
+        # we should get here when the server gets terminated
+        sys.exit(0)
+
+
+def get_port_mapping(x):
+    # if we do not sleep here, then we could skip mapping for some process if 
it is handle
+    time.sleep(1)
+    return multiprocessing.current_process().name, 9091 + x
+
+
+def get_cdxgen_port_mapping(parallelism: int, pool: Pool) -> dict[str, int]:
+    """
+    Map processes from pool to port numbers so that there is always the same 
port
+    used by the same process in the pool - effectively having one 
multiprocessing
+    process talking to the same cdxgen server
+
+    :param parallelism: parallelism to use
+    :param pool: pool to map ports for
+    :return: mapping of process name to port
+    """
+    port_map: dict[str, int] = dict(pool.map(get_port_mapping, 
range(parallelism)))
+    return port_map
+
+
+@dataclass
+class SbomApplicationJob:
+    airflow_version: str
+    python_version: str
+    application_root_path: Path
+    include_provider_dependencies: bool
+    target_path: Path
+
+
+def produce_sbom_for_application_via_cdxgen_server(
+    job: SbomApplicationJob, output: Output | None, port_map: dict[str, int] | 
None = None
+) -> tuple[int, str]:
+    """
+    Produces SBOM for application using cdxgen server.
+    :param job: Job to run
+    :param output: Output to use
+    :param port_map map of process name to port - making sure that one process 
talks to one server
+         in case parallel processing is used
+    :return: tuple with exit code and output
+    """
+    import requests
+
+    if port_map is None:
+        port = 9090
+    else:
+        port = port_map[multiprocessing.current_process().name]
+        get_console(output=output).print(f"[info]Using port {port}")
+    get_console(output=output).print(
+        f"[info]Updating sbom for Airflow {job.airflow_version} and python 
{job.python_version}"
+    )
+    source_dir = job.application_root_path / job.airflow_version / 
job.python_version
+    source_dir.mkdir(parents=True, exist_ok=True)
+    constraints_tag = f"constraints-{job.airflow_version}"
+    lock_file_relative_path = "airflow/www/yarn.lock"
+    download_file_from_github(
+        tag=job.airflow_version, path=lock_file_relative_path, 
output_file=source_dir / "yarn.lock"
+    )
+    if job.include_provider_dependencies:
+        constraints_file_path = f"constraints-{job.python_version}.txt"
+    else:
+        constraints_file_path = 
f"constraints-no-providers-{job.python_version}.txt"
+    if not download_file_from_github(
+        tag=constraints_tag,
+        path=constraints_file_path,
+        output_file=source_dir / "requirements.txt",
+    ):
+        get_console(output=output).print(
+            f"[warning]Failed to download constraints file for "
+            f"{job.airflow_version} and {job.python_version}. Skipping"
+        )
+        return 0, f"SBOM Generate {job.airflow_version}:{job.python_version}"
+    get_console(output=output).print(
+        f"[info]Generating sbom for Airflow {job.airflow_version} and python 
{job.python_version} with cdxgen"
+    )
+    url = (
+        
f"http://127.0.0.1:{port}/sbom?path=/app/{job.airflow_version}/{job.python_version}&";
+        
f"project-name=apache-airflow&project-version={job.airflow_version}&multiProject=true"
+    )
+    get_console(output=output).print(f"[info]Triggering sbom generation in 
{job.airflow_version} via {url}")
+    if not get_dry_run():
+        response = requests.get(url)
+        if response.status_code != 200:
+            get_console(output=output).print(
+                f"[error]Generation for Airflow 
{job.airflow_version}:{job.python_version} failed. "
+                f"Status code {response.status_code}"
+            )
+            return response.status_code, f"SBOM Generate 
{job.airflow_version}:{job.python_version}"
+        job.target_path.write_bytes(response.content)
+        get_console(output=output).print(
+            f"[success]Generated SBOM for 
{job.airflow_version}:{job.python_version}"
+        )
+
+    return 0, f"SBOM Generate {job.airflow_version}:{job.python_version}"
diff --git a/dev/breeze/src/airflow_breeze/utils/github.py 
b/dev/breeze/src/airflow_breeze/utils/github.py
new file mode 100644
index 0000000000..370055ff0c
--- /dev/null
+++ b/dev/breeze/src/airflow_breeze/utils/github.py
@@ -0,0 +1,110 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import re
+import sys
+from pathlib import Path
+from typing import Any
+
+from rich.markup import escape
+
+from airflow_breeze.utils.confirm import Answer, user_confirm
+from airflow_breeze.utils.console import get_console
+from airflow_breeze.utils.path_utils import AIRFLOW_SOURCES_ROOT
+from airflow_breeze.utils.shared_options import get_dry_run
+
+
+def get_ga_output(name: str, value: Any) -> str:
+    output_name = name.replace("_", "-")
+    printed_value = str(value).lower() if isinstance(value, bool) else value
+    get_console().print(f"[info]{output_name}[/] = 
[green]{escape(str(printed_value))}[/]")
+    return f"{output_name}={printed_value}"
+
+
+def download_file_from_github(tag: str, path: str, output_file: Path) -> bool:
+    """
+    Downloads a file from GitHub repository of Apache Airflow
+
+    :param tag: tag to download from
+    :param path: path of the file relative to the repository root
+    :param output_file: Path where the file should be downloaded
+    :return: whether the file was successfully downloaded (False if the file 
is missing or error occurred)
+    """
+    import requests
+
+    url = f"https://raw.githubusercontent.com/apache/airflow/{tag}/{path}";
+    get_console().print(f"[info]Downloading {url} to {output_file}")
+    if not get_dry_run():
+        response = requests.get(url)
+        if response.status_code == 404:
+            get_console().print(f"[warning]The {url} has not been found. 
Skipping")
+            return False
+        if response.status_code != 200:
+            get_console().print(
+                f"[error]The {url} could not be downloaded. Status code 
{response.status_code}"
+            )
+            return False
+        output_file.write_bytes(response.content)
+    get_console().print(f"[success]Downloaded {url} to {output_file}")
+    return True
+
+
+ACTIVE_TAG_MATCH = re.compile(r"^(\d+)\.\d+\.\d+$")
+
+
+def get_active_airflow_versions() -> list[str]:
+    """
+    Gets list of active Airflow versions from GitHub.
+    :return: list of active Airflow versions
+    """
+    from git import GitCommandError, Repo
+    from packaging.version import Version
+
+    get_console().print(
+        "\n[warning]Make sure you have 'apache` remote added pointing to 
apache/airflow repository\n"
+    )
+    get_console().print("[info]Fetching all released Airflow 2 versions from 
GitHub[/]\n")
+    repo = Repo(AIRFLOW_SOURCES_ROOT)
+    all_active_tags: list[str] = []
+    try:
+        ref_tags = repo.git.ls_remote("--tags", "apache").split("\n")
+    except GitCommandError as ex:
+        get_console().print(
+            "[error]Could not fetch tags from `apache` remote! Make sure to 
have it configured.\n"
+        )
+        get_console().print(f"{ex}\n")
+        get_console().print(
+            "[info]You can add apache remote with on of those commands (depend 
which protocol you use):\n"
+            " * git remote add apache https://github.com/apache/airflow.git\n";
+            " * git remote add apache [email protected]:apache/airflow.git\n"
+        )
+        sys.exit(1)
+    tags = [tag.split("refs/tags/")[1].strip() for tag in ref_tags if 
"refs/tags/" in tag]
+    for tag in tags:
+        match = ACTIVE_TAG_MATCH.match(tag)
+        if match and match.group(1) == "2":
+            all_active_tags.append(tag)
+    airflow_versions = sorted(all_active_tags, key=lambda x: Version(x))
+    get_console().print(f"All Airflow 2 versions: {all_active_tags}")
+    answer = user_confirm(
+        "Should we continue with those versions?", quit_allowed=False, 
default_answer=Answer.YES
+    )
+    if answer == Answer.NO:
+        get_console().print("[red]Aborting[/]")
+        sys.exit(1)
+    return airflow_versions
diff --git a/dev/breeze/src/airflow_breeze/utils/github_actions.py 
b/dev/breeze/src/airflow_breeze/utils/github_actions.py
deleted file mode 100644
index 6b8043aa7e..0000000000
--- a/dev/breeze/src/airflow_breeze/utils/github_actions.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-from __future__ import annotations
-
-from typing import Any
-
-from rich.markup import escape
-
-from airflow_breeze.utils.console import get_console
-
-
-def get_ga_output(name: str, value: Any) -> str:
-    output_name = name.replace("_", "-")
-    printed_value = str(value).lower() if isinstance(value, bool) else value
-    get_console().print(f"[info]{output_name}[/] = 
[green]{escape(str(printed_value))}[/]")
-    return f"{output_name}={printed_value}"
diff --git a/dev/breeze/src/airflow_breeze/utils/parallel.py 
b/dev/breeze/src/airflow_breeze/utils/parallel.py
index 790c11e72b..629d757e74 100644
--- a/dev/breeze/src/airflow_breeze/utils/parallel.py
+++ b/dev/breeze/src/airflow_breeze/utils/parallel.py
@@ -118,6 +118,12 @@ class AbstractProgressInfoMatcher(metaclass=ABCMeta):
         """
 
 
+class ShowLastLineProgressMatcher(AbstractProgressInfoMatcher):
+    def get_best_matching_lines(self, output: Output) -> list[str] | None:
+        last_lines, _ = get_last_lines_of_file(output.file_name, num_lines=1)
+        return last_lines
+
+
 class DockerBuildxProgressMatcher(AbstractProgressInfoMatcher):
     DOCKER_BUILDX_PROGRESS_MATCHER = re.compile(r"\s*#(\d*) ")
 
diff --git a/dev/breeze/src/airflow_breeze/utils/path_utils.py 
b/dev/breeze/src/airflow_breeze/utils/path_utils.py
index 1e8747cbbb..fe3a1a0cd7 100644
--- a/dev/breeze/src/airflow_breeze/utils/path_utils.py
+++ b/dev/breeze/src/airflow_breeze/utils/path_utils.py
@@ -268,6 +268,7 @@ AIRFLOW_PROVIDERS_ROOT = AIRFLOW_SOURCES_ROOT / "airflow" / 
"providers"
 BUILD_CACHE_DIR = AIRFLOW_SOURCES_ROOT / ".build"
 DEPENDENCIES_JSON_FILE_PATH = AIRFLOW_SOURCES_ROOT / "generated" / 
"provider_dependencies.json"
 WWW_CACHE_DIR = BUILD_CACHE_DIR / "www"
+AIRFLOW_TMP_DIR_PATH = AIRFLOW_SOURCES_ROOT / "tmp"
 WWW_ASSET_COMPILE_LOCK = WWW_CACHE_DIR / ".asset_compile.lock"
 WWW_ASSET_OUT_FILE = WWW_CACHE_DIR / "asset_compile.out"
 WWW_ASSET_OUT_DEV_MODE_FILE = WWW_CACHE_DIR / "asset_compile_dev_mode.out"
diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py 
b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
index 4c2ee6c304..6aa79df7cb 100644
--- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
+++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
@@ -55,7 +55,6 @@ from airflow_breeze.global_constants import (
 )
 from airflow_breeze.utils.console import get_console
 from airflow_breeze.utils.exclude_from_matrix import excluded_combos
-from airflow_breeze.utils.github_actions import get_ga_output
 from airflow_breeze.utils.kubernetes_utils import get_kubernetes_python_combos
 from airflow_breeze.utils.path_utils import (
     AIRFLOW_PROVIDERS_ROOT,
@@ -322,6 +321,8 @@ class SelectiveChecks:
         )
 
     def __str__(self) -> str:
+        from airflow_breeze.utils.github import get_ga_output
+
         output = []
         for field_name in dir(self):
             if not field_name.startswith("_"):
diff --git a/images/breeze/output-commands-hash.txt 
b/images/breeze/output-commands-hash.txt
index 1d9780c348..b0fc9aa209 100644
--- a/images/breeze/output-commands-hash.txt
+++ b/images/breeze/output-commands-hash.txt
@@ -45,15 +45,16 @@ 
release-management:prepare-provider-packages:cf41c33c6d6121efef1f1d97333e8710
 release-management:release-prod-images:9bf4731e91c435e9df17199c395a23fb
 release-management:start-rc-process:6aafbaceabd7b67b9a1af4c2f59abc4c
 release-management:start-release:acb384d86e02ff5fde1bf971897be17c
+release-management:update-sbom-information:e6c43441fdda06a7f0d3574de2951360
 release-management:verify-provider-packages:566c60fb1bfdc5ed7c4be590736891b2
-release-management:e30735d4b3903a168d8542fca0d92b6d
+release-management:5d53c2230b52ba36cd8bdd65b42da4bc
 setup:autocomplete:03343478bf1d0cf9c101d454cdb63b68
-setup:check-all-params-in-groups:1a6a07dcef12a55bf42bcbcef0d86adc
+setup:check-all-params-in-groups:27a55838171cf07c35e314c43fd73270
 setup:config:2db1944d8fcb030d4db329a1ff28dd19
-setup:regenerate-command-images:873006338375c95a3d683da214366191
+setup:regenerate-command-images:dfb756874dc71ebef60dc0bfd788e06b
 setup:self-upgrade:d02f70c7a230eae3463ceec2056b63fa
 setup:version:123b462a421884dc2320ffc5e54b2478
-setup:20e12e09d796ffb8c5b45daed12eac2f
+setup:66256c0ba3ae0ffd15b986cbd466ca52
 shell:13f90c5749811e2f00e24d95e44e946d
 start-airflow:22c118d58b13a9d190e966bed5bb8ed8
 static-checks:9985d1db64592e29ab71b8a000ce302e
diff --git a/images/breeze/output_release-management.svg 
b/images/breeze/output_release-management.svg
index 9ea0d2537c..9ac9bf686f 100644
--- a/images/breeze/output_release-management.svg
+++ b/images/breeze/output_release-management.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 489.2" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 513.5999999999999" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -42,7 +42,7 @@
 
     <defs>
     <clipPath id="breeze-release-management-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="438.2" />
+      <rect x="0" y="0" width="1463.0" height="462.59999999999997" />
     </clipPath>
     <clipPath id="breeze-release-management-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -95,9 +95,12 @@
 <clipPath id="breeze-release-management-line-16">
     <rect x="0" y="391.9" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-release-management-line-17">
+    <rect x="0" y="416.3" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="487.2" rx="8"/><text 
class="breeze-release-management-title" fill="#c5c8c6" text-anchor="middle" 
x="740" y="27">Command:&#160;release-management</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="511.6" rx="8"/><text 
class="breeze-release-management-title" fill="#c5c8c6" text-anchor="middle" 
x="740" y="27">Command:&#160;release-management</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -123,8 +126,9 @@
 </text><text class="breeze-release-management-r5" x="0" y="337.2" 
textLength="12.2" 
clip-path="url(#breeze-release-management-line-13)">│</text><text 
class="breeze-release-management-r4" x="24.4" y="337.2" textLength="414.8" 
clip-path="url(#breeze-release-management-line-13)">prepare-provider-documentation&#160;&#160;&#160;&#160;</text><text
 class="breeze-release-management-r2" x="463.6" y="337.2" textLength="97.6" 
clip-path="url(#breeze-release-management-line-13)">Prepare&#160;</text>< [...]
 </text><text class="breeze-release-management-r5" x="0" y="361.6" 
textLength="12.2" 
clip-path="url(#breeze-release-management-line-14)">│</text><text 
class="breeze-release-management-r4" x="24.4" y="361.6" textLength="414.8" 
clip-path="url(#breeze-release-management-line-14)">prepare-provider-packages&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-release-management-r2" x="463.6" y="361.6" textLength="976" 
clip-path="url(#breeze-release-management-line-14 [...]
 </text><text class="breeze-release-management-r5" x="0" y="386" 
textLength="12.2" 
clip-path="url(#breeze-release-management-line-15)">│</text><text 
class="breeze-release-management-r4" x="24.4" y="386" textLength="414.8" 
clip-path="url(#breeze-release-management-line-15)">release-prod-images&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-release-management-r2" x="463.6" y="386" textLength="976" 
clip-path="url(#breeze-re [...]
-</text><text class="breeze-release-management-r5" x="0" y="410.4" 
textLength="12.2" 
clip-path="url(#breeze-release-management-line-16)">│</text><text 
class="breeze-release-management-r4" x="24.4" y="410.4" textLength="414.8" 
clip-path="url(#breeze-release-management-line-16)">verify-provider-packages&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-release-management-r2" x="463.6" y="410.4" textLength="976" 
clip-path="url(#breeze-release-management-li [...]
-</text><text class="breeze-release-management-r5" x="0" y="434.8" 
textLength="1464" 
clip-path="url(#breeze-release-management-line-17)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-release-management-r2" x="1464" y="434.8" textLength="12.2" 
clip-path="url(#breeze-release-management-line-17)">
+</text><text class="breeze-release-management-r5" x="0" y="410.4" 
textLength="12.2" 
clip-path="url(#breeze-release-management-line-16)">│</text><text 
class="breeze-release-management-r4" x="24.4" y="410.4" textLength="414.8" 
clip-path="url(#breeze-release-management-line-16)">update-sbom-information&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-release-management-r2" x="463.6" y="410.4" textLength="85.4" 
clip-path="url(#breeze-release-managem [...]
+</text><text class="breeze-release-management-r5" x="0" y="434.8" 
textLength="12.2" 
clip-path="url(#breeze-release-management-line-17)">│</text><text 
class="breeze-release-management-r4" x="24.4" y="434.8" textLength="414.8" 
clip-path="url(#breeze-release-management-line-17)">verify-provider-packages&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-release-management-r2" x="463.6" y="434.8" textLength="976" 
clip-path="url(#breeze-release-management-li [...]
+</text><text class="breeze-release-management-r5" x="0" y="459.2" 
textLength="1464" 
clip-path="url(#breeze-release-management-line-18)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-release-management-r2" x="1464" y="459.2" textLength="12.2" 
clip-path="url(#breeze-release-management-line-18)">
 </text>
     </g>
     </g>
diff --git 
a/images/breeze/output_release-management_update-sbom-information.svg 
b/images/breeze/output_release-management_update-sbom-information.svg
new file mode 100644
index 0000000000..da92384992
--- /dev/null
+++ b/images/breeze/output_release-management_update-sbom-information.svg
@@ -0,0 +1,182 @@
+<svg class="rich-terminal" viewBox="0 0 1482 782.0" 
xmlns="http://www.w3.org/2000/svg";>
+    <!-- Generated with Rich https://www.textualize.io -->
+    <style>
+
+    @font-face {
+        font-family: "Fira Code";
+        src: local("FiraCode-Regular"),
+                
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2";)
 format("woff2"),
+                
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff";)
 format("woff");
+        font-style: normal;
+        font-weight: 400;
+    }
+    @font-face {
+        font-family: "Fira Code";
+        src: local("FiraCode-Bold"),
+                
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2";)
 format("woff2"),
+                
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff";)
 format("woff");
+        font-style: bold;
+        font-weight: 700;
+    }
+
+    .breeze-release-management-update-sbom-information-matrix {
+        font-family: Fira Code, monospace;
+        font-size: 20px;
+        line-height: 24.4px;
+        font-variant-east-asian: full-width;
+    }
+
+    .breeze-release-management-update-sbom-information-title {
+        font-size: 18px;
+        font-weight: bold;
+        font-family: arial;
+    }
+
+    .breeze-release-management-update-sbom-information-r1 { fill: 
#c5c8c6;font-weight: bold }
+.breeze-release-management-update-sbom-information-r2 { fill: #c5c8c6 }
+.breeze-release-management-update-sbom-information-r3 { fill: 
#d0b344;font-weight: bold }
+.breeze-release-management-update-sbom-information-r4 { fill: 
#68a0b3;font-weight: bold }
+.breeze-release-management-update-sbom-information-r5 { fill: #868887 }
+.breeze-release-management-update-sbom-information-r6 { fill: #cc555a }
+.breeze-release-management-update-sbom-information-r7 { fill: #8d7b39 }
+.breeze-release-management-update-sbom-information-r8 { fill: #8a4346 }
+.breeze-release-management-update-sbom-information-r9 { fill: 
#98a84b;font-weight: bold }
+    </style>
+
+    <defs>
+    <clipPath 
id="breeze-release-management-update-sbom-information-clip-terminal">
+      <rect x="0" y="0" width="1463.0" height="731.0" />
+    </clipPath>
+    <clipPath id="breeze-release-management-update-sbom-information-line-0">
+    <rect x="0" y="1.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-1">
+    <rect x="0" y="25.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-2">
+    <rect x="0" y="50.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-3">
+    <rect x="0" y="74.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-4">
+    <rect x="0" y="99.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-5">
+    <rect x="0" y="123.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-6">
+    <rect x="0" y="147.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-7">
+    <rect x="0" y="172.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-8">
+    <rect x="0" y="196.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-9">
+    <rect x="0" y="221.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-10">
+    <rect x="0" y="245.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-11">
+    <rect x="0" y="269.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-12">
+    <rect x="0" y="294.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-13">
+    <rect x="0" y="318.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-14">
+    <rect x="0" y="343.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-15">
+    <rect x="0" y="367.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-16">
+    <rect x="0" y="391.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-17">
+    <rect x="0" y="416.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-18">
+    <rect x="0" y="440.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-19">
+    <rect x="0" y="465.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-20">
+    <rect x="0" y="489.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-21">
+    <rect x="0" y="513.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-22">
+    <rect x="0" y="538.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-23">
+    <rect x="0" y="562.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-24">
+    <rect x="0" y="587.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-25">
+    <rect x="0" y="611.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-26">
+    <rect x="0" y="635.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-27">
+    <rect x="0" y="660.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-sbom-information-line-28">
+    <rect x="0" y="684.7" width="1464" height="24.65"/>
+            </clipPath>
+    </defs>
+
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="780" rx="8"/><text 
class="breeze-release-management-update-sbom-information-title" fill="#c5c8c6" 
text-anchor="middle" x="740" 
y="27">Command:&#160;release-management&#160;update-sbom-information</text>
+            <g transform="translate(26,22)">
+            <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+            <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+            <circle cx="44" cy="0" r="7" fill="#28c840"/>
+            </g>
+        
+    <g transform="translate(9, 41)" 
clip-path="url(#breeze-release-management-update-sbom-information-clip-terminal)">
+    
+    <g class="breeze-release-management-update-sbom-information-matrix">
+    <text class="breeze-release-management-update-sbom-information-r2" 
x="1464" y="20" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-0)">
+</text><text class="breeze-release-management-update-sbom-information-r3" 
x="12.2" y="44.4" textLength="85.4" 
clip-path="url(#breeze-release-management-update-sbom-information-line-1)">Usage:&#160;</text><text
 class="breeze-release-management-update-sbom-information-r1" x="97.6" y="44.4" 
textLength="622.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-1)">breeze&#160;release-management&#160;update-sbom-information&#160;[</text><text
 class="breeze-release-manageme [...]
+</text><text class="breeze-release-management-update-sbom-information-r2" 
x="1464" y="68.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-2)">
+</text><text class="breeze-release-management-update-sbom-information-r2" 
x="12.2" y="93.2" textLength="85.4" 
clip-path="url(#breeze-release-management-update-sbom-information-line-3)">Update&#160;</text><text
 class="breeze-release-management-update-sbom-information-r4" x="97.6" y="93.2" 
textLength="48.8" 
clip-path="url(#breeze-release-management-update-sbom-information-line-3)">SBOM</text><text
 class="breeze-release-management-update-sbom-information-r2" x="146.4" 
y="93.2" textLength="4 [...]
+</text><text class="breeze-release-management-update-sbom-information-r2" 
x="1464" y="117.6" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-4)">
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="142" textLength="24.4" 
clip-path="url(#breeze-release-management-update-sbom-information-line-5)">╭─</text><text
 class="breeze-release-management-update-sbom-information-r5" x="24.4" y="142" 
textLength="378.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-5)">&#160;Update&#160;SBOM&#160;information&#160;flags&#160;</text><text
 class="breeze-release-management-update-sbom-informatio [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="166.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-6)">│</text><text
 class="breeze-release-management-update-sbom-information-r6" x="24.4" 
y="166.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-6)">*</text><text
 class="breeze-release-management-update-sbom-information-r4" x="61" y="166.4" 
textLength="12.2" clip-path="u [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="190.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-7)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="61" y="190.8" 
textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-7)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="73.2" 
y="190.8" textLength="97.6" clip-path="u [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="215.2" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-8)">│</text><text
 class="breeze-release-management-update-sbom-information-r2" x="488" y="215.2" 
textLength="951.6" 
clip-path="url(#breeze-release-management-update-sbom-information-line-8)">versions)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="239.6" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-9)">│</text><text
 class="breeze-release-management-update-sbom-information-r7" x="488" y="239.6" 
textLength="951.6" 
clip-path="url(#breeze-release-management-update-sbom-information-line-9)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="264" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-10)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="61" y="264" 
textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-10)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="73.2" y="264" 
textLength="85.4" clip-path="url(# [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="288.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-11)">│</text><text
 class="breeze-release-management-update-sbom-information-r7" x="488" y="288.4" 
textLength="841.8" 
clip-path="url(#breeze-release-management-update-sbom-information-line-11)">(3.6&#160;|&#160;3.7&#160;|&#160;3.8&#160;|&#160;3.9&#160;|&#160;3.10&#160;|&#160;3.11)&#160;&#160;&#160;&#160;&#160;&#1
 [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="312.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-12)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="61" y="312.8" 
textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-12)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="73.2" 
y="312.8" textLength="97.6" clip-path= [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="337.2" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-13)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="61" y="337.2" 
textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-13)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="73.2" 
y="337.2" textLength="73.2" clip-path= [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="361.6" textLength="1464" 
clip-path="url(#breeze-release-management-update-sbom-information-line-14)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-release-management-update-sbom-information-r2" x="1464" 
y="361.6" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-14)">
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="386" textLength="24.4" 
clip-path="url(#breeze-release-management-update-sbom-information-line-15)">╭─</text><text
 class="breeze-release-management-update-sbom-information-r5" x="24.4" y="386" 
textLength="219.6" 
clip-path="url(#breeze-release-management-update-sbom-information-line-15)">&#160;Parallel&#160;running&#160;</text><text
 class="breeze-release-management-update-sbom-information-r5" x="244" y="386" 
[...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="410.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-16)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" 
y="410.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-16)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" 
y="410.4" textLength="48.8" clip-pat [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="434.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-17)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" 
y="434.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-17)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" 
y="434.8" textLength="146.4" clip-pa [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="459.2" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-18)">│</text><text
 class="breeze-release-management-update-sbom-information-r7" x="378.2" 
y="459.2" textLength="915" 
clip-path="url(#breeze-release-management-update-sbom-information-line-18)">(INTEGER&#160;RANGE)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16
 [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="483.6" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-19)">│</text><text
 class="breeze-release-management-update-sbom-information-r5" x="378.2" 
y="483.6" textLength="915" 
clip-path="url(#breeze-release-management-update-sbom-information-line-19)">[default:&#160;4;&#160;1&lt;=x&lt;=8]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="508" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-20)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" y="508" 
textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-20)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" y="508" 
textLength="61" clip-path="url(# [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="532.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-21)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" 
y="532.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-21)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" 
y="532.4" textLength="73.2" clip-pat [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="556.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-22)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" 
y="556.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-22)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" 
y="556.8" textLength="97.6" clip-pat [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="581.2" textLength="1464" 
clip-path="url(#breeze-release-management-update-sbom-information-line-23)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-release-management-update-sbom-information-r2" x="1464" 
y="581.2" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-23)">
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="605.6" textLength="24.4" 
clip-path="url(#breeze-release-management-update-sbom-information-line-24)">╭─</text><text
 class="breeze-release-management-update-sbom-information-r5" x="24.4" 
y="605.6" textLength="195.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-24)">&#160;Common&#160;options&#160;</text><text
 class="breeze-release-management-update-sbom-information-r5" x="219.6" y=" 
[...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="630" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-25)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" y="630" 
textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-25)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" y="630" 
textLength="97.6" clip-path="url [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="654.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-26)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" 
y="654.4" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-26)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" 
y="654.4" textLength="48.8" clip-pat [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="678.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-27)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" 
y="678.8" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-27)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" 
y="678.8" textLength="85.4" clip-pat [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="703.2" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-28)">│</text><text
 class="breeze-release-management-update-sbom-information-r4" x="24.4" 
y="703.2" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-28)">-</text><text
 class="breeze-release-management-update-sbom-information-r4" x="36.6" 
y="703.2" textLength="61" clip-path= [...]
+</text><text class="breeze-release-management-update-sbom-information-r5" 
x="0" y="727.6" textLength="1464" 
clip-path="url(#breeze-release-management-update-sbom-information-line-29)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-release-management-update-sbom-information-r2" x="1464" 
y="727.6" textLength="12.2" 
clip-path="url(#breeze-release-management-update-sbom-information-line-29)">
+</text>
+    </g>
+    </g>
+</svg>
diff --git a/images/breeze/output_setup_check-all-params-in-groups.svg 
b/images/breeze/output_setup_check-all-params-in-groups.svg
index f17b5e10b9..6e663cee02 100644
--- a/images/breeze/output_setup_check-all-params-in-groups.svg
+++ b/images/breeze/output_setup_check-all-params-in-groups.svg
@@ -155,11 +155,11 @@
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="361.6" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-14)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="361.6" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-14)">release-management:install-provider-packages&#160;|&#160;release-management:prepare-airflow-package&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="386" 
textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-15)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="386" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-15)">release-management:prepare-provider-documentation&#160;|&#160;release-management:prepare-provider-packages&#160;|&#160;&#160;&#160;&#160;&#160;</text><text
 class=" [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="410.4" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-16)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="410.4" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-16)">release-management:release-prod-images&#160;|&#160;release-management:start-rc-process&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
 [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="434.8" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-17)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="434.8" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-17)">release-management:start-release&#160;|&#160;release-management:verify-provider-packages&#160;|&#160;release-management&#160;|&#160;&#160;</text><text
 class="b [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="459.2" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-18)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="459.2" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-18)">setup:autocomplete&#160;|&#160;setup:check-all-params-in-groups&#160;|&#160;setup:config&#160;|&#160;setup:regenerate-command-images&#160;</text><text
 class="b [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="483.6" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-19)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="483.6" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-19)">|&#160;setup:self-upgrade&#160;|&#160;setup:version&#160;|&#160;setup&#160;|&#160;shell&#160;|&#160;start-airflow&#160;|&#160;static-checks&#160;|&#160;&#160;&
 [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="508" 
textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-20)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="508" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-20)">testing:docker-compose-tests&#160;|&#160;testing:helm-tests&#160;|&#160;testing:integration-tests&#160;|&#160;testing:tests&#160;|&#160;&#160;&#160;&#160;&#160;&#1
 [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="532.4" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-21)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="532.4" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-21)">testing)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="434.8" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-17)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="434.8" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-17)">release-management:start-release&#160;|&#160;release-management:update-sbom-information&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="459.2" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-18)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="459.2" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-18)">release-management:verify-provider-packages&#160;|&#160;release-management&#160;|&#160;setup:autocomplete&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="483.6" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-19)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="483.6" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-19)">setup:check-all-params-in-groups&#160;|&#160;setup:config&#160;|&#160;setup:regenerate-command-images&#160;|&#160;setup:self-upgrade&#160;</text><text
 class="b [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="508" 
textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-20)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="508" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-20)">|&#160;setup:version&#160;|&#160;setup&#160;|&#160;shell&#160;|&#160;start-airflow&#160;|&#160;static-checks&#160;|&#160;testing:docker-compose-tests&#160;|&#160;&
 [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="532.4" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-21)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="532.4" 
textLength="1256.6" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-21)">testing:helm-tests&#160;|&#160;testing:integration-tests&#160;|&#160;testing:tests&#160;|&#160;testing)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="556.8" textLength="1464" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-22)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-setup-check-all-params-in-groups-r2" x="1464" y="556.8" 
textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-22)">
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="581.2" textLength="24.4" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-23)">╭─</text><text
 class="breeze-setup-check-all-params-in-groups-r5" x="24.4" y="581.2" 
textLength="195.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-23)">&#160;Common&#160;options&#160;</text><text
 class="breeze-setup-check-all-params-in-groups-r5" x="219.6" y="581.2" 
textLength="1220" clip-path="url(#breeze-se [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" 
y="605.6" textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-24)">│</text><text 
class="breeze-setup-check-all-params-in-groups-r4" x="24.4" y="605.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-check-all-params-in-groups-line-24)">-</text><text 
class="breeze-setup-check-all-params-in-groups-r4" x="36.6" y="605.6" 
textLength="97.6" clip-path="url(#breeze-setup-check-all-params-in-groups-li 
[...]
diff --git a/images/breeze/output_setup_regenerate-command-images.svg 
b/images/breeze/output_setup_regenerate-command-images.svg
index d2b809e3b5..3c3db22746 100644
--- a/images/breeze/output_setup_regenerate-command-images.svg
+++ b/images/breeze/output_setup_regenerate-command-images.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 806.4" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 830.8" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-setup-regenerate-command-images-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="755.4" />
+      <rect x="0" y="0" width="1463.0" height="779.8" />
     </clipPath>
     <clipPath id="breeze-setup-regenerate-command-images-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -135,9 +135,12 @@
 <clipPath id="breeze-setup-regenerate-command-images-line-29">
     <rect x="0" y="709.1" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-setup-regenerate-command-images-line-30">
+    <rect x="0" y="733.5" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="804.4" rx="8"/><text 
class="breeze-setup-regenerate-command-images-title" fill="#c5c8c6" 
text-anchor="middle" x="740" 
y="27">Command:&#160;setup&#160;regenerate-command-images</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="828.8" rx="8"/><text 
class="breeze-setup-regenerate-command-images-title" fill="#c5c8c6" 
text-anchor="middle" x="740" 
y="27">Command:&#160;setup&#160;regenerate-command-images</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -165,19 +168,20 @@
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="386" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-15)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="386" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-15)">release-management:install-provider-packages&#160;|&#160;release-management:prepare-airflow-package&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text>
 [...]
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="410.4" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-16)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="410.4" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-16)">release-management:prepare-provider-documentation&#160;|&#160;release-management:prepare-provider-packages&#160;|&#160;&#160;</text><text
 class="breeze-setup-regen [...]
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="434.8" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-17)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="434.8" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-17)">release-management:release-prod-images&#160;|&#160;release-management:start-rc-process&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16
 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="459.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-18)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="459.2" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-18)">release-management:start-release&#160;|&#160;release-management:verify-provider-packages&#160;|&#160;release-management&#160;</text><text
 class="breeze-setup-regen [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="483.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-19)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="483.6" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-19)">|&#160;setup:autocomplete&#160;|&#160;setup:check-all-params-in-groups&#160;|&#160;setup:config&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="508" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-20)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="508" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-20)">setup:regenerate-command-images&#160;|&#160;setup:self-upgrade&#160;|&#160;setup:version&#160;|&#160;setup&#160;|&#160;shell&#160;|&#160;start-airflow</text><text
 clas [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="532.4" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-21)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="532.4" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-21)">|&#160;static-checks&#160;|&#160;testing:docker-compose-tests&#160;|&#160;testing:helm-tests&#160;|&#160;testing:integration-tests&#160;|&#160;&#160;&#160;</text><
 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="556.8" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-22)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="556.8" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-22)">testing:tests&#160;|&#160;testing)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1
 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="581.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-23)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="581.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-23)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="581.2" 
textLength="73.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-23) [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="605.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-24)">│</text><text 
class="breeze-setup-regenerate-command-images-r2" x="219.6" y="605.6" 
textLength="170.8" 
clip-path="url(#breeze-setup-regenerate-command-images-line-24)">together&#160;with&#160;</text><text
 class="breeze-setup-regenerate-command-images-r4" x="390.4" y="605.6" 
textLength="12.2" clip-path="url(#breeze-setup-regenera [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="630" 
textLength="1464" 
clip-path="url(#breeze-setup-regenerate-command-images-line-25)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-setup-regenerate-command-images-r2" x="1464" y="630" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-25)">
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="654.4" 
textLength="24.4" 
clip-path="url(#breeze-setup-regenerate-command-images-line-26)">╭─</text><text 
class="breeze-setup-regenerate-command-images-r5" x="24.4" y="654.4" 
textLength="195.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-26)">&#160;Common&#160;options&#160;</text><text
 class="breeze-setup-regenerate-command-images-r5" x="219.6" y="654.4" 
textLength="1220" clip-path="url(#breeze-setup-r [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="678.8" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-27)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="678.8" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-27)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="678.8" 
textLength="97.6" 
clip-path="url(#breeze-setup-regenerate-command-images-line-27) [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="703.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-28)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="703.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-28)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="703.2" 
textLength="48.8" 
clip-path="url(#breeze-setup-regenerate-command-images-line-28) [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="727.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-29)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="727.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-29)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="727.6" 
textLength="61" 
clip-path="url(#breeze-setup-regenerate-command-images-line-29)"> [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="752" 
textLength="1464" 
clip-path="url(#breeze-setup-regenerate-command-images-line-30)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-setup-regenerate-command-images-r2" x="1464" y="752" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-30)">
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="459.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-18)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="459.2" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-18)">release-management:start-release&#160;|&#160;release-management:update-sbom-information&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1
 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="483.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-19)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="483.6" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-19)">release-management:verify-provider-packages&#160;|&#160;release-management&#160;|&#160;setup:autocomplete&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1
 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="508" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-20)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="508" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-20)">setup:check-all-params-in-groups&#160;|&#160;setup:config&#160;|&#160;setup:regenerate-command-images&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="532.4" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-21)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="532.4" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-21)">setup:self-upgrade&#160;|&#160;setup:version&#160;|&#160;setup&#160;|&#160;shell&#160;|&#160;start-airflow&#160;|&#160;static-checks&#160;|&#160;&#160;&#160;&#160;
 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="556.8" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-22)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="556.8" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-22)">testing:docker-compose-tests&#160;|&#160;testing:helm-tests&#160;|&#160;testing:integration-tests&#160;|&#160;testing:tests&#160;|&#160;&#160;&#160;&#160;&#160;</t
 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="581.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-23)">│</text><text 
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="581.2" 
textLength="1220" 
clip-path="url(#breeze-setup-regenerate-command-images-line-23)">testing)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="605.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-24)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="605.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-24)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="605.6" 
textLength="73.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-24) [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="630" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-25)">│</text><text 
class="breeze-setup-regenerate-command-images-r2" x="219.6" y="630" 
textLength="170.8" 
clip-path="url(#breeze-setup-regenerate-command-images-line-25)">together&#160;with&#160;</text><text
 class="breeze-setup-regenerate-command-images-r4" x="390.4" y="630" 
textLength="12.2" clip-path="url(#breeze-setup-regenerate-com [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="654.4" 
textLength="1464" 
clip-path="url(#breeze-setup-regenerate-command-images-line-26)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-setup-regenerate-command-images-r2" x="1464" y="654.4" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-26)">
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="678.8" 
textLength="24.4" 
clip-path="url(#breeze-setup-regenerate-command-images-line-27)">╭─</text><text 
class="breeze-setup-regenerate-command-images-r5" x="24.4" y="678.8" 
textLength="195.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-27)">&#160;Common&#160;options&#160;</text><text
 class="breeze-setup-regenerate-command-images-r5" x="219.6" y="678.8" 
textLength="1220" clip-path="url(#breeze-setup-r [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="703.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-28)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="703.2" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-28)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="703.2" 
textLength="97.6" 
clip-path="url(#breeze-setup-regenerate-command-images-line-28) [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="727.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-29)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="727.6" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-29)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="727.6" 
textLength="48.8" 
clip-path="url(#breeze-setup-regenerate-command-images-line-29) [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="752" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-30)">│</text><text 
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="752" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-30)">-</text><text 
class="breeze-setup-regenerate-command-images-r4" x="36.6" y="752" 
textLength="61" 
clip-path="url(#breeze-setup-regenerate-command-images-line-30)">-help< [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="776.4" 
textLength="1464" 
clip-path="url(#breeze-setup-regenerate-command-images-line-31)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-setup-regenerate-command-images-r2" x="1464" y="776.4" 
textLength="12.2" 
clip-path="url(#breeze-setup-regenerate-command-images-line-31)">
 </text>
     </g>
     </g>


Reply via email to