diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index 14f0628e454bb..4276573b95fe2 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -153,108 +153,6 @@ jobs: env: FORCE_COLOR: 2 - test-openapi-client: - timeout-minutes: 10 - name: "Test OpenAPI client" - runs-on: ${{ fromJSON(inputs.runs-on-as-json-public) }} - if: inputs.needs-api-codegen == 'true' - steps: - - name: "Cleanup repo" - shell: bash - run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@v4 - with: - fetch-depth: 2 - persist-credentials: false - - name: "Cleanup docker" - run: ./scripts/ci/cleanup_docker.sh - - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@v4 - with: - repository: "apache/airflow-client-python" - fetch-depth: 1 - persist-credentials: false - path: ./airflow-client-python - - name: "Install Breeze" - uses: ./.github/actions/breeze - - name: "Generate client with breeze" - run: > - breeze release-management prepare-python-client --package-format both - --version-suffix-for-pypi dev0 --python-client-repo ./airflow-client-python - - name: "Show diff" - run: git diff --color HEAD - working-directory: ./airflow-client-python - - name: Install hatch - run: | - python -m pip install --upgrade uv - uv tool install hatch - - name: Run tests - run: hatch run run-coverage - env: - HATCH_ENV: "test" - working-directory: ./clients/python - - name: "Install source version of required packages" - run: | - breeze release-management prepare-provider-packages \ - fab \ - standard \ - common.sql \ - sqlite \ - --package-format wheel \ - --skip-tag-check \ - --version-suffix-for-pypi dev0 - pip install . \ - dist/apache_airflow_providers_fab-*.whl \ - dist/apache_airflow_providers_standard-*.whl \ - dist/apache_airflow_providers_common_sql-*.whl \ - dist/apache_airflow_providers_sqlite-*.whl - breeze release-management prepare-task-sdk-package --package-format wheel - pip install ./dist/apache_airflow_task_sdk-*.whl - - name: "Install Python client" - run: pip install ./dist/apache_airflow_client-*.whl - - name: "Initialize Airflow DB and start webserver" - run: | - airflow db init - # Let scheduler runs a few loops and get all DAG files from example DAGs serialized to DB - airflow scheduler --num-runs 100 - airflow users create --username admin --password admin --firstname Admin --lastname Admin \ - --role Admin --email admin@example.org - killall python || true # just in case there is a webserver running in the background - nohup airflow webserver --port 8080 & - echo "Started webserver" - env: - AIRFLOW__API__AUTH_BACKENDS: >- - airflow.api.auth.backend.session,airflow.providers.fab.auth_manager.api.auth.backend.basic_auth - AIRFLOW__WEBSERVER__EXPOSE_CONFIG: "True" - AIRFLOW__CORE__LOAD_EXAMPLES: "True" - AIRFLOW_HOME: "${{ github.workspace }}/airflow_home" - - name: "Waiting for the webserver to be available" - run: | - timeout 30 bash -c 'until nc -z $0 $1; do echo "sleeping"; sleep 1; done' localhost 8080 - sleep 5 - - name: "Run test python client" - run: python ./clients/python/test_python_client.py - env: - FORCE_COLOR: "standard" - - name: "Stop running webserver" - run: killall python || true # just in case there is a webserver running in the background - if: always() - - name: "Upload python client packages" - uses: actions/upload-artifact@v4 - with: - name: python-client-packages - path: ./dist/apache_airflow_client-* - retention-days: 7 - if-no-files-found: error - - name: "Upload logs from failed tests" - uses: actions/upload-artifact@v4 - if: failure() - with: - name: python-client-failed-logs - path: "${{ github.workspace }}/airflow_home/logs" - retention-days: 7 - # Those checks are run if no image needs to be built for checks. This is for simple changes that # Do not touch any of the python code or any of the important files that might require building # The CI Docker image and they can be run entirely using the pre-commit virtual environments on host diff --git a/.github/workflows/static-checks-mypy-docs.yml b/.github/workflows/ci-image-checks.yml similarity index 83% rename from .github/workflows/static-checks-mypy-docs.yml rename to .github/workflows/ci-image-checks.yml index be2c4f8e28645..63598755c32d0 100644 --- a/.github/workflows/static-checks-mypy-docs.yml +++ b/.github/workflows/ci-image-checks.yml @@ -16,7 +16,7 @@ # under the License. # --- -name: Static checks, mypy, docs +name: CI Image Checks on: # yamllint disable-line rule:truthy workflow_call: inputs: @@ -96,6 +96,19 @@ on: # yamllint disable-line rule:truthy description: "Whether to build docs (true/false)" required: true type: string + needs-api-codegen: + description: "Whether to run API codegen (true/false)" + required: true + type: string + default-postgres-version: + description: "The default version of the postgres to use" + required: true + type: string + run-coverage: + description: "Whether to run coverage or not (true/false)" + required: true + type: string + jobs: static-checks: timeout-minutes: 45 @@ -304,3 +317,50 @@ jobs: - name: "Upload documentation to AWS S3" if: inputs.branch == 'main' run: aws s3 sync --delete ./docs/_build s3://apache-airflow-docs + + test-python-api-client: + timeout-minutes: 60 + name: "Test Python API client" + runs-on: ${{ fromJSON(inputs.runs-on-as-json-default) }} + if: inputs.needs-api-codegen == 'true' + env: + BACKEND: "postgres" + BACKEND_VERSION: "${{ inputs.default-postgres-version }}" + DEBUG_RESOURCES: "${{ inputs.debug-resources }}" + ENABLE_COVERAGE: "${{ inputs.run-coverage }}" + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_USERNAME: ${{ github.actor }} + IMAGE_TAG: "${{ inputs.image-tag }}" + JOB_ID: "python-api-client-tests" + PYTHON_MAJOR_MINOR_VERSION: "${{ inputs.default-python-version }}" + VERBOSE: "true" + steps: + - name: "Cleanup repo" + shell: bash + run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 + with: + fetch-depth: 2 + persist-credentials: false + - name: "Cleanup docker" + run: ./scripts/ci/cleanup_docker.sh + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 + with: + repository: "apache/airflow-client-python" + fetch-depth: 1 + persist-credentials: false + path: ./airflow-client-python + - name: "Prepare breeze & CI image: ${{inputs.default-python-version}}:${{inputs.image-tag}}" + uses: ./.github/actions/prepare_breeze_and_image + - name: "Generate airflow python client" + run: > + breeze release-management prepare-python-client --package-format both + --version-suffix-for-pypi dev0 --python-client-repo ./airflow-client-python + - name: "Show diff" + run: git diff --color HEAD + working-directory: ./airflow-client-python + - name: "Python API client tests" + run: breeze testing python-api-client-tests diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 115d78a49913a..e0e1ffd8bf20b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -297,10 +297,10 @@ jobs: chicken-egg-providers: ${{ needs.build-info.outputs.chicken-egg-providers }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} - static-checks-mypy-docs: - name: "Static checks, mypy, docs" + ci-image-checks: + name: "CI image checks" needs: [build-info, wait-for-ci-images] - uses: ./.github/workflows/static-checks-mypy-docs.yml + uses: ./.github/workflows/ci-image-checks.yml secrets: inherit with: runs-on-as-json-default: ${{ needs.build-info.outputs.runs-on-as-json-default }} @@ -322,6 +322,9 @@ jobs: include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} docs-build: ${{ needs.build-info.outputs.docs-build }} + needs-api-codegen: ${{ needs.build-info.outputs.needs-api-codegen }} + default-postgres-version: ${{ needs.build-info.outputs.default-postgres-version }} + run-coverage: ${{ needs.build-info.outputs.run-coverage }} providers: name: "Provider packages tests" @@ -702,7 +705,7 @@ jobs: - generate-constraints - wait-for-ci-images - wait-for-prod-images - - static-checks-mypy-docs + - ci-image-checks - tests-sqlite - tests-mysql - tests-postgres diff --git a/.github/workflows/special-tests.yml b/.github/workflows/special-tests.yml index 9ff5afeeaf121..1cf1df579a49a 100644 --- a/.github/workflows/special-tests.yml +++ b/.github/workflows/special-tests.yml @@ -76,6 +76,7 @@ on: # yamllint disable-line rule:truthy description: "Whether to debug resources or not (true/false)" required: true type: string + jobs: tests-min-sqlalchemy: name: "Min SQLAlchemy test" diff --git a/Dockerfile.ci b/Dockerfile.ci index b3686b782ad93..25ad9618f4d5b 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -822,6 +822,8 @@ mkdir "${AIRFLOW_HOME}/sqlite" -p || true ASSET_COMPILATION_WAIT_MULTIPLIER=${ASSET_COMPILATION_WAIT_MULTIPLIER:=1} +. "${IN_CONTAINER_DIR}/check_connectivity.sh" + function wait_for_asset_compilation() { if [[ -f "${AIRFLOW_SOURCES}/.build/www/.asset_compile.lock" ]]; then echo @@ -1155,12 +1157,61 @@ function check_force_lowest_dependencies() { set +x } +function check_airflow_python_client_installation() { + if [[ ${INSTALL_AIRFLOW_PYTHON_CLIENT=} != "true" ]]; then + return + fi + python "${IN_CONTAINER_DIR}/install_airflow_python_client.py" +} + +function start_webserver_with_examples(){ + if [[ ${START_WEBSERVER_WITH_EXAMPLES=} != "true" ]]; then + return + fi + export AIRFLOW__CORE__LOAD_EXAMPLES=True + export AIRFLOW__API__AUTH_BACKENDS=airflow.api.auth.backend.session,airflow.providers.fab.auth_manager.api.auth.backend.basic_auth + export AIRFLOW__WEBSERVER__EXPOSE_CONFIG=True + echo + echo "${COLOR_BLUE}Initializing database${COLOR_RESET}" + echo + airflow db migrate + echo + echo "${COLOR_BLUE}Database initialized${COLOR_RESET}" + echo + echo "${COLOR_BLUE}Parsing example dags${COLOR_RESET}" + echo + airflow scheduler --num-runs 100 + echo "Example dags parsing finished" + echo "Create admin user" + airflow users create -u admin -p admin -f Thor -l Administrator -r Admin -e admin@email.domain + echo "Admin user created" + echo + echo "${COLOR_BLUE}Starting airflow webserver${COLOR_RESET}" + echo + airflow webserver --port 8080 --daemon + echo + echo "${COLOR_BLUE}Waiting for webserver to start${COLOR_RESET}" + echo + check_service_connection "Airflow webserver" "run_nc localhost 8080" 100 + EXIT_CODE=$? + if [[ ${EXIT_CODE} != 0 ]]; then + echo + echo "${COLOR_RED}Webserver did not start properly${COLOR_RESET}" + echo + exit ${EXIT_CODE} + fi + echo + echo "${COLOR_BLUE}Airflow webserver started${COLOR_RESET}" +} + determine_airflow_to_use environment_initialization check_boto_upgrade check_downgrade_sqlalchemy check_downgrade_pendulum check_force_lowest_dependencies +check_airflow_python_client_installation +start_webserver_with_examples check_run_tests "${@}" exec /bin/bash "${@}" diff --git a/clients/python/test_python_client.py b/clients/python/test_python_client.py index 5d0accdc019ff..87ceb656b7db8 100644 --- a/clients/python/test_python_client.py +++ b/clients/python/test_python_client.py @@ -27,9 +27,11 @@ from __future__ import annotations import sys +import time import uuid import airflow_client.client +import pytest try: # If you have rich installed, you will have nice colored output of the API responses @@ -63,68 +65,81 @@ # or AIRFLOW__CORE__LOAD_EXAMPLES environment variable set to True DAG_ID = "example_bash_operator" + # Enter a context with an instance of the API client -with airflow_client.client.ApiClient(configuration) as api_client: - errors = False - - print("[blue]Getting DAG list") - dag_api_instance = dag_api.DAGApi(api_client) - try: - api_response = dag_api_instance.get_dags() - print(api_response) - except airflow_client.client.OpenApiException as e: - print(f"[red]Exception when calling DagAPI->get_dags: {e}\n") - errors = True - else: - print("[green]Getting DAG list successful") - - print("[blue]Getting Tasks for a DAG") - try: - api_response = dag_api_instance.get_tasks(DAG_ID) - print(api_response) - except airflow_client.client.exceptions.OpenApiException as e: - print(f"[red]Exception when calling DagAPI->get_tasks: {e}\n") - errors = True - else: - print("[green]Getting Tasks successful") - - print("[blue]Triggering a DAG run") - dag_run_api_instance = dag_run_api.DAGRunApi(api_client) - try: - # Create a DAGRun object (no dag_id should be specified because it is read-only property of DAGRun) - # dag_run id is generated randomly to allow multiple executions of the script - dag_run = DAGRun( - dag_run_id="some_test_run_" + uuid.uuid4().hex, - ) - api_response = dag_run_api_instance.post_dag_run(DAG_ID, dag_run) - print(api_response) - except airflow_client.client.exceptions.OpenApiException as e: - print(f"[red]Exception when calling DAGRunAPI->post_dag_run: {e}\n") - errors = True - else: - print("[green]Posting DAG Run successful") - - # Get current configuration. Note, this is disabled by default with most installation. - # You need to set `expose_config = True` in Airflow configuration in order to retrieve configuration. - conf_api_instance = config_api.ConfigApi(api_client) - try: - api_response = conf_api_instance.get_config() - print(api_response) - except airflow_client.client.OpenApiException as e: - if "FORBIDDEN" in str(e): - print( - "[yellow]You need to set `expose_config = True` in Airflow configuration" - " in order to retrieve configuration." - ) - print("[bright_blue]This is OK. Exposing config is disabled by default.") +@pytest.mark.execution_timeout(400) +def test_python_client(): + with airflow_client.client.ApiClient(configuration) as api_client: + errors = False + + print("[blue]Getting DAG list") + max_retries = 10 + while max_retries > 0: + try: + dag_api_instance = dag_api.DAGApi(api_client) + api_response = dag_api_instance.get_dags() + print(api_response) + except airflow_client.client.OpenApiException as e: + print(f"[red]Exception when calling DagAPI->get_dags: {e}\n") + errors = True + time.sleep(6) + max_retries -= 1 + else: + errors = False + print("[green]Getting DAG list successful") + break + + print("[blue]Getting Tasks for a DAG") + try: + api_response = dag_api_instance.get_tasks(DAG_ID) + print(api_response) + except airflow_client.client.exceptions.OpenApiException as e: + print(f"[red]Exception when calling DagAPI->get_tasks: {e}\n") + errors = True else: + print("[green]Getting Tasks successful") + + print("[blue]Triggering a DAG run") + dag_run_api_instance = dag_run_api.DAGRunApi(api_client) + try: + # Create a DAGRun object (no dag_id should be specified because it is read-only property of DAGRun) + # dag_run id is generated randomly to allow multiple executions of the script + dag_run = DAGRun( + dag_run_id="some_test_run_" + uuid.uuid4().hex, + ) + api_response = dag_run_api_instance.post_dag_run(DAG_ID, dag_run) + print(api_response) + except airflow_client.client.exceptions.OpenApiException as e: print(f"[red]Exception when calling DAGRunAPI->post_dag_run: {e}\n") errors = True - else: - print("[green]Config retrieved successfully") - - if errors: - print("\n[red]There were errors while running the script - see above for details") - sys.exit(1) - else: - print("\n[green]Everything went well") + else: + print("[green]Posting DAG Run successful") + + # Get current configuration. Note, this is disabled by default with most installation. + # You need to set `expose_config = True` in Airflow configuration in order to retrieve configuration. + conf_api_instance = config_api.ConfigApi(api_client) + try: + api_response = conf_api_instance.get_config() + print(api_response) + except airflow_client.client.OpenApiException as e: + if "FORBIDDEN" in str(e): + print( + "[yellow]You need to set `expose_config = True` in Airflow configuration" + " in order to retrieve configuration." + ) + print("[bright_blue]This is OK. Exposing config is disabled by default.") + else: + print(f"[red]Exception when calling DAGRunAPI->post_dag_run: {e}\n") + errors = True + else: + print("[green]Config retrieved successfully") + + if errors: + print("\n[red]There were errors while running the script - see above for details") + sys.exit(1) + else: + print("\n[green]Everything went well") + + +if __name__ == "__main__": + test_python_client() diff --git a/contributing-docs/09_testing.rst b/contributing-docs/09_testing.rst index 895fd1b964f09..18a43e9d6b21c 100644 --- a/contributing-docs/09_testing.rst +++ b/contributing-docs/09_testing.rst @@ -49,6 +49,9 @@ You can also run other kinds of tests when you are developing airflow packages: * `Testing packages `__ is a document that describes how to manually build and test pre-release candidate packages of airflow and providers. +* `Python client tests `__ are tests we run to check if the Python API + client works correctly. + * `DAG testing `__ is a document that describes how to test DAGs in a local environment with ``DebugExecutor``. Note, that this is a legacy method - you can now use dag.test() method to test DAGs. diff --git a/contributing-docs/testing/python_client_tests.rst b/contributing-docs/testing/python_client_tests.rst new file mode 100644 index 0000000000000..5bc492734bff3 --- /dev/null +++ b/contributing-docs/testing/python_client_tests.rst @@ -0,0 +1,47 @@ + .. 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. + +Airflow Python API Client Tests +=============================== + +This document describes how to run tests for the Airflow Python API client. + +Running Python API Client Tests with Breeze +------------------------------------------- + +The Python API client tests are run in the Breeze environment. The tests are run in the same way as the other tests in Breeze. + +The way the tests work: + +1. The Airflow Python API client package is first built into a wheel file and placed in the dist folder. +2. The ``breeze testing python-api-client-tests`` command is used to initiate the tests. +3. This command installs the package from the dist folder. +4. Example DAGs are then parsed and executed to validate the Python API client. +5. The webserver is started with the credentials admin/admin, and tests are run against the webserver. + +If you have python client repository not cloned, you can clone it by running the following command: + +.. code-block:: bash + + git clone https://github.com/apache/airflow-client-python.git + +To build the package, you can run the following command: + +.. code-block:: bash + + breeze release-management prepare-python-client --package-format both + --version-suffix-for-pypi dev0 --python-client-repo ./airflow-client-python diff --git a/dev/breeze/doc/05_test_commands.rst b/dev/breeze/doc/05_test_commands.rst index f5b3a78eef78f..819ac80224525 100644 --- a/dev/breeze/doc/05_test_commands.rst +++ b/dev/breeze/doc/05_test_commands.rst @@ -218,6 +218,29 @@ Here is the detailed set of options for the ``breeze testing providers-integrati :alt: Breeze testing providers-integration-tests +Running Python API client tests +............................... + +To run Python API client tests, you need to have airflow python client packaged in dist folder. +To package the client, clone the airflow-python-client repository and run the following command: + +.. code-block:: bash + + breeze release-management prepare-python-client --package-format both + --version-suffix-for-pypi dev0 --python-client-repo ./airflow-client-python + +.. code-block:: bash + + breeze testing python-api-client-tests + +Here is the detailed set of options for the ``breeze testing python-api-client-tests`` command. + +.. image:: ./images/output_testing_python-api-client-tests.svg + :target: https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/images/output_testing_python-api-client-tests.svg + :width: 100% + :alt: Breeze testing python-api-client-tests + + Running system tests .................... diff --git a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg index 2281855ed930d..6a312f5b20d2c 100644 --- a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg +++ b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg @@ -202,8 +202,8 @@ setup:check-all-params-in-groups | setup:config | setup:regenerate-command-images | setup:self-upgrade  | setup:synchronize-local-mounts | setup:version | shell | start-airflow | static-checks | testing |    testing:core-integration-tests | testing:core-tests | testing:docker-compose-tests | testing:helm-tests -| testing:providers-integration-tests | testing:providers-tests | testing:system-tests |                -testing:task-sdk-tests)                                                                                 +| testing:providers-integration-tests | testing:providers-tests | testing:python-api-client-tests |     +testing:system-tests | testing:task-sdk-tests)                                                          ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ --verbose-vPrint verbose information about performed steps. diff --git a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt index 8af1fd4596083..6bc1fa3014426 100644 --- a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt +++ b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt @@ -1 +1 @@ -5b1f2b4c7ccd4fb99efaa8f48c721c34 +4f2ddff749749897c4bdd3b36b5b3c32 diff --git a/dev/breeze/doc/images/output_setup_regenerate-command-images.svg b/dev/breeze/doc/images/output_setup_regenerate-command-images.svg index 7a3bcdedd717e..2956a66972df4 100644 --- a/dev/breeze/doc/images/output_setup_regenerate-command-images.svg +++ b/dev/breeze/doc/images/output_setup_regenerate-command-images.svg @@ -1,4 +1,4 @@ - + setup:self-upgrade | setup:synchronize-local-mounts | setup:version | shell | start-airflow |        static-checks | testing | testing:core-integration-tests | testing:core-tests |                      testing:docker-compose-tests | testing:helm-tests | testing:providers-integration-tests |            -testing:providers-tests | testing:system-tests | testing:task-sdk-tests)                             ---check-onlyOnly check if some images need to be regenerated. Return 0 if no need or 1 if needed. Cannot be used -together with --command flag or --force.                                                             -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ ---verbose-vPrint verbose information about performed steps. ---dry-run-DIf dry-run is set, commands are only printed, not executed. ---help-hShow this message and exit. -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +testing:providers-tests | testing:python-api-client-tests | testing:system-tests |                   +testing:task-sdk-tests)                                                                              +--check-onlyOnly check if some images need to be regenerated. Return 0 if no need or 1 if needed. Cannot be used +together with --command flag or --force.                                                             +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ +--verbose-vPrint verbose information about performed steps. +--dry-run-DIf dry-run is set, commands are only printed, not executed. +--help-hShow this message and exit. +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/dev/breeze/doc/images/output_setup_regenerate-command-images.txt b/dev/breeze/doc/images/output_setup_regenerate-command-images.txt index 8cc4669293051..d26de039adee2 100644 --- a/dev/breeze/doc/images/output_setup_regenerate-command-images.txt +++ b/dev/breeze/doc/images/output_setup_regenerate-command-images.txt @@ -1 +1 @@ -cef764d3eaa21feef72d2f259627ade6 +9001008210b2148e49e4fd11f11bb25a diff --git a/dev/breeze/doc/images/output_shell.svg b/dev/breeze/doc/images/output_shell.svg index 86892b0ea2ec3..aefd48c1531eb 100644 --- a/dev/breeze/doc/images/output_shell.svg +++ b/dev/breeze/doc/images/output_shell.svg @@ -1,4 +1,4 @@ - +