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 84bd22c3d78 Add `localstack` Breeze integration (#54050)
84bd22c3d78 is described below

commit 84bd22c3d78aafc5939e1256bacc4918dc666829
Author: LIU ZHE YOU <[email protected]>
AuthorDate: Sat Sep 13 12:02:52 2025 -0500

    Add `localstack` Breeze integration (#54050)
    
    * Add localstack breeze integration
    
    * Fix Breeze unit test
    
    * Disbale test for localstack and export envs
    
    * Add docs for Running External System Integrations with Breeze
    
    * Fix output-commands.svg
---
 Dockerfile.ci                                      | 21 +++++++++
 contributing-docs/testing/integration_tests.rst    |  2 +
 dev/breeze/doc/03_developer_tasks.rst              | 23 ++++++++++
 dev/breeze/doc/images/output-commands.svg          | 50 +++++++++++-----------
 dev/breeze/doc/images/output_shell.txt             |  2 +-
 dev/breeze/doc/images/output_start-airflow.txt     |  2 +-
 .../output_testing_providers-integration-tests.svg |  4 +-
 .../output_testing_providers-integration-tests.txt |  2 +-
 dev/breeze/src/airflow_breeze/global_constants.py  |  2 +
 .../src/airflow_breeze/params/shell_params.py      |  1 +
 .../ci/docker-compose/integration-localstack.yml   | 37 ++++++++++++++++
 scripts/docker/entrypoint_ci.sh                    | 21 +++++++++
 12 files changed, 137 insertions(+), 30 deletions(-)

diff --git a/Dockerfile.ci b/Dockerfile.ci
index 230b25ba8ae..61eab57f2d1 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -1208,6 +1208,27 @@ function environment_initialization() {
         ssh-keyscan -H localhost >> ~/.ssh/known_hosts 2>/dev/null
     fi
 
+    if [[ ${INTEGRATION_LOCALSTACK:-"false"} == "true" ]]; then
+        echo
+        echo "${COLOR_BLUE}Configuring LocalStack integration${COLOR_RESET}"
+        echo
+
+        # Define LocalStack AWS configuration
+        declare -A localstack_config=(
+            ["AWS_ENDPOINT_URL"]="http://localstack:4566";
+            ["AWS_ACCESS_KEY_ID"]="test"
+            ["AWS_SECRET_ACCESS_KEY"]="test"
+            ["AWS_DEFAULT_REGION"]="us-east-1"
+        )
+
+        # Export each configuration variable and log it
+        for key in "${!localstack_config[@]}"; do
+            export "$key"="${localstack_config[$key]}"
+            echo "  * ${COLOR_BLUE}${key}:${COLOR_RESET} 
${localstack_config[$key]}"
+        done
+        echo
+    fi
+
     cd "${AIRFLOW_SOURCES}"
 
     # Temporarily add /opt/airflow/providers/standard/tests to PYTHONPATH in 
order to see example dags
diff --git a/contributing-docs/testing/integration_tests.rst 
b/contributing-docs/testing/integration_tests.rst
index a5d6c6deb87..af0554c48ab 100644
--- a/contributing-docs/testing/integration_tests.rst
+++ b/contributing-docs/testing/integration_tests.rst
@@ -70,6 +70,8 @@ core or provider type of test.
 +--------------+-------------------------------------------------------+
 | keycloak     | Integration for manual testing of multi-team Airflow. |
 +--------------+-------------------------------------------------------+
+| localstack   | Integration that emulates AWS services locally.       |
++--------------+-------------------------------------------------------+
 | mongo        | Integration required for MongoDB hooks.               |
 +--------------+-------------------------------------------------------+
 | mssql        | Integration required for mssql hooks.                 |
diff --git a/dev/breeze/doc/03_developer_tasks.rst 
b/dev/breeze/doc/03_developer_tasks.rst
index 38d9db39d83..4d0d4c6905b 100644
--- a/dev/breeze/doc/03_developer_tasks.rst
+++ b/dev/breeze/doc/03_developer_tasks.rst
@@ -392,6 +392,29 @@ These are all available flags of ``start-airflow`` command:
   :width: 100%
   :alt: Breeze start-airflow
 
+Running External System Integrations with Breeze
+------------------------------------------------
+
+You can run Airflow alongside external systems in Breeze, such as Kafka, 
Cassandra, MongoDB, and more.
+
+To start Airflow with an integration, use the following command:
+
+.. code-block:: bash
+
+    breeze --python 3.10 --backend postgres --integration <integration_name>
+
+For example, to run Airflow with Kafka:
+
+.. code-block:: bash
+
+    breeze --python 3.10 --backend postgres --integration kafka
+
+Check the available integrations by running:
+
+.. code-block:: bash
+
+    breeze --integration --help
+
 Launching multiple terminals in the same environment
 ----------------------------------------------------
 
diff --git a/dev/breeze/doc/images/output-commands.svg 
b/dev/breeze/doc/images/output-commands.svg
index eaa5000bec7..857b530a7d9 100644
--- a/dev/breeze/doc/images/output-commands.svg
+++ b/dev/breeze/doc/images/output-commands.svg
@@ -331,62 +331,62 @@
 </text><text class="breeze-help-r2" x="12.2" y="44.4" textLength="73.2" 
clip-path="url(#breeze-help-line-1)">Usage:</text><text class="breeze-help-r3" 
x="97.6" y="44.4" textLength="73.2" 
clip-path="url(#breeze-help-line-1)">breeze</text><text class="breeze-help-r1" 
x="183" y="44.4" textLength="12.2" 
clip-path="url(#breeze-help-line-1)">[</text><text class="breeze-help-r4" 
x="195.2" y="44.4" textLength="85.4" 
clip-path="url(#breeze-help-line-1)">OPTIONS</text><text class="breeze-help-r1" 
 [...]
 </text><text class="breeze-help-r1" x="1464" y="68.8" textLength="12.2" 
clip-path="url(#breeze-help-line-2)">
 </text><text class="breeze-help-r5" x="0" y="93.2" textLength="24.4" 
clip-path="url(#breeze-help-line-3)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="93.2" textLength="195.2" 
clip-path="url(#breeze-help-line-3)">&#160;Execution&#160;mode&#160;</text><text
 class="breeze-help-r5" x="219.6" y="93.2" textLength="1220" 
clip-path="url(#breeze-help-line-3)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
 class="breeze-help-r [...]
-</text><text class="breeze-help-r5" x="0" y="117.6" textLength="12.2" 
clip-path="url(#breeze-help-line-4)">│</text><text class="breeze-help-r4" 
x="24.4" y="117.6" textLength="12.2" 
clip-path="url(#breeze-help-line-4)">-</text><text class="breeze-help-r4" 
x="36.6" y="117.6" textLength="85.4" 
clip-path="url(#breeze-help-line-4)">-python</text><text class="breeze-help-r6" 
x="719.8" y="117.6" textLength="24.4" 
clip-path="url(#breeze-help-line-4)">-p</text><text class="breeze-help-r1" 
x="768. [...]
+</text><text class="breeze-help-r5" x="0" y="117.6" textLength="12.2" 
clip-path="url(#breeze-help-line-4)">│</text><text class="breeze-help-r4" 
x="24.4" y="117.6" textLength="97.6" 
clip-path="url(#breeze-help-line-4)">--python</text><text 
class="breeze-help-r6" x="719.8" y="117.6" textLength="24.4" 
clip-path="url(#breeze-help-line-4)">-p</text><text class="breeze-help-r1" 
x="768.6" y="117.6" textLength="671" 
clip-path="url(#breeze-help-line-4)">Python&#160;major/minor&#160;version&#160;u
 [...]
 </text><text class="breeze-help-r5" x="0" y="142" textLength="12.2" 
clip-path="url(#breeze-help-line-5)">│</text><text class="breeze-help-r1" 
x="768.6" y="142" textLength="671" 
clip-path="url(#breeze-help-line-5)">images.&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
 </text><text class="breeze-help-r5" x="0" y="166.4" textLength="12.2" 
clip-path="url(#breeze-help-line-6)">│</text><text class="breeze-help-r7" 
x="768.6" y="166.4" textLength="671" 
clip-path="url(#breeze-help-line-6)">(&gt;3.10&lt;&#160;|&#160;3.11&#160;|&#160;3.12&#160;|&#160;3.13)&#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-help-r5" x="1451.8" y="166 [...]
 </text><text class="breeze-help-r5" x="0" y="190.8" textLength="12.2" 
clip-path="url(#breeze-help-line-7)">│</text><text class="breeze-help-r5" 
x="768.6" y="190.8" textLength="671" 
clip-path="url(#breeze-help-line-7)">[default:&#160;3.10]&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 c [...]
-</text><text class="breeze-help-r5" x="0" y="215.2" textLength="12.2" 
clip-path="url(#breeze-help-line-8)">│</text><text class="breeze-help-r4" 
x="24.4" y="215.2" textLength="12.2" 
clip-path="url(#breeze-help-line-8)">-</text><text class="breeze-help-r4" 
x="36.6" y="215.2" textLength="146.4" 
clip-path="url(#breeze-help-line-8)">-integration</text><text 
class="breeze-help-r1" x="768.6" y="215.2" textLength="671" 
clip-path="url(#breeze-help-line-8)">Core&#160;Integrations&#160;to&#160;enab 
[...]
+</text><text class="breeze-help-r5" x="0" y="215.2" textLength="12.2" 
clip-path="url(#breeze-help-line-8)">│</text><text class="breeze-help-r4" 
x="24.4" y="215.2" textLength="158.6" 
clip-path="url(#breeze-help-line-8)">--integration</text><text 
class="breeze-help-r1" x="768.6" y="215.2" textLength="671" 
clip-path="url(#breeze-help-line-8)">Core&#160;Integrations&#160;to&#160;enable&#160;when&#160;running&#160;(can&#160;be&#160;more&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8 [...]
 </text><text class="breeze-help-r5" x="0" y="239.6" textLength="12.2" 
clip-path="url(#breeze-help-line-9)">│</text><text class="breeze-help-r1" 
x="768.6" y="239.6" textLength="671" 
clip-path="url(#breeze-help-line-9)">than&#160;one).&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
 </text><text class="breeze-help-r5" x="0" y="264" textLength="12.2" 
clip-path="url(#breeze-help-line-10)">│</text><text class="breeze-help-r7" 
x="768.6" y="264" textLength="671" 
clip-path="url(#breeze-help-line-10)">(all&#160;|&#160;all-testable&#160;|&#160;cassandra&#160;|&#160;celery&#160;|&#160;drill&#160;|&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="264" textLength="12.2" 
clip-path="url(#breeze-help-line-10)">│</text><text class="breeze-help-r1" x=" 
[...]
-</text><text class="breeze-help-r5" x="0" y="288.4" textLength="12.2" 
clip-path="url(#breeze-help-line-11)">│</text><text class="breeze-help-r7" 
x="768.6" y="288.4" textLength="671" 
clip-path="url(#breeze-help-line-11)">kafka&#160;|&#160;kerberos&#160;|&#160;keycloak&#160;|&#160;mongo&#160;|&#160;mssql&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="288.4" textLength="12.2" 
clip-path="url(#breeze-help-line-11)">│</text>< [...]
-</text><text class="breeze-help-r5" x="0" y="312.8" textLength="12.2" 
clip-path="url(#breeze-help-line-12)">│</text><text class="breeze-help-r7" 
x="768.6" y="312.8" textLength="671" 
clip-path="url(#breeze-help-line-12)">openlineage&#160;|&#160;otel&#160;|&#160;pinot&#160;|&#160;qdrant&#160;|&#160;redis&#160;|&#160;redis&#160;|&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="312.8" textLength="12.2" 
clip-path="url(#breeze-help-line-12)">│</text><text class="breeze-help-r1" x= 
[...]
-</text><text class="breeze-help-r5" x="0" y="337.2" textLength="12.2" 
clip-path="url(#breeze-help-line-13)">│</text><text class="breeze-help-r7" 
x="768.6" y="337.2" textLength="671" 
clip-path="url(#breeze-help-line-13)">statsd&#160;|&#160;tinkerpop&#160;|&#160;trino&#160;|&#160;ydb)&#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-help-r5" x="1451.8" y="337.2" textLength="12.2" cl [...]
-</text><text class="breeze-help-r5" x="0" y="361.6" textLength="12.2" 
clip-path="url(#breeze-help-line-14)">│</text><text class="breeze-help-r4" 
x="24.4" y="361.6" textLength="12.2" 
clip-path="url(#breeze-help-line-14)">-</text><text class="breeze-help-r4" 
x="36.6" y="361.6" textLength="134.2" 
clip-path="url(#breeze-help-line-14)">-standalone</text><text 
class="breeze-help-r4" x="170.8" y="361.6" textLength="170.8" 
clip-path="url(#breeze-help-line-14)">-dag-processor</text><text class="b [...]
-</text><text class="breeze-help-r5" x="0" y="386" textLength="12.2" 
clip-path="url(#breeze-help-line-15)">│</text><text class="breeze-help-r1" 
x="768.6" y="386" textLength="671" 
clip-path="url(#breeze-help-line-15)">(required&#160;for&#160;Airflow&#160;3).&#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;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="386" t [...]
+</text><text class="breeze-help-r5" x="0" y="288.4" textLength="12.2" 
clip-path="url(#breeze-help-line-11)">│</text><text class="breeze-help-r7" 
x="768.6" y="288.4" textLength="671" 
clip-path="url(#breeze-help-line-11)">kafka&#160;|&#160;kerberos&#160;|&#160;keycloak&#160;|&#160;localstack&#160;|&#160;mongo&#160;|&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="288.4" textLength="12.2" 
clip-path="url(#breeze-help-line-11)">│</text><text class="breeze-help-r [...]
+</text><text class="breeze-help-r5" x="0" y="312.8" textLength="12.2" 
clip-path="url(#breeze-help-line-12)">│</text><text class="breeze-help-r7" 
x="768.6" y="312.8" textLength="671" 
clip-path="url(#breeze-help-line-12)">mssql&#160;|&#160;openlineage&#160;|&#160;otel&#160;|&#160;pinot&#160;|&#160;qdrant&#160;|&#160;redis&#160;|&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="312.8" textLength="12.2" 
clip-path="url(#breeze-help-line-12)">│</text><text class="breeze-help-r1" x= 
[...]
+</text><text class="breeze-help-r5" x="0" y="337.2" textLength="12.2" 
clip-path="url(#breeze-help-line-13)">│</text><text class="breeze-help-r7" 
x="768.6" y="337.2" textLength="671" 
clip-path="url(#breeze-help-line-13)">redis&#160;|&#160;statsd&#160;|&#160;tinkerpop&#160;|&#160;trino&#160;|&#160;ydb)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="337.2" textLength="12.2" 
clip-path="url(#breeze-help-line [...]
+</text><text class="breeze-help-r5" x="0" y="361.6" textLength="12.2" 
clip-path="url(#breeze-help-line-14)">│</text><text class="breeze-help-r4" 
x="24.4" y="361.6" textLength="317.2" 
clip-path="url(#breeze-help-line-14)">--standalone-dag-processor</text><text 
class="breeze-help-r1" x="341.6" y="361.6" textLength="12.2" 
clip-path="url(#breeze-help-line-14)">/</text><text class="breeze-help-r4" 
x="353.8" y="361.6" textLength="341.6" 
clip-path="url(#breeze-help-line-14)">--no-standalone-dag [...]
+</text><text class="breeze-help-r5" x="0" y="386" textLength="12.2" 
clip-path="url(#breeze-help-line-15)">│</text><text class="breeze-help-r4" 
x="24.4" y="386" textLength="12.2" 
clip-path="url(#breeze-help-line-15)">r</text><text class="breeze-help-r1" 
x="768.6" y="386" textLength="671" 
clip-path="url(#breeze-help-line-15)">(required&#160;for&#160;Airflow&#160;3).&#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-help-r5" x="0" y="410.4" textLength="12.2" 
clip-path="url(#breeze-help-line-16)">│</text><text class="breeze-help-r5" 
x="768.6" y="410.4" textLength="671" 
clip-path="url(#breeze-help-line-16)">[default:&#160;standalone-dag-processor]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="410.4" textLength="12.2" 
clip-path="url(#breeze-help-line-16)" [...]
-</text><text class="breeze-help-r5" x="0" y="434.8" textLength="12.2" 
clip-path="url(#breeze-help-line-17)">│</text><text class="breeze-help-r4" 
x="24.4" y="434.8" textLength="12.2" 
clip-path="url(#breeze-help-line-17)">-</text><text class="breeze-help-r4" 
x="36.6" y="434.8" textLength="61" 
clip-path="url(#breeze-help-line-17)">-auth</text><text class="breeze-help-r4" 
x="97.6" y="434.8" textLength="97.6" 
clip-path="url(#breeze-help-line-17)">-manager</text><text 
class="breeze-help-r1" x= [...]
+</text><text class="breeze-help-r5" x="0" y="434.8" textLength="12.2" 
clip-path="url(#breeze-help-line-17)">│</text><text class="breeze-help-r4" 
x="24.4" y="434.8" textLength="170.8" 
clip-path="url(#breeze-help-line-17)">--auth-manager</text><text 
class="breeze-help-r1" x="768.6" y="434.8" textLength="463.6" 
clip-path="url(#breeze-help-line-17)">Specify&#160;the&#160;auth&#160;manager&#160;to&#160;set&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" [...]
 </text><text class="breeze-help-r5" x="0" y="459.2" textLength="12.2" 
clip-path="url(#breeze-help-line-18)">│</text><text class="breeze-help-r7" 
x="768.6" y="459.2" textLength="463.6" 
clip-path="url(#breeze-help-line-18)">(&gt;SimpleAuthManager&lt;&#160;|&#160;FabAuthManager)</text><text
 class="breeze-help-r5" x="1451.8" y="459.2" textLength="12.2" 
clip-path="url(#breeze-help-line-18)">│</text><text class="breeze-help-r1" 
x="1464" y="459.2" textLength="12.2" clip-path="url(#breeze-help-l [...]
 </text><text class="breeze-help-r5" x="0" y="483.6" textLength="12.2" 
clip-path="url(#breeze-help-line-19)">│</text><text class="breeze-help-r5" 
x="768.6" y="483.6" textLength="463.6" 
clip-path="url(#breeze-help-line-19)">[default:&#160;SimpleAuthManager]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="483.6" textLength="12.2" 
clip-path="url(#breeze-help-line-19)">│</text><text class="breeze-help-r1" 
x="1464" y="483.6" textLeng [...]
 </text><text class="breeze-help-r5" x="0" y="508" textLength="1464" 
clip-path="url(#breeze-help-line-20)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-help-r1" x="1464" y="508" textLength="12.2" 
clip-path="url(#breeze-help-line-20)">
 </text><text class="breeze-help-r5" x="0" y="532.4" textLength="24.4" 
clip-path="url(#breeze-help-line-21)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="532.4" textLength="463.6" 
clip-path="url(#breeze-help-line-21)">&#160;Docker&#160;Compose&#160;selection&#160;and&#160;cleanup&#160;</text><text
 class="breeze-help-r5" x="488" y="532.4" textLength="951.6" 
clip-path="url(#breeze-help-line-21)">──────────────────────────────────────────────────────────────────────────────</text><text
  [...]
-</text><text class="breeze-help-r5" x="0" y="556.8" textLength="12.2" 
clip-path="url(#breeze-help-line-22)">│</text><text class="breeze-help-r4" 
x="24.4" y="556.8" textLength="12.2" 
clip-path="url(#breeze-help-line-22)">-</text><text class="breeze-help-r4" 
x="36.6" y="556.8" textLength="97.6" 
clip-path="url(#breeze-help-line-22)">-project</text><text 
class="breeze-help-r4" x="134.2" y="556.8" textLength="61" 
clip-path="url(#breeze-help-line-22)">-name</text><text class="breeze-help-r1" 
x [...]
-</text><text class="breeze-help-r5" x="0" y="581.2" textLength="12.2" 
clip-path="url(#breeze-help-line-23)">│</text><text class="breeze-help-r1" 
x="244" y="581.2" textLength="512.4" 
clip-path="url(#breeze-help-line-23)">project&#160;name&#160;and&#160;you&#160;can&#160;use&#160;`breeze&#160;down&#160;</text><text
 class="breeze-help-r4" x="756.4" y="581.2" textLength="12.2" 
clip-path="url(#breeze-help-line-23)">-</text><text class="breeze-help-r4" 
x="768.6" y="581.2" textLength="97.6" cli [...]
+</text><text class="breeze-help-r5" x="0" y="556.8" textLength="12.2" 
clip-path="url(#breeze-help-line-22)">│</text><text class="breeze-help-r4" 
x="24.4" y="556.8" textLength="170.8" 
clip-path="url(#breeze-help-line-22)">--project-name</text><text 
class="breeze-help-r1" x="244" y="556.8" textLength="1195.6" 
clip-path="url(#breeze-help-line-22)">Name&#160;of&#160;the&#160;docker-compose&#160;project&#160;to&#160;bring&#160;down.&#160;The&#160;`docker-compose`&#160;is&#160;for&#160;legacy&
 [...]
+</text><text class="breeze-help-r5" x="0" y="581.2" textLength="12.2" 
clip-path="url(#breeze-help-line-23)">│</text><text class="breeze-help-r1" 
x="244" y="581.2" textLength="512.4" 
clip-path="url(#breeze-help-line-23)">project&#160;name&#160;and&#160;you&#160;can&#160;use&#160;`breeze&#160;down&#160;</text><text
 class="breeze-help-r4" x="756.4" y="581.2" textLength="170.8" 
clip-path="url(#breeze-help-line-23)">--project-name</text><text 
class="breeze-help-r1" x="927.2" y="581.2" textLen [...]
 </text><text class="breeze-help-r5" x="0" y="605.6" textLength="12.2" 
clip-path="url(#breeze-help-line-24)">│</text><text class="breeze-help-r1" 
x="244" y="605.6" textLength="1195.6" 
clip-path="url(#breeze-help-line-24)">belonging&#160;to&#160;it.&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
 </text><text class="breeze-help-r5" x="0" y="630" textLength="12.2" 
clip-path="url(#breeze-help-line-25)">│</text><text class="breeze-help-r7" 
x="244" y="630" textLength="1195.6" 
clip-path="url(#breeze-help-line-25)">(breeze&#160;|&#160;prek&#160;|&#160;docker-compose)&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
 </text><text class="breeze-help-r5" x="0" y="654.4" textLength="12.2" 
clip-path="url(#breeze-help-line-26)">│</text><text class="breeze-help-r5" 
x="244" y="654.4" textLength="1195.6" 
clip-path="url(#breeze-help-line-26)">[default:&#160;breeze]&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1
 [...]
-</text><text class="breeze-help-r5" x="0" y="678.8" textLength="12.2" 
clip-path="url(#breeze-help-line-27)">│</text><text class="breeze-help-r4" 
x="24.4" y="678.8" textLength="12.2" 
clip-path="url(#breeze-help-line-27)">-</text><text class="breeze-help-r4" 
x="36.6" y="678.8" textLength="85.4" 
clip-path="url(#breeze-help-line-27)">-docker</text><text 
class="breeze-help-r4" x="122" y="678.8" textLength="61" 
clip-path="url(#breeze-help-line-27)">-host</text><text class="breeze-help-r1" 
x="2 [...]
+</text><text class="breeze-help-r5" x="0" y="678.8" textLength="12.2" 
clip-path="url(#breeze-help-line-27)">│</text><text class="breeze-help-r4" 
x="24.4" y="678.8" textLength="158.6" 
clip-path="url(#breeze-help-line-27)">--docker-host</text><text 
class="breeze-help-r1" x="244" y="678.8" textLength="915" 
clip-path="url(#breeze-help-line-27)">Optional&#160;-&#160;docker&#160;host&#160;to&#160;use&#160;when&#160;running&#160;docker&#160;commands.&#160;When&#160;set,&#160;the&#160;`</text><t
 [...]
 </text><text class="breeze-help-r5" x="0" y="703.2" textLength="12.2" 
clip-path="url(#breeze-help-line-28)">│</text><text class="breeze-help-r1" 
x="244" y="703.2" textLength="1195.6" 
clip-path="url(#breeze-help-line-28)">ignored&#160;when&#160;building&#160;images.&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
 </text><text class="breeze-help-r5" x="0" y="727.6" textLength="12.2" 
clip-path="url(#breeze-help-line-29)">│</text><text class="breeze-help-r7" 
x="244" y="727.6" textLength="1195.6" 
clip-path="url(#breeze-help-line-29)">(TEXT)&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
 </text><text class="breeze-help-r5" x="0" y="752" textLength="1464" 
clip-path="url(#breeze-help-line-30)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-help-r1" x="1464" y="752" textLength="12.2" 
clip-path="url(#breeze-help-line-30)">
 </text><text class="breeze-help-r5" x="0" y="776.4" textLength="24.4" 
clip-path="url(#breeze-help-line-31)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="776.4" textLength="122" 
clip-path="url(#breeze-help-line-31)">&#160;Database&#160;</text><text 
class="breeze-help-r5" x="146.4" y="776.4" textLength="1293.2" 
clip-path="url(#breeze-help-line-31)">──────────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
 class="breeze-help- [...]
-</text><text class="breeze-help-r5" x="0" y="800.8" textLength="12.2" 
clip-path="url(#breeze-help-line-32)">│</text><text class="breeze-help-r4" 
x="24.4" y="800.8" textLength="12.2" 
clip-path="url(#breeze-help-line-32)">-</text><text class="breeze-help-r4" 
x="36.6" y="800.8" textLength="97.6" 
clip-path="url(#breeze-help-line-32)">-backend</text><text 
class="breeze-help-r6" x="268.4" y="800.8" textLength="24.4" 
clip-path="url(#breeze-help-line-32)">-b</text><text class="breeze-help-r1" x= 
[...]
+</text><text class="breeze-help-r5" x="0" y="800.8" textLength="12.2" 
clip-path="url(#breeze-help-line-32)">│</text><text class="breeze-help-r4" 
x="24.4" y="800.8" textLength="109.8" 
clip-path="url(#breeze-help-line-32)">--backend</text><text 
class="breeze-help-r6" x="268.4" y="800.8" textLength="24.4" 
clip-path="url(#breeze-help-line-32)">-b</text><text class="breeze-help-r1" 
x="488" y="800.8" textLength="951.6" 
clip-path="url(#breeze-help-line-32)">Database&#160;backend&#160;to&#160;us 
[...]
 </text><text class="breeze-help-r5" x="0" y="825.2" textLength="12.2" 
clip-path="url(#breeze-help-line-33)">│</text><text class="breeze-help-r1" 
x="488" y="825.2" textLength="951.6" 
clip-path="url(#breeze-help-line-33)">start&#160;with&#160;an&#160;invalid&#160;database&#160;configuration&#160;—&#160;no&#160;database&#160;will&#160;be&#160;available,&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="825.2" textLength="12.2" 
clip-path="url(#breeze-help-line-33)">│</text><text class=" [...]
 </text><text class="breeze-help-r5" x="0" y="849.6" textLength="12.2" 
clip-path="url(#breeze-help-line-34)">│</text><text class="breeze-help-r1" 
x="488" y="849.6" textLength="951.6" 
clip-path="url(#breeze-help-line-34)">and&#160;any&#160;attempt&#160;to&#160;run&#160;Airflow&#160;will&#160;fail.&#160;Use&#160;&#x27;none&#x27;&#160;only&#160;for&#160;specific&#160;non-DB&#160;</text><text
 class="breeze-help-r5" x="1451.8" y="849.6" textLength="12.2" 
clip-path="url(#breeze-help-line-34)">│ [...]
 </text><text class="breeze-help-r5" x="0" y="874" textLength="12.2" 
clip-path="url(#breeze-help-line-35)">│</text><text class="breeze-help-r1" 
x="488" y="874" textLength="951.6" 
clip-path="url(#breeze-help-line-35)">test&#160;cases.&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
 </text><text class="breeze-help-r5" x="0" y="898.4" textLength="12.2" 
clip-path="url(#breeze-help-line-36)">│</text><text class="breeze-help-r7" 
x="488" y="898.4" textLength="951.6" 
clip-path="url(#breeze-help-line-36)">(&gt;sqlite&lt;&#160;|&#160;mysql&#160;|&#160;postgres&#160;|&#160;none)&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
 </text><text class="breeze-help-r5" x="0" y="922.8" textLength="12.2" 
clip-path="url(#breeze-help-line-37)">│</text><text class="breeze-help-r5" 
x="488" y="922.8" textLength="951.6" 
clip-path="url(#breeze-help-line-37)">[default:&#160;sqlite]&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16
 [...]
-</text><text class="breeze-help-r5" x="0" y="947.2" textLength="12.2" 
clip-path="url(#breeze-help-line-38)">│</text><text class="breeze-help-r4" 
x="24.4" y="947.2" textLength="12.2" 
clip-path="url(#breeze-help-line-38)">-</text><text class="breeze-help-r4" 
x="36.6" y="947.2" textLength="109.8" 
clip-path="url(#breeze-help-line-38)">-postgres</text><text 
class="breeze-help-r4" x="146.4" y="947.2" textLength="97.6" 
clip-path="url(#breeze-help-line-38)">-version</text><text class="breeze-hel 
[...]
-</text><text class="breeze-help-r5" x="0" y="971.6" textLength="12.2" 
clip-path="url(#breeze-help-line-39)">│</text><text class="breeze-help-r4" 
x="24.4" y="971.6" textLength="12.2" 
clip-path="url(#breeze-help-line-39)">-</text><text class="breeze-help-r4" 
x="36.6" y="971.6" textLength="73.2" 
clip-path="url(#breeze-help-line-39)">-mysql</text><text class="breeze-help-r4" 
x="109.8" y="971.6" textLength="97.6" 
clip-path="url(#breeze-help-line-39)">-version</text><text 
class="breeze-help-r6 [...]
-</text><text class="breeze-help-r5" x="0" y="996" textLength="12.2" 
clip-path="url(#breeze-help-line-40)">│</text><text class="breeze-help-r4" 
x="24.4" y="996" textLength="12.2" 
clip-path="url(#breeze-help-line-40)">-</text><text class="breeze-help-r4" 
x="36.6" y="996" textLength="36.6" 
clip-path="url(#breeze-help-line-40)">-db</text><text class="breeze-help-r4" 
x="73.2" y="996" textLength="73.2" 
clip-path="url(#breeze-help-line-40)">-reset</text><text class="breeze-help-r6" 
x="268.4" y= [...]
+</text><text class="breeze-help-r5" x="0" y="947.2" textLength="12.2" 
clip-path="url(#breeze-help-line-38)">│</text><text class="breeze-help-r4" 
x="24.4" y="947.2" textLength="219.6" 
clip-path="url(#breeze-help-line-38)">--postgres-version</text><text 
class="breeze-help-r6" x="268.4" y="947.2" textLength="24.4" 
clip-path="url(#breeze-help-line-38)">-P</text><text class="breeze-help-r1" 
x="488" y="947.2" textLength="305" 
clip-path="url(#breeze-help-line-38)">Version&#160;of&#160;Postgres& [...]
+</text><text class="breeze-help-r5" x="0" y="971.6" textLength="12.2" 
clip-path="url(#breeze-help-line-39)">│</text><text class="breeze-help-r4" 
x="24.4" y="971.6" textLength="183" 
clip-path="url(#breeze-help-line-39)">--mysql-version</text><text 
class="breeze-help-r6" x="268.4" y="971.6" textLength="24.4" 
clip-path="url(#breeze-help-line-39)">-M</text><text class="breeze-help-r1" 
x="488" y="971.6" textLength="268.4" 
clip-path="url(#breeze-help-line-39)">Version&#160;of&#160;MySQL&#160;u [...]
+</text><text class="breeze-help-r5" x="0" y="996" textLength="12.2" 
clip-path="url(#breeze-help-line-40)">│</text><text class="breeze-help-r4" 
x="24.4" y="996" textLength="122" 
clip-path="url(#breeze-help-line-40)">--db-reset</text><text 
class="breeze-help-r6" x="268.4" y="996" textLength="24.4" 
clip-path="url(#breeze-help-line-40)">-d</text><text class="breeze-help-r1" 
x="292.8" y="996" textLength="12.2" 
clip-path="url(#breeze-help-line-40)">/</text><text class="breeze-help-r4" 
x="305"  [...]
 </text><text class="breeze-help-r5" x="0" y="1020.4" textLength="1464" 
clip-path="url(#breeze-help-line-41)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-help-r1" x="1464" y="1020.4" textLength="12.2" 
clip-path="url(#breeze-help-line-41)">
 </text><text class="breeze-help-r5" x="0" y="1044.8" textLength="24.4" 
clip-path="url(#breeze-help-line-42)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="1044.8" textLength="488" 
clip-path="url(#breeze-help-line-42)">&#160;Build&#160;CI&#160;image&#160;(before&#160;entering&#160;shell)&#160;</text><text
 class="breeze-help-r5" x="512.4" y="1044.8" textLength="927.2" 
clip-path="url(#breeze-help-line-42)">────────────────────────────────────────────────────────────────────────────</tex
 [...]
-</text><text class="breeze-help-r5" x="0" y="1069.2" textLength="12.2" 
clip-path="url(#breeze-help-line-43)">│</text><text class="breeze-help-r4" 
x="24.4" y="1069.2" textLength="12.2" 
clip-path="url(#breeze-help-line-43)">-</text><text class="breeze-help-r4" 
x="36.6" y="1069.2" textLength="85.4" 
clip-path="url(#breeze-help-line-43)">-github</text><text 
class="breeze-help-r4" x="122" y="1069.2" textLength="134.2" 
clip-path="url(#breeze-help-line-43)">-repository</text><text class="breeze- 
[...]
-</text><text class="breeze-help-r5" x="0" y="1093.6" textLength="12.2" 
clip-path="url(#breeze-help-line-44)">│</text><text class="breeze-help-r4" 
x="24.4" y="1093.6" textLength="12.2" 
clip-path="url(#breeze-help-line-44)">-</text><text class="breeze-help-r4" 
x="36.6" y="1093.6" textLength="97.6" 
clip-path="url(#breeze-help-line-44)">-builder</text><text 
class="breeze-help-r1" x="341.6" y="1093.6" textLength="756.4" 
clip-path="url(#breeze-help-line-44)">Buildx&#160;builder&#160;used&#160; [...]
+</text><text class="breeze-help-r5" x="0" y="1069.2" textLength="12.2" 
clip-path="url(#breeze-help-line-43)">│</text><text class="breeze-help-r4" 
x="24.4" y="1069.2" textLength="231.8" 
clip-path="url(#breeze-help-line-43)">--github-repository</text><text 
class="breeze-help-r6" x="292.8" y="1069.2" textLength="24.4" 
clip-path="url(#breeze-help-line-43)">-g</text><text class="breeze-help-r1" 
x="341.6" y="1069.2" textLength="585.6" 
clip-path="url(#breeze-help-line-43)">GitHub&#160;repositor [...]
+</text><text class="breeze-help-r5" x="0" y="1093.6" textLength="12.2" 
clip-path="url(#breeze-help-line-44)">│</text><text class="breeze-help-r4" 
x="24.4" y="1093.6" textLength="109.8" 
clip-path="url(#breeze-help-line-44)">--builder</text><text 
class="breeze-help-r1" x="341.6" y="1093.6" textLength="756.4" 
clip-path="url(#breeze-help-line-44)">Buildx&#160;builder&#160;used&#160;to&#160;perform&#160;`docker&#160;buildx&#160;build`&#160;commands.</text><text
 class="breeze-help-r7" x="1110. [...]
 </text><text class="breeze-help-r5" x="0" y="1118" textLength="12.2" 
clip-path="url(#breeze-help-line-45)">│</text><text class="breeze-help-r5" 
x="341.6" y="1118" textLength="756.4" 
clip-path="url(#breeze-help-line-45)">[default:&#160;autodetect]&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
 [...]
-</text><text class="breeze-help-r5" x="0" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-help-line-46)">│</text><text class="breeze-help-r4" 
x="24.4" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-help-line-46)">-</text><text class="breeze-help-r4" 
x="36.6" y="1142.4" textLength="48.8" 
clip-path="url(#breeze-help-line-46)">-use</text><text class="breeze-help-r4" 
x="85.4" y="1142.4" textLength="36.6" 
clip-path="url(#breeze-help-line-46)">-uv</text><text class="breeze-help-r1" x= 
[...]
-</text><text class="breeze-help-r5" x="0" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-help-line-47)">│</text><text class="breeze-help-r4" 
x="24.4" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-help-line-47)">-</text><text class="breeze-help-r4" 
x="36.6" y="1166.8" textLength="36.6" 
clip-path="url(#breeze-help-line-47)">-uv</text><text class="breeze-help-r4" 
x="73.2" y="1166.8" textLength="158.6" 
clip-path="url(#breeze-help-line-47)">-http-timeout</text><text class="breeze-h 
[...]
+</text><text class="breeze-help-r5" x="0" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-help-line-46)">│</text><text class="breeze-help-r4" 
x="24.4" y="1142.4" textLength="97.6" 
clip-path="url(#breeze-help-line-46)">--use-uv</text><text 
class="breeze-help-r1" x="122" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-help-line-46)">/</text><text class="breeze-help-r4" 
x="134.2" y="1142.4" textLength="134.2" 
clip-path="url(#breeze-help-line-46)">--no-use-uv</text><text class="breez [...]
+</text><text class="breeze-help-r5" x="0" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-help-line-47)">│</text><text class="breeze-help-r4" 
x="24.4" y="1166.8" textLength="207.4" 
clip-path="url(#breeze-help-line-47)">--uv-http-timeout</text><text 
class="breeze-help-r1" x="341.6" y="1166.8" textLength="829.6" 
clip-path="url(#breeze-help-line-47)">Timeout&#160;for&#160;requests&#160;that&#160;UV&#160;makes&#160;(only&#160;used&#160;in&#160;case&#160;of&#160;UV&#160;builds).</text><te
 [...]
 </text><text class="breeze-help-r5" x="0" y="1191.2" textLength="12.2" 
clip-path="url(#breeze-help-line-48)">│</text><text class="breeze-help-r5" 
x="341.6" y="1191.2" textLength="829.6" 
clip-path="url(#breeze-help-line-48)">[default:&#160;300;&#160;x&gt;=1]&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
 </text><text class="breeze-help-r5" x="0" y="1215.6" textLength="1464" 
clip-path="url(#breeze-help-line-49)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-help-r1" x="1464" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-help-line-49)">
 </text><text class="breeze-help-r5" x="0" y="1240" textLength="24.4" 
clip-path="url(#breeze-help-line-50)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="1240" textLength="183" 
clip-path="url(#breeze-help-line-50)">&#160;Other&#160;options&#160;</text><text
 class="breeze-help-r5" x="207.4" y="1240" textLength="1232.2" 
clip-path="url(#breeze-help-line-50)">─────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
 class="breeze-hel [...]
-</text><text class="breeze-help-r5" x="0" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-help-line-51)">│</text><text class="breeze-help-r4" 
x="24.4" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-help-line-51)">-</text><text class="breeze-help-r4" 
x="36.6" y="1264.4" textLength="97.6" 
clip-path="url(#breeze-help-line-51)">-forward</text><text 
class="breeze-help-r4" x="134.2" y="1264.4" textLength="146.4" 
clip-path="url(#breeze-help-line-51)">-credentials</text><text class="bre [...]
-</text><text class="breeze-help-r5" x="0" y="1288.8" textLength="12.2" 
clip-path="url(#breeze-help-line-52)">│</text><text class="breeze-help-r4" 
x="24.4" y="1288.8" textLength="12.2" 
clip-path="url(#breeze-help-line-52)">-</text><text class="breeze-help-r4" 
x="36.6" y="1288.8" textLength="48.8" 
clip-path="url(#breeze-help-line-52)">-max</text><text class="breeze-help-r4" 
x="85.4" y="1288.8" textLength="61" 
clip-path="url(#breeze-help-line-52)">-time</text><text class="breeze-help-r1" 
x= [...]
+</text><text class="breeze-help-r5" x="0" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-help-line-51)">│</text><text class="breeze-help-r4" 
x="24.4" y="1264.4" textLength="256.2" 
clip-path="url(#breeze-help-line-51)">--forward-credentials</text><text 
class="breeze-help-r6" x="305" y="1264.4" textLength="24.4" 
clip-path="url(#breeze-help-line-51)">-f</text><text class="breeze-help-r1" 
x="353.8" y="1264.4" textLength="634.4" 
clip-path="url(#breeze-help-line-51)">Forward&#160;local&#1 [...]
+</text><text class="breeze-help-r5" x="0" y="1288.8" textLength="12.2" 
clip-path="url(#breeze-help-line-52)">│</text><text class="breeze-help-r4" 
x="24.4" y="1288.8" textLength="122" 
clip-path="url(#breeze-help-line-52)">--max-time</text><text 
class="breeze-help-r1" x="353.8" y="1288.8" textLength="1049.2" 
clip-path="url(#breeze-help-line-52)">Maximum&#160;time&#160;that&#160;the&#160;command&#160;should&#160;take&#160;-&#160;if&#160;it&#160;takes&#160;longer,&#160;the&#160;command&#160;
 [...]
 </text><text class="breeze-help-r5" x="0" y="1313.2" textLength="12.2" 
clip-path="url(#breeze-help-line-53)">│</text><text class="breeze-help-r7" 
x="353.8" y="1313.2" textLength="1049.2" 
clip-path="url(#breeze-help-line-53)">(INTEGER&#160;RANGE)&#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;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
 </text><text class="breeze-help-r5" x="0" y="1337.6" textLength="1464" 
clip-path="url(#breeze-help-line-54)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-help-r1" x="1464" y="1337.6" textLength="12.2" 
clip-path="url(#breeze-help-line-54)">
 </text><text class="breeze-help-r5" x="0" y="1362" textLength="24.4" 
clip-path="url(#breeze-help-line-55)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="1362" textLength="195.2" 
clip-path="url(#breeze-help-line-55)">&#160;Common&#160;options&#160;</text><text
 class="breeze-help-r5" x="219.6" y="1362" textLength="1220" 
clip-path="url(#breeze-help-line-55)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
 class="breeze-hel [...]
-</text><text class="breeze-help-r5" x="0" y="1386.4" textLength="12.2" 
clip-path="url(#breeze-help-line-56)">│</text><text class="breeze-help-r4" 
x="24.4" y="1386.4" textLength="12.2" 
clip-path="url(#breeze-help-line-56)">-</text><text class="breeze-help-r4" 
x="36.6" y="1386.4" textLength="85.4" 
clip-path="url(#breeze-help-line-56)">-answer</text><text 
class="breeze-help-r6" x="158.6" y="1386.4" textLength="24.4" 
clip-path="url(#breeze-help-line-56)">-a</text><text class="breeze-help-r1" 
[...]
-</text><text class="breeze-help-r5" x="0" y="1410.8" textLength="12.2" 
clip-path="url(#breeze-help-line-57)">│</text><text class="breeze-help-r4" 
x="24.4" y="1410.8" textLength="12.2" 
clip-path="url(#breeze-help-line-57)">-</text><text class="breeze-help-r4" 
x="36.6" y="1410.8" textLength="48.8" 
clip-path="url(#breeze-help-line-57)">-dry</text><text class="breeze-help-r4" 
x="85.4" y="1410.8" textLength="48.8" 
clip-path="url(#breeze-help-line-57)">-run</text><text class="breeze-help-r6" x 
[...]
-</text><text class="breeze-help-r5" x="0" y="1435.2" textLength="12.2" 
clip-path="url(#breeze-help-line-58)">│</text><text class="breeze-help-r4" 
x="24.4" y="1435.2" textLength="12.2" 
clip-path="url(#breeze-help-line-58)">-</text><text class="breeze-help-r4" 
x="36.6" y="1435.2" textLength="97.6" 
clip-path="url(#breeze-help-line-58)">-verbose</text><text 
class="breeze-help-r6" x="158.6" y="1435.2" textLength="24.4" 
clip-path="url(#breeze-help-line-58)">-v</text><text class="breeze-help-r1 [...]
-</text><text class="breeze-help-r5" x="0" y="1459.6" textLength="12.2" 
clip-path="url(#breeze-help-line-59)">│</text><text class="breeze-help-r4" 
x="24.4" y="1459.6" textLength="12.2" 
clip-path="url(#breeze-help-line-59)">-</text><text class="breeze-help-r4" 
x="36.6" y="1459.6" textLength="61" 
clip-path="url(#breeze-help-line-59)">-help</text><text class="breeze-help-r6" 
x="158.6" y="1459.6" textLength="24.4" 
clip-path="url(#breeze-help-line-59)">-h</text><text class="breeze-help-r1" x=" 
[...]
+</text><text class="breeze-help-r5" x="0" y="1386.4" textLength="12.2" 
clip-path="url(#breeze-help-line-56)">│</text><text class="breeze-help-r4" 
x="24.4" y="1386.4" textLength="97.6" 
clip-path="url(#breeze-help-line-56)">--answer</text><text 
class="breeze-help-r6" x="158.6" y="1386.4" textLength="24.4" 
clip-path="url(#breeze-help-line-56)">-a</text><text class="breeze-help-r1" 
x="207.4" y="1386.4" textLength="317.2" 
clip-path="url(#breeze-help-line-56)">Force&#160;answer&#160;to&#160;qu [...]
+</text><text class="breeze-help-r5" x="0" y="1410.8" textLength="12.2" 
clip-path="url(#breeze-help-line-57)">│</text><text class="breeze-help-r4" 
x="24.4" y="1410.8" textLength="109.8" 
clip-path="url(#breeze-help-line-57)">--dry-run</text><text 
class="breeze-help-r6" x="158.6" y="1410.8" textLength="24.4" 
clip-path="url(#breeze-help-line-57)">-D</text><text class="breeze-help-r1" 
x="207.4" y="1410.8" textLength="719.8" 
clip-path="url(#breeze-help-line-57)">If&#160;dry-run&#160;is&#160;se [...]
+</text><text class="breeze-help-r5" x="0" y="1435.2" textLength="12.2" 
clip-path="url(#breeze-help-line-58)">│</text><text class="breeze-help-r4" 
x="24.4" y="1435.2" textLength="109.8" 
clip-path="url(#breeze-help-line-58)">--verbose</text><text 
class="breeze-help-r6" x="158.6" y="1435.2" textLength="24.4" 
clip-path="url(#breeze-help-line-58)">-v</text><text class="breeze-help-r1" 
x="207.4" y="1435.2" textLength="585.6" 
clip-path="url(#breeze-help-line-58)">Print&#160;verbose&#160;informa [...]
+</text><text class="breeze-help-r5" x="0" y="1459.6" textLength="12.2" 
clip-path="url(#breeze-help-line-59)">│</text><text class="breeze-help-r4" 
x="24.4" y="1459.6" textLength="73.2" 
clip-path="url(#breeze-help-line-59)">--help</text><text class="breeze-help-r6" 
x="158.6" y="1459.6" textLength="24.4" 
clip-path="url(#breeze-help-line-59)">-h</text><text class="breeze-help-r1" 
x="207.4" y="1459.6" textLength="329.4" 
clip-path="url(#breeze-help-line-59)">Show&#160;this&#160;message&#160;an [...]
 </text><text class="breeze-help-r5" x="0" y="1484" textLength="1464" 
clip-path="url(#breeze-help-line-60)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-help-r1" x="1464" y="1484" textLength="12.2" 
clip-path="url(#breeze-help-line-60)">
 </text><text class="breeze-help-r5" x="0" y="1508.4" textLength="24.4" 
clip-path="url(#breeze-help-line-61)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="1508.4" textLength="244" 
clip-path="url(#breeze-help-line-61)">&#160;Developer&#160;commands&#160;</text><text
 class="breeze-help-r5" x="268.4" y="1508.4" textLength="1171.2" 
clip-path="url(#breeze-help-line-61)">────────────────────────────────────────────────────────────────────────────────────────────────</text><text
 class="bree [...]
 </text><text class="breeze-help-r5" x="0" y="1532.8" textLength="12.2" 
clip-path="url(#breeze-help-line-62)">│</text><text class="breeze-help-r4" 
x="24.4" y="1532.8" textLength="280.6" 
clip-path="url(#breeze-help-line-62)">start-airflow&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-help-r1" x="329.4" y="1532.8" textLength="1110.2" 
clip-path="url(#breeze-help-line-62)">Enter&#160;breeze&#160;environment&#160;and&#160;starts&#160;all&#160;Airflow&#16
 [...]
diff --git a/dev/breeze/doc/images/output_shell.txt 
b/dev/breeze/doc/images/output_shell.txt
index a52f06728d2..691681a156c 100644
--- a/dev/breeze/doc/images/output_shell.txt
+++ b/dev/breeze/doc/images/output_shell.txt
@@ -1 +1 @@
-5bdfe1d4afe64fb8bd3e07d5c6e9c2d5
+345a25e9b7fd41a8e1d14d2c275e387d
diff --git a/dev/breeze/doc/images/output_start-airflow.txt 
b/dev/breeze/doc/images/output_start-airflow.txt
index fe487fdf093..49b8a247041 100644
--- a/dev/breeze/doc/images/output_start-airflow.txt
+++ b/dev/breeze/doc/images/output_start-airflow.txt
@@ -1 +1 @@
-da22448455ba68de7ee5d2b1bd206265
+c5ecfff87a01e315b8f558798a5dc35c
diff --git 
a/dev/breeze/doc/images/output_testing_providers-integration-tests.svg 
b/dev/breeze/doc/images/output_testing_providers-integration-tests.svg
index 6bee01df22d..d023b849a3f 100644
--- a/dev/breeze/doc/images/output_testing_providers-integration-tests.svg
+++ b/dev/breeze/doc/images/output_testing_providers-integration-tests.svg
@@ -237,8 +237,8 @@
 </text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="752" textLength="1464" 
clip-path="url(#breeze-testing-providers-integration-tests-line-30)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-testing-providers-integration-tests-r1" x="1464" y="752" 
textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-30)">
 </text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="776.4" textLength="24.4" 
clip-path="url(#breeze-testing-providers-integration-tests-line-31)">╭─</text><text
 class="breeze-testing-providers-integration-tests-r5" x="24.4" y="776.4" 
textLength="231.8" 
clip-path="url(#breeze-testing-providers-integration-tests-line-31)">&#160;Integration&#160;tests&#160;</text><text
 class="breeze-testing-providers-integration-tests-r5" x="256.2" y="776.4" 
textLength="1183.4" clip- [...]
 </text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="800.8" textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-32)">│</text><text
 class="breeze-testing-providers-integration-tests-r4" x="24.4" y="800.8" 
textLength="158.6" 
clip-path="url(#breeze-testing-providers-integration-tests-line-32)">--integration</text><text
 class="breeze-testing-providers-integration-tests-r1" x="231.8" y="800.8" 
textLength="1207.8" clip-path="url(#breeze-test [...]
-</text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="825.2" textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-33)">│</text><text
 class="breeze-testing-providers-integration-tests-r6" x="231.8" y="825.2" 
textLength="1207.8" 
clip-path="url(#breeze-testing-providers-integration-tests-line-33)">(all&#160;|&#160;all-testable&#160;|&#160;cassandra&#160;|&#160;celery&#160;|&#160;drill&#160;|&#160;kafka&#160;|&#160;mongo&#160;|&#160;mssql&#1
 [...]
-</text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="849.6" textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-34)">│</text><text
 class="breeze-testing-providers-integration-tests-r6" x="231.8" y="849.6" 
textLength="1207.8" 
clip-path="url(#breeze-testing-providers-integration-tests-line-34)">qdrant&#160;|&#160;redis&#160;|&#160;tinkerpop&#160;|&#160;trino&#160;|&#160;ydb)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16
 [...]
+</text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="825.2" textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-33)">│</text><text
 class="breeze-testing-providers-integration-tests-r6" x="231.8" y="825.2" 
textLength="1207.8" 
clip-path="url(#breeze-testing-providers-integration-tests-line-33)">(all&#160;|&#160;all-testable&#160;|&#160;cassandra&#160;|&#160;celery&#160;|&#160;drill&#160;|&#160;kafka&#160;|&#160;localstack&#160;|&#160;mon
 [...]
+</text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="849.6" textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-34)">│</text><text
 class="breeze-testing-providers-integration-tests-r6" x="231.8" y="849.6" 
textLength="1207.8" 
clip-path="url(#breeze-testing-providers-integration-tests-line-34)">|&#160;pinot&#160;|&#160;qdrant&#160;|&#160;redis&#160;|&#160;tinkerpop&#160;|&#160;trino&#160;|&#160;ydb)&#160;&#160;&#160;&#160;&#160;&#160;&#1
 [...]
 </text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="874" textLength="1464" 
clip-path="url(#breeze-testing-providers-integration-tests-line-35)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-testing-providers-integration-tests-r1" x="1464" y="874" 
textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-35)">
 </text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="898.4" textLength="24.4" 
clip-path="url(#breeze-testing-providers-integration-tests-line-36)">╭─</text><text
 class="breeze-testing-providers-integration-tests-r5" x="24.4" y="898.4" 
textLength="402.6" 
clip-path="url(#breeze-testing-providers-integration-tests-line-36)">&#160;Advanced&#160;flag&#160;for&#160;tests&#160;command&#160;</text><text
 class="breeze-testing-providers-integration-tests-r5" x="427" y="898.4 [...]
 </text><text class="breeze-testing-providers-integration-tests-r5" x="0" 
y="922.8" textLength="12.2" 
clip-path="url(#breeze-testing-providers-integration-tests-line-37)">│</text><text
 class="breeze-testing-providers-integration-tests-r4" x="24.4" y="922.8" 
textLength="231.8" 
clip-path="url(#breeze-testing-providers-integration-tests-line-37)">--github-repository</text><text
 class="breeze-testing-providers-integration-tests-r7" x="366" y="922.8" 
textLength="24.4" clip-path="url(#breeze-te [...]
diff --git 
a/dev/breeze/doc/images/output_testing_providers-integration-tests.txt 
b/dev/breeze/doc/images/output_testing_providers-integration-tests.txt
index 7a3452bc580..f8e31d84496 100644
--- a/dev/breeze/doc/images/output_testing_providers-integration-tests.txt
+++ b/dev/breeze/doc/images/output_testing_providers-integration-tests.txt
@@ -1 +1 @@
-66a5d51390e696c06b63d6ad296c7784
+c01e190daa309e88d3021a63f3099b52
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py 
b/dev/breeze/src/airflow_breeze/global_constants.py
index 8d688366aa5..3af544999c9 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -72,6 +72,7 @@ TESTABLE_PROVIDERS_INTEGRATIONS = [
     "drill",
     "tinkerpop",
     "kafka",
+    "localstack",
     "mongo",
     "mssql",
     "pinot",
@@ -82,6 +83,7 @@ TESTABLE_PROVIDERS_INTEGRATIONS = [
 ]
 DISABLE_TESTABLE_INTEGRATIONS_FROM_CI = [
     "mssql",
+    "localstack",  # just for local integration testing for now
 ]
 KEYCLOAK_INTEGRATION = "keycloak"
 STATSD_INTEGRATION = "statsd"
diff --git a/dev/breeze/src/airflow_breeze/params/shell_params.py 
b/dev/breeze/src/airflow_breeze/params/shell_params.py
index 6c43d29d766..082b3838f75 100644
--- a/dev/breeze/src/airflow_breeze/params/shell_params.py
+++ b/dev/breeze/src/airflow_breeze/params/shell_params.py
@@ -429,6 +429,7 @@ class ShellParams:
         else:
             integrations = self.integration
         for integration in integrations:
+            get_console().print(f"[info]Adding integration compose file for 
{integration}[/]")
             compose_file_list.append(DOCKER_COMPOSE_DIR / 
f"integration-{integration}.yml")
         if "trino" in integrations and "kerberos" not in integrations:
             get_console().print(
diff --git a/scripts/ci/docker-compose/integration-localstack.yml 
b/scripts/ci/docker-compose/integration-localstack.yml
new file mode 100644
index 00000000000..68560bb0476
--- /dev/null
+++ b/scripts/ci/docker-compose/integration-localstack.yml
@@ -0,0 +1,37 @@
+# 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.
+---
+services:
+  localstack:
+    container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
+    image: localstack/localstack:4.7
+    labels:
+      breeze.description: "Integration that emulates AWS services locally."
+    ports:
+      - "4566:4566"            # LocalStack Gateway
+      - "4510-4559:4510-4559"  # external services port range
+    environment:
+      # LocalStack configuration: 
https://docs.localstack.cloud/references/configuration/
+      - DEBUG=${DEBUG:-0}
+    volumes:
+      - "/var/run/docker.sock:/var/run/docker.sock"
+
+  airflow:
+    environment:
+      - INTEGRATION_LOCALSTACK=true
+    depends_on:
+      - localstack
diff --git a/scripts/docker/entrypoint_ci.sh b/scripts/docker/entrypoint_ci.sh
index af93ccaa026..bf64cb795e9 100755
--- a/scripts/docker/entrypoint_ci.sh
+++ b/scripts/docker/entrypoint_ci.sh
@@ -184,6 +184,27 @@ function environment_initialization() {
         ssh-keyscan -H localhost >> ~/.ssh/known_hosts 2>/dev/null
     fi
 
+    if [[ ${INTEGRATION_LOCALSTACK:-"false"} == "true" ]]; then
+        echo
+        echo "${COLOR_BLUE}Configuring LocalStack integration${COLOR_RESET}"
+        echo
+
+        # Define LocalStack AWS configuration
+        declare -A localstack_config=(
+            ["AWS_ENDPOINT_URL"]="http://localstack:4566";
+            ["AWS_ACCESS_KEY_ID"]="test"
+            ["AWS_SECRET_ACCESS_KEY"]="test"
+            ["AWS_DEFAULT_REGION"]="us-east-1"
+        )
+
+        # Export each configuration variable and log it
+        for key in "${!localstack_config[@]}"; do
+            export "$key"="${localstack_config[$key]}"
+            echo "  * ${COLOR_BLUE}${key}:${COLOR_RESET} 
${localstack_config[$key]}"
+        done
+        echo
+    fi
+
     cd "${AIRFLOW_SOURCES}"
 
     # Temporarily add /opt/airflow/providers/standard/tests to PYTHONPATH in 
order to see example dags

Reply via email to