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

uranusjr 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 c9d7f367ac4 Final wire up for Java SDK (#67826)
c9d7f367ac4 is described below

commit c9d7f367ac4c7043454502b16d41340b3ec2c66d
Author: Tzu-ping Chung <[email protected]>
AuthorDate: Thu Jun 4 19:53:13 2026 +0800

    Final wire up for Java SDK (#67826)
---
 .dockerignore                                      |   1 +
 .github/workflows/ci-amd.yml                       |  42 +++-
 .github/workflows/ci-arm.yml                       |  42 +++-
 .github/workflows/codeql-analysis.yml              |   6 +-
 .github/workflows/publish-docs-to-s3.yml           |  60 ++++-
 Dockerfile.ci                                      |   4 +
 dev/breeze/doc/images/output_build-docs.svg        |  94 ++++----
 dev/breeze/doc/images/output_build-docs.txt        |   2 +-
 dev/breeze/doc/images/output_shell.svg             |  16 +-
 dev/breeze/doc/images/output_shell.txt             |   2 +-
 dev/breeze/doc/images/output_start-airflow.svg     |  16 +-
 dev/breeze/doc/images/output_start-airflow.txt     |   2 +-
 .../src/airflow_breeze/commands/common_options.py  |   9 +
 .../airflow_breeze/commands/developer_commands.py  | 260 +++++++++++++++------
 .../commands/developer_commands_config.py          |   7 +-
 .../commands/release_management_commands.py        |  12 +-
 dev/breeze/src/airflow_breeze/global_constants.py  |   3 +
 .../src/airflow_breeze/params/shell_params.py      |   3 +
 .../src/airflow_breeze/utils/publish_docs_to_s3.py |   9 +-
 java-sdk/build.gradle.kts                          |   6 +-
 java-sdk/gradle.properties                         |   2 +
 java-sdk/sdk/build.gradle.kts                      |  17 +-
 scripts/docker/entrypoint_ci.sh                    |   4 +
 scripts/docker/install_jdk.sh                      |  70 ++++++
 24 files changed, 548 insertions(+), 141 deletions(-)

diff --git a/.dockerignore b/.dockerignore
index df08c066ce3..401e8fff9fb 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -39,6 +39,7 @@
 !task-sdk/
 !airflow-ctl/
 !go-sdk/
+!java-sdk/
 
 # Add all "test" distributions
 !tests
diff --git a/.github/workflows/ci-amd.yml b/.github/workflows/ci-amd.yml
index 7c4f5630072..21eb17e8126 100644
--- a/.github/workflows/ci-amd.yml
+++ b/.github/workflows/ci-amd.yml
@@ -54,6 +54,12 @@ env:
   GITHUB_REPOSITORY: ${{ github.repository }}
   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
   GITHUB_USERNAME: ${{ github.actor }}
+  # Keep these in sync:
+  # - jvmTarget, languageVersion, and sourceCompatibility in 
java-sdk/build.gradle.kts
+  # - TEMURIN_VERSION in scripts/docker/install_jdk.sh
+  # - JAVA_VERSION in .github/workflows/ci-amd.yml and 
.github/workflows/ci-arm.yml
+  # - java-version in .github/workflows/codeql-analysis.yml
+  JAVA_VERSION: '11'
   SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
   VERBOSE: "true"
 
@@ -974,18 +980,49 @@ jobs:
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # 
v6.0.2
         with:
           persist-credentials: false
-      # keep this in sync with the jvmTarget in java-sdk/build.gradle.kts
       - name: Setup Java
         uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # 
v5.2.0
         with:
           distribution: 'temurin'
-          java-version: '11'
+          java-version: ${{ env.JAVA_VERSION }}
       - name: "Cleanup dist files"
         run: rm -fv ./dist/*
       - name: Run Java SDK tests
         working-directory: ./java-sdk
         run: ./gradlew test
 
+  build-java-sdk-docs:
+    name: "Java SDK docs"
+    needs: [build-info]
+    runs-on: ${{ fromJSON(needs.build-info.outputs.runner-type) }}
+    timeout-minutes: 30
+    permissions:
+      contents: read
+      packages: read
+    if: needs.build-info.outputs.run-java-sdk-tests == 'true'
+    env:
+      GITHUB_REPOSITORY: ${{ github.repository }}
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      GITHUB_USERNAME: ${{ github.actor }}
+      VERBOSE: "true"
+    steps:
+      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # 
v6.0.2
+        with:
+          persist-credentials: false
+      - name: "Install Breeze"
+        uses: ./.github/actions/breeze
+      - name: "Build Java SDK Javadoc"
+        run: breeze build-docs --sdk-docs-only --sdk=java
+      - name: "Upload Javadoc artifact"
+        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a 
 # v7.0.1
+        with:
+          name: java-sdk-docs
+          path: generated/_build/docs/java-sdk/
+          retention-days: 7
+          if-no-files-found: error
+          overwrite: 'true'
+
   tests-airflow-ctl:
     name: "Airflow CTL tests"
     uses: ./.github/workflows/airflow-distributions-tests.yml
@@ -1040,6 +1077,7 @@ jobs:
       - tests-airflow-ctl
       - tests-go-sdk
       - tests-java-sdk
+      - build-java-sdk-docs
       - tests-with-lowest-direct-resolution-core
       - tests-with-lowest-direct-resolution-providers
     uses: ./.github/workflows/finalize-tests.yml
diff --git a/.github/workflows/ci-arm.yml b/.github/workflows/ci-arm.yml
index b750c4a949c..9250c092b8e 100644
--- a/.github/workflows/ci-arm.yml
+++ b/.github/workflows/ci-arm.yml
@@ -44,6 +44,12 @@ env:
   GITHUB_REPOSITORY: ${{ github.repository }}
   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
   GITHUB_USERNAME: ${{ github.actor }}
+  # Keep these in sync:
+  # - jvmTarget, languageVersion, and sourceCompatibility in 
java-sdk/build.gradle.kts
+  # - TEMURIN_VERSION in scripts/docker/install_jdk.sh
+  # - JAVA_VERSION in .github/workflows/ci-amd.yml and 
.github/workflows/ci-arm.yml
+  # - java-version in .github/workflows/codeql-analysis.yml
+  JAVA_VERSION: '11'
   SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
   VERBOSE: "true"
 
@@ -964,18 +970,49 @@ jobs:
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # 
v6.0.2
         with:
           persist-credentials: false
-      # keep this in sync with the jvmTarget in java-sdk/build.gradle.kts
       - name: Setup Java
         uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # 
v5.2.0
         with:
           distribution: 'temurin'
-          java-version: '11'
+          java-version: ${{ env.JAVA_VERSION }}
       - name: "Cleanup dist files"
         run: rm -fv ./dist/*
       - name: Run Java SDK tests
         working-directory: ./java-sdk
         run: ./gradlew test
 
+  build-java-sdk-docs:
+    name: "Java SDK docs"
+    needs: [build-info]
+    runs-on: ${{ fromJSON(needs.build-info.outputs.runner-type) }}
+    timeout-minutes: 30
+    permissions:
+      contents: read
+      packages: read
+    if: needs.build-info.outputs.run-java-sdk-tests == 'true'
+    env:
+      GITHUB_REPOSITORY: ${{ github.repository }}
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      GITHUB_USERNAME: ${{ github.actor }}
+      VERBOSE: "true"
+    steps:
+      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # 
v6.0.2
+        with:
+          persist-credentials: false
+      - name: "Install Breeze"
+        uses: ./.github/actions/breeze
+      - name: "Build Java SDK Javadoc"
+        run: breeze build-docs --sdk-docs-only --sdk=java
+      - name: "Upload Javadoc artifact"
+        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a 
 # v7.0.1
+        with:
+          name: java-sdk-docs
+          path: generated/_build/docs/java-sdk/
+          retention-days: 7
+          if-no-files-found: error
+          overwrite: 'true'
+
   tests-airflow-ctl:
     name: "Airflow CTL tests"
     uses: ./.github/workflows/airflow-distributions-tests.yml
@@ -1030,6 +1067,7 @@ jobs:
       - tests-airflow-ctl
       - tests-go-sdk
       - tests-java-sdk
+      - build-java-sdk-docs
       - tests-with-lowest-direct-resolution-core
       - tests-with-lowest-direct-resolution-providers
     uses: ./.github/workflows/finalize-tests.yml
diff --git a/.github/workflows/codeql-analysis.yml 
b/.github/workflows/codeql-analysis.yml
index ce46330319a..8ef9ddbe360 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -96,7 +96,11 @@ jobs:
         with:
           persist-credentials: false
 
-      # keep this in sync with the jvmTarget in java-sdk/build.gradle.kts
+      # Keep these in sync:
+      # - jvmTarget, languageVersion, and sourceCompatibility in 
java-sdk/build.gradle.kts
+      # - TEMURIN_VERSION in scripts/docker/install_jdk.sh
+      # - JAVA_VERSION in .github/workflows/ci-amd.yml and 
.github/workflows/ci-arm.yml
+      # - java-version in .github/workflows/codeql-analysis.yml
       - name: Setup Java
         if: matrix.language == 'java'
         uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # 
v5.2.0
diff --git a/.github/workflows/publish-docs-to-s3.yml 
b/.github/workflows/publish-docs-to-s3.yml
index 8c5d152931a..1192283a081 100644
--- a/.github/workflows/publish-docs-to-s3.yml
+++ b/.github/workflows/publish-docs-to-s3.yml
@@ -345,8 +345,56 @@ jobs:
           if-no-files-found: 'error'
           overwrite: 'true'
 
+  build-java-sdk-docs:
+    needs: [build-info]
+    timeout-minutes: 30
+    name: "Build Java SDK Javadoc"
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      packages: read
+    env:
+      GITHUB_REPOSITORY: ${{ github.repository }}
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      GITHUB_USERNAME: ${{ github.actor }}
+      VERBOSE: "true"
+    outputs:
+      built: ${{ steps.sdk-present.outputs.exists }}
+    steps:
+      - name: "Checkout ${{ inputs.ref }}"
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # 
v6.0.2
+        with:
+          persist-credentials: false
+          ref: ${{ inputs.ref }}
+      - name: "Check whether the Java SDK exists at this ref"
+        id: sdk-present
+        env:
+          REF: ${{ inputs.ref }}
+        run: |
+          if [[ -f "java-sdk/gradlew" ]]; then
+            echo "exists=true" >> "${GITHUB_OUTPUT}"
+          else
+            echo "exists=false" >> "${GITHUB_OUTPUT}"
+            echo "java-sdk/ not found at ref ${REF} — skipping Javadoc build."
+          fi
+      - name: "Install Breeze"
+        if: steps.sdk-present.outputs.exists == 'true'
+        uses: ./.github/actions/breeze
+      - name: "Build Java SDK Javadoc"
+        if: steps.sdk-present.outputs.exists == 'true'
+        run: breeze build-docs --sdk-docs-only --sdk=java
+      - name: "Upload Java SDK docs"
+        if: steps.sdk-present.outputs.exists == 'true'
+        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a 
 # v7.0.1
+        with:
+          name: java-sdk-docs
+          path: generated/_build/docs/java-sdk/
+          retention-days: '7'
+          if-no-files-found: 'error'
+          overwrite: 'true'
+
   publish-docs-to-s3:
-    needs: [build-docs, build-info]
+    needs: [build-docs, build-java-sdk-docs, build-info]
     name: "Publish documentation to S3"
     permissions:
       id-token: write
@@ -385,6 +433,12 @@ jobs:
           path: /mnt/_build
       - name: "Move docs to generated folder"
         run: mv /mnt/_build generated/_build
+      - name: "Download Java SDK docs artifact"
+        if: needs.build-java-sdk-docs.outputs.built == 'true'
+        uses: 
actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c  # v8.0.1
+        with:
+          name: java-sdk-docs
+          path: generated/_build/docs/java-sdk
       - name: "Make sure SBOM dir exists and has the right permissions"
         run: |
           sudo mkdir -vp ./files/sbom
@@ -416,8 +470,10 @@ jobs:
       - name: "Publish docs to /mnt/airflow-site directory using ${{ 
inputs.ref }} reference breeze"
         env:
           INCLUDE_DOCS: ${{ needs.build-info.outputs.include-docs }}
+          JAVA_SDK_DOCS: ${{ needs.build-java-sdk-docs.outputs.built == 'true' 
&& 'java-sdk' || '' }}
         run: >
-          breeze release-management publish-docs --override-versioned 
--run-in-parallel ${INCLUDE_DOCS}
+          breeze release-management publish-docs --override-versioned 
--run-in-parallel
+          ${INCLUDE_DOCS} ${JAVA_SDK_DOCS}
       - name: Check disk space available
         run: df -H
       - name: "Update watermarks"
diff --git a/Dockerfile.ci b/Dockerfile.ci
index 2379df51297..144b118ad69 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -1222,6 +1222,10 @@ function environment_initialization() {
         export AIRFLOW__SCHEDULER__GO_WORKER=True
     fi
 
+    if [[ ${INSTALL_SDK_JAVA=} == "true" ]]; then
+        "${AIRFLOW_SOURCES}/scripts/docker/install_jdk.sh"
+    fi
+
     RUN_TESTS=${RUN_TESTS:="false"}
     CI=${CI:="false"}
 
diff --git a/dev/breeze/doc/images/output_build-docs.svg 
b/dev/breeze/doc/images/output_build-docs.svg
index f35a9a4f072..8600627f062 100644
--- a/dev/breeze/doc/images/output_build-docs.svg
+++ b/dev/breeze/doc/images/output_build-docs.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 1489.6" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 1538.3999999999999" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-build-docs-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="1438.6" />
+      <rect x="0" y="0" width="1463.0" height="1487.3999999999999" />
     </clipPath>
     <clipPath id="breeze-build-docs-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -219,9 +219,15 @@
 <clipPath id="breeze-build-docs-line-57">
     <rect x="0" y="1392.3" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-build-docs-line-58">
+    <rect x="0" y="1416.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-build-docs-line-59">
+    <rect x="0" y="1441.1" 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="1487.6" rx="8"/><text 
class="breeze-build-docs-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;build-docs</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="1536.4" rx="8"/><text 
class="breeze-build-docs-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;build-docs</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -249,47 +255,49 @@
 </text><text class="breeze-build-docs-r1" x="1464" y="386" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-15)">
 </text><text class="breeze-build-docs-r1" x="12.2" y="410.4" 
textLength="195.2" 
clip-path="url(#breeze-build-docs-line-16)">Build&#160;documents.</text><text 
class="breeze-build-docs-r1" x="1464" y="410.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-16)">
 </text><text class="breeze-build-docs-r1" x="1464" y="434.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-17)">
-</text><text class="breeze-build-docs-r5" x="0" y="459.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-18)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="459.2" textLength="671" 
clip-path="url(#breeze-build-docs-line-18)">&#160;Build&#160;scope&#160;(default&#160;is&#160;to&#160;build&#160;docs&#160;and&#160;spellcheck)&#160;</text><text
 class="breeze-build-docs-r5" x="695.4" y="459.2" textLength="744.2" 
clip-path="url(#breeze-build-docs-line-18)">────────────────── [...]
+</text><text class="breeze-build-docs-r5" x="0" y="459.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-18)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="459.2" textLength="756.4" 
clip-path="url(#breeze-build-docs-line-18)">&#160;Build&#160;scope&#160;(default&#160;is&#160;to&#160;build&#160;Python&#160;docs&#160;and&#160;spellcheck)&#160;</text><text
 class="breeze-build-docs-r5" x="780.8" y="459.2" textLength="658.8" 
clip-path="url(#breeze-build-docs-line-18)">──── [...]
 </text><text class="breeze-build-docs-r5" x="0" y="483.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-19)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="483.6" textLength="207.4" 
clip-path="url(#breeze-build-docs-line-19)">--docs-only&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r6" x="256.2" y="483.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-19)">-d</text><text 
class="breeze-build-docs-r1" x="305" y="483.6" textLength="30 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="508" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-20)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="508" textLength="207.4" 
clip-path="url(#breeze-build-docs-line-20)">--spellcheck-only</text><text 
class="breeze-build-docs-r6" x="256.2" y="508" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-20)">-s</text><text 
class="breeze-build-docs-r1" x="305" y="508" textLength="292.8" 
clip-path="url(#breeze-build-docs [...]
-</text><text class="breeze-build-docs-r5" x="0" y="532.4" textLength="1464" 
clip-path="url(#breeze-build-docs-line-21)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="532.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-21)">
-</text><text class="breeze-build-docs-r5" x="0" y="556.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-22)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="556.8" textLength="183" 
clip-path="url(#breeze-build-docs-line-22)">&#160;Type&#160;of&#160;build&#160;</text><text
 class="breeze-build-docs-r5" x="207.4" y="556.8" textLength="1232.2" 
clip-path="url(#breeze-build-docs-line-22)">───────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="581.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-23)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="581.2" textLength="183" 
clip-path="url(#breeze-build-docs-line-23)">--one-pass-only</text><text 
class="breeze-build-docs-r1" x="231.8" y="581.2" textLength="1000.4" 
clip-path="url(#breeze-build-docs-line-23)">Builds&#160;documentation&#160;in&#160;one&#160;pass&#160;only.&#160;This&#160;is&#160;useful&#160;for&#160;
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="605.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-24)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="605.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-24)">
-</text><text class="breeze-build-docs-r5" x="0" y="630" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-25)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="630" textLength="268.4" 
clip-path="url(#breeze-build-docs-line-25)">&#160;Cleaning&#160;inventories&#160;</text><text
 class="breeze-build-docs-r5" x="292.8" y="630" textLength="1146.8" 
clip-path="url(#breeze-build-docs-line-25)">─────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="654.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-26)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="654.4" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-26)">--clean-build&#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-build-docs-r1" x="549" y="654.4" textLe [...]
-</text><text class="breeze-build-docs-r5" x="0" y="678.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-27)">│</text><text 
class="breeze-build-docs-r1" x="549" y="678.8" textLength="341.6" 
clip-path="url(#breeze-build-docs-line-27)">delete&#160;inventory&#160;cache&#160;(use&#160;</text><text
 class="breeze-build-docs-r4" x="890.6" y="678.8" textLength="280.6" 
clip-path="url(#breeze-build-docs-line-27)">--clean-inventory-cache</text><text 
class="breeze-build-docs-r1" x="1171.2" [...]
-</text><text class="breeze-build-docs-r5" x="0" y="703.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-28)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="703.2" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-28)">--clean-inventory-cache&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="549" y="703.2" textLength="671" 
clip-path="url(#breeze-build-docs-line- [...]
-</text><text class="breeze-build-docs-r5" x="0" y="727.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-29)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="727.6" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-29)">--refresh-airflow-inventories&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="549" y="727.6" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-29)">When&#160;set,&#160;onl [...]
-</text><text class="breeze-build-docs-r5" x="0" y="752" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-30)">│</text><text 
class="breeze-build-docs-r1" x="549" y="752" textLength="463.6" 
clip-path="url(#breeze-build-docs-line-30)">if&#160;they&#160;are&#160;already&#160;downloaded.&#160;With&#160;`</text><text
 class="breeze-build-docs-r4" x="1012.6" y="752" textLength="158.6" 
clip-path="url(#breeze-build-docs-line-30)">--clean-build</text><text 
class="breeze-build-docs-r1" x="11 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="776.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-31)">│</text><text 
class="breeze-build-docs-r1" x="549" y="776.4" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-31)">cleaned.&#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-build-docs-r5" x="0" y="800.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-32)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="800.8" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-32)">--fail-on-missing-third-party-inventories</text><text
 class="breeze-build-docs-r1" x="549" y="800.8" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-32)">Fail&#160;the&#160;build&#160;if&#160;any&#160;third-party&#160;inventory&#160;cann
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="825.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-33)">│</text><text 
class="breeze-build-docs-r1" x="549" y="825.2" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-33)">default,&#160;missing&#160;third-party&#160;inventories&#160;are&#160;warned&#160;about&#160;but&#160;do&#160;not&#160;fail</text><text
 class="breeze-build-docs-r5" x="1451.8" y="825.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-33)"> [...]
-</text><text class="breeze-build-docs-r5" x="0" y="849.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-34)">│</text><text 
class="breeze-build-docs-r1" x="549" y="849.6" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-34)">the&#160;build.&#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-build-docs-r5" x="0" y="874" textLength="1464" 
clip-path="url(#breeze-build-docs-line-35)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="874" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-35)">
-</text><text class="breeze-build-docs-r5" x="0" y="898.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-36)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="898.4" textLength="231.8" 
clip-path="url(#breeze-build-docs-line-36)">&#160;Filtering&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="256.2" y="898.4" textLength="1183.4" 
clip-path="url(#breeze-build-docs-line-36)">──────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="922.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-37)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="922.8" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-37)">--package-filter&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="402.6" y="922.8" textLength="1037" 
clip-path="url(#breeze-build-docs-line-37)">Filter(s)&#160;to&#160;use&#1 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="947.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-38)">│</text><text 
class="breeze-build-docs-r1" x="402.6" y="947.2" textLength="1037" 
clip-path="url(#breeze-build-docs-line-38)">the&#160;full&#160;package&#160;name,&#160;for&#160;example&#160;`apache-airflow-providers-*`.&#160;Useful&#160;when&#160;you&#160;want</text><text
 class="breeze-build-docs-r5" x="1451.8" y="947.2" textLength="12.2" 
clip-path="url(#breeze-build-do [...]
-</text><text class="breeze-build-docs-r5" x="0" y="971.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-39)">│</text><text 
class="breeze-build-docs-r1" x="402.6" y="971.6" textLength="634.4" 
clip-path="url(#breeze-build-docs-line-39)">to&#160;selectseveral&#160;similarly&#160;named&#160;packages&#160;together.&#160;</text><text
 class="breeze-build-docs-r7" x="1037" y="971.6" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-39)">(TEXT)</text><text 
class="breeze-build-do [...]
-</text><text class="breeze-build-docs-r5" x="0" y="996" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-40)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="996" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-40)">--include-not-ready-providers</text><text
 class="breeze-build-docs-r1" x="402.6" y="996" textLength="817.4" 
clip-path="url(#breeze-build-docs-line-40)">Whether&#160;to&#160;include&#160;providers&#160;that&#160;are&#160;not&#160;yet&#160;ready&#160;to
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1020.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-41)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1020.4" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-41)">--include-removed-providers&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="402.6" y="1020.4" textLength="561.2" 
clip-path="url(#breeze-build-docs-line-41)">Whether&#160;to&#160;include&#160;providers&#160;that&#160;are&#160;removed.</te
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1044.8" textLength="1464" 
clip-path="url(#breeze-build-docs-line-42)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1044.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-42)">
-</text><text class="breeze-build-docs-r5" x="0" y="1069.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-43)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1069.2" textLength="170.8" 
clip-path="url(#breeze-build-docs-line-43)">&#160;Misc&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="195.2" y="1069.2" textLength="1244.4" 
clip-path="url(#breeze-build-docs-line-43)">────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1093.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-44)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1093.6" textLength="244" 
clip-path="url(#breeze-build-docs-line-44)">--include-commits&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1093.6" textLength="451.4" 
clip-path="url(#breeze-build-docs-line-44)">Include&#160;commits&#160;in&#160;the&#160;documentation.</text><text
 class="breeze-bu [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1118" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-45)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1118" textLength="244" 
clip-path="url(#breeze-build-docs-line-45)">--github-repository&#160;</text><text
 class="breeze-build-docs-r6" x="292.8" y="1118" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-45)">-g</text><text 
class="breeze-build-docs-r1" x="341.6" y="1118" textLength="597.8" 
clip-path="url(#breez [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-46)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1142.4" textLength="244" 
clip-path="url(#breeze-build-docs-line-46)">--builder&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1142.4" textLength="768.6" 
clip-path="url(#breeze-build-docs-line-46)">Buildx&#160;builder&#160;used&#160;to&#160;per
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-47)">│</text><text 
class="breeze-build-docs-r7" x="341.6" y="1166.8" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-47)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-47)">│</text><text 
class="breeze-build-docs-r1" x="1464" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-build-doc [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1191.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-48)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1191.2" textLength="244" 
clip-path="url(#breeze-build-docs-line-48)">--distributions-list</text><text 
class="breeze-build-docs-r1" x="341.6" y="1191.2" textLength="1098" 
clip-path="url(#breeze-build-docs-line-48)">Optional,&#160;contains&#160;space&#160;separated&#160;list&#160;of&#160;package&#160;ids&#160;that&#1
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-49)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1215.6" textLength="1098" 
clip-path="url(#breeze-build-docs-line-49)">documentation&#160;building,&#160;and&#160;document&#160;publishing.&#160;It&#160;is&#160;an&#160;easier&#160;alternative&#160;to&#160;adding&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1215.6" textLength="12.2 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1240" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-50)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1240" textLength="1098" 
clip-path="url(#breeze-build-docs-line-50)">individual&#160;packages&#160;as&#160;arguments&#160;to&#160;every&#160;command.&#160;This&#160;overrides&#160;the&#160;packages&#160;passed&#160;as&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1240" textLength="12.2" clip-path 
[...]
-</text><text class="breeze-build-docs-r5" x="0" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-51)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1264.4" textLength="134.2" 
clip-path="url(#breeze-build-docs-line-51)">arguments.&#160;</text><text 
class="breeze-build-docs-r7" x="475.8" y="1264.4" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-51)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1264.4" textLength="12.2" 
clip-path="url( [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1288.8" textLength="1464" 
clip-path="url(#breeze-build-docs-line-52)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1288.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-52)">
-</text><text class="breeze-build-docs-r5" x="0" y="1313.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-53)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1313.2" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-53)">&#160;Common&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="219.6" y="1313.2" textLength="1220" 
clip-path="url(#breeze-build-docs-line-53)">────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1337.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-54)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1337.6" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-54)">--dry-run</text><text 
class="breeze-build-docs-r6" x="158.6" y="1337.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-54)">-D</text><text 
class="breeze-build-docs-r1" x="207.4" y="1337.6" textLength="719.8" 
clip-path="url(#breeze-buil [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1362" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-55)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1362" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-55)">--verbose</text><text 
class="breeze-build-docs-r6" x="158.6" y="1362" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-55)">-v</text><text 
class="breeze-build-docs-r1" x="207.4" y="1362" textLength="585.6" 
clip-path="url(#breeze-build-docs-l [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1386.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-56)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1386.4" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-56)">--answer&#160;</text><text 
class="breeze-build-docs-r6" x="158.6" y="1386.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-56)">-a</text><text 
class="breeze-build-docs-r1" x="207.4" y="1386.4" textLength="329.4" 
clip-path="url(#breeze [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1410.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-57)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1410.8" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-57)">--help&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r6" x="158.6" y="1410.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-57)">-h</text><text 
class="breeze-build-docs-r1" x="207.4" y="1410.8" textLength="329.4" 
clip-path="u [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1435.2" textLength="1464" 
clip-path="url(#breeze-build-docs-line-58)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1435.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-58)">
+</text><text class="breeze-build-docs-r5" x="0" y="508" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-20)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="508" textLength="207.4" 
clip-path="url(#breeze-build-docs-line-20)">--sdk-docs-only&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="305" y="508" textLength="524.6" 
clip-path="url(#breeze-build-docs-line-20)">Only&#160;build&#160;SDK&#160;docs.&#160;Requires&#160;at&#160;least&#160;one&#160;</text><text
 class=" [...]
+</text><text class="breeze-build-docs-r5" x="0" y="532.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-21)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="532.4" textLength="207.4" 
clip-path="url(#breeze-build-docs-line-21)">--spellcheck-only</text><text 
class="breeze-build-docs-r6" x="256.2" y="532.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-21)">-s</text><text 
class="breeze-build-docs-r1" x="305" y="532.4" textLength="292.8" 
clip-path="url(#breeze-bu [...]
+</text><text class="breeze-build-docs-r5" x="0" y="556.8" textLength="1464" 
clip-path="url(#breeze-build-docs-line-22)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="556.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-22)">
+</text><text class="breeze-build-docs-r5" x="0" y="581.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-23)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="581.2" textLength="183" 
clip-path="url(#breeze-build-docs-line-23)">&#160;Type&#160;of&#160;build&#160;</text><text
 class="breeze-build-docs-r5" x="207.4" y="581.2" textLength="1232.2" 
clip-path="url(#breeze-build-docs-line-23)">───────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="605.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-24)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="605.6" textLength="183" 
clip-path="url(#breeze-build-docs-line-24)">--one-pass-only</text><text 
class="breeze-build-docs-r1" x="231.8" y="605.6" textLength="1000.4" 
clip-path="url(#breeze-build-docs-line-24)">Builds&#160;documentation&#160;in&#160;one&#160;pass&#160;only.&#160;This&#160;is&#160;useful&#160;for&#160;
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="630" textLength="1464" 
clip-path="url(#breeze-build-docs-line-25)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="630" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-25)">
+</text><text class="breeze-build-docs-r5" x="0" y="654.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-26)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="654.4" textLength="268.4" 
clip-path="url(#breeze-build-docs-line-26)">&#160;Cleaning&#160;inventories&#160;</text><text
 class="breeze-build-docs-r5" x="292.8" y="654.4" textLength="1146.8" 
clip-path="url(#breeze-build-docs-line-26)">───────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="678.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-27)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="678.8" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-27)">--clean-build&#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-build-docs-r1" x="549" y="678.8" textLe [...]
+</text><text class="breeze-build-docs-r5" x="0" y="703.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-28)">│</text><text 
class="breeze-build-docs-r1" x="549" y="703.2" textLength="341.6" 
clip-path="url(#breeze-build-docs-line-28)">delete&#160;inventory&#160;cache&#160;(use&#160;</text><text
 class="breeze-build-docs-r4" x="890.6" y="703.2" textLength="280.6" 
clip-path="url(#breeze-build-docs-line-28)">--clean-inventory-cache</text><text 
class="breeze-build-docs-r1" x="1171.2" [...]
+</text><text class="breeze-build-docs-r5" x="0" y="727.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-29)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="727.6" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-29)">--clean-inventory-cache&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="549" y="727.6" textLength="671" 
clip-path="url(#breeze-build-docs-line- [...]
+</text><text class="breeze-build-docs-r5" x="0" y="752" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-30)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="752" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-30)">--refresh-airflow-inventories&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="549" y="752" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-30)">When&#160;set,&#160;only&#160 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="776.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-31)">│</text><text 
class="breeze-build-docs-r1" x="549" y="776.4" textLength="463.6" 
clip-path="url(#breeze-build-docs-line-31)">if&#160;they&#160;are&#160;already&#160;downloaded.&#160;With&#160;`</text><text
 class="breeze-build-docs-r4" x="1012.6" y="776.4" textLength="158.6" 
clip-path="url(#breeze-build-docs-line-31)">--clean-build</text><text 
class="breeze-build-docs-r1" [...]
+</text><text class="breeze-build-docs-r5" x="0" y="800.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-32)">│</text><text 
class="breeze-build-docs-r1" x="549" y="800.8" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-32)">cleaned.&#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-build-docs-r5" x="0" y="825.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-33)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="825.2" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-33)">--fail-on-missing-third-party-inventories</text><text
 class="breeze-build-docs-r1" x="549" y="825.2" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-33)">Fail&#160;the&#160;build&#160;if&#160;any&#160;third-party&#160;inventory&#160;cann
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="849.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-34)">│</text><text 
class="breeze-build-docs-r1" x="549" y="849.6" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-34)">default,&#160;missing&#160;third-party&#160;inventories&#160;are&#160;warned&#160;about&#160;but&#160;do&#160;not&#160;fail</text><text
 class="breeze-build-docs-r5" x="1451.8" y="849.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-34)"> [...]
+</text><text class="breeze-build-docs-r5" x="0" y="874" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-35)">│</text><text 
class="breeze-build-docs-r1" x="549" y="874" textLength="890.6" 
clip-path="url(#breeze-build-docs-line-35)">the&#160;build.&#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-build-docs-r5" x="0" y="898.4" textLength="1464" 
clip-path="url(#breeze-build-docs-line-36)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="898.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-36)">
+</text><text class="breeze-build-docs-r5" x="0" y="922.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-37)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="922.8" textLength="231.8" 
clip-path="url(#breeze-build-docs-line-37)">&#160;Filtering&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="256.2" y="922.8" textLength="1183.4" 
clip-path="url(#breeze-build-docs-line-37)">──────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="947.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-38)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="947.2" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-38)">--sdk&#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-build-docs-r1" x="402.6" y="947.2" textLength="305" 
clip-path="url(#bre [...]
+</text><text class="breeze-build-docs-r5" x="0" y="971.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-39)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="971.6" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-39)">--package-filter&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="402.6" y="971.6" textLength="1037" 
clip-path="url(#breeze-build-docs-line-39)">Filter(s)&#160;to&#160;use&#1 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="996" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-40)">│</text><text 
class="breeze-build-docs-r1" x="402.6" y="996" textLength="1037" 
clip-path="url(#breeze-build-docs-line-40)">the&#160;full&#160;package&#160;name,&#160;for&#160;example&#160;`apache-airflow-providers-*`.&#160;Useful&#160;when&#160;you&#160;want</text><text
 class="breeze-build-docs-r5" x="1451.8" y="996" textLength="12.2" 
clip-path="url(#breeze-build-docs-lin [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1020.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-41)">│</text><text 
class="breeze-build-docs-r1" x="402.6" y="1020.4" textLength="634.4" 
clip-path="url(#breeze-build-docs-line-41)">to&#160;selectseveral&#160;similarly&#160;named&#160;packages&#160;together.&#160;</text><text
 class="breeze-build-docs-r7" x="1037" y="1020.4" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-41)">(TEXT)</text><text 
class="breeze-build [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1044.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-42)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1044.8" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-42)">--include-not-ready-providers</text><text
 class="breeze-build-docs-r1" x="402.6" y="1044.8" textLength="817.4" 
clip-path="url(#breeze-build-docs-line-42)">Whether&#160;to&#160;include&#160;providers&#160;that&#160;are&#160;not&#160;yet&#160;read
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1069.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-43)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1069.2" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-43)">--include-removed-providers&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="402.6" y="1069.2" textLength="561.2" 
clip-path="url(#breeze-build-docs-line-43)">Whether&#160;to&#160;include&#160;providers&#160;that&#160;are&#160;removed.</te
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1093.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-44)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1093.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-44)">
+</text><text class="breeze-build-docs-r5" x="0" y="1118" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-45)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1118" textLength="170.8" 
clip-path="url(#breeze-build-docs-line-45)">&#160;Misc&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="195.2" y="1118" textLength="1244.4" 
clip-path="url(#breeze-build-docs-line-45)">──────────────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-46)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1142.4" textLength="244" 
clip-path="url(#breeze-build-docs-line-46)">--include-commits&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1142.4" textLength="451.4" 
clip-path="url(#breeze-build-docs-line-46)">Include&#160;commits&#160;in&#160;the&#160;documentation.</text><text
 class="breeze-bu [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-47)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1166.8" textLength="244" 
clip-path="url(#breeze-build-docs-line-47)">--github-repository&#160;</text><text
 class="breeze-build-docs-r6" x="292.8" y="1166.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-47)">-g</text><text 
class="breeze-build-docs-r1" x="341.6" y="1166.8" textLength="597.8" 
clip-path="ur [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1191.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-48)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1191.2" textLength="244" 
clip-path="url(#breeze-build-docs-line-48)">--builder&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1191.2" textLength="768.6" 
clip-path="url(#breeze-build-docs-line-48)">Buildx&#160;builder&#160;used&#160;to&#160;per
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-49)">│</text><text 
class="breeze-build-docs-r7" x="341.6" y="1215.6" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-49)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-49)">│</text><text 
class="breeze-build-docs-r1" x="1464" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-build-doc [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1240" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-50)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1240" textLength="244" 
clip-path="url(#breeze-build-docs-line-50)">--distributions-list</text><text 
class="breeze-build-docs-r1" x="341.6" y="1240" textLength="1098" 
clip-path="url(#breeze-build-docs-line-50)">Optional,&#160;contains&#160;space&#160;separated&#160;list&#160;of&#160;package&#160;ids&#160;that&#160;are
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-51)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1264.4" textLength="1098" 
clip-path="url(#breeze-build-docs-line-51)">documentation&#160;building,&#160;and&#160;document&#160;publishing.&#160;It&#160;is&#160;an&#160;easier&#160;alternative&#160;to&#160;adding&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1264.4" textLength="12.2 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1288.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-52)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1288.8" textLength="1098" 
clip-path="url(#breeze-build-docs-line-52)">individual&#160;packages&#160;as&#160;arguments&#160;to&#160;every&#160;command.&#160;This&#160;overrides&#160;the&#160;packages&#160;passed&#160;as&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1288.8" textLength="12.2" cli [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1313.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-53)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1313.2" textLength="134.2" 
clip-path="url(#breeze-build-docs-line-53)">arguments.&#160;</text><text 
class="breeze-build-docs-r7" x="475.8" y="1313.2" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-53)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1313.2" textLength="12.2" 
clip-path="url( [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1337.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-54)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1337.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-54)">
+</text><text class="breeze-build-docs-r5" x="0" y="1362" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-55)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1362" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-55)">&#160;Common&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="219.6" y="1362" textLength="1220" 
clip-path="url(#breeze-build-docs-line-55)">──────────────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1386.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-56)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1386.4" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-56)">--dry-run</text><text 
class="breeze-build-docs-r6" x="158.6" y="1386.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-56)">-D</text><text 
class="breeze-build-docs-r1" x="207.4" y="1386.4" textLength="719.8" 
clip-path="url(#breeze-buil [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1410.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-57)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1410.8" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-57)">--verbose</text><text 
class="breeze-build-docs-r6" x="158.6" y="1410.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-57)">-v</text><text 
class="breeze-build-docs-r1" x="207.4" y="1410.8" textLength="585.6" 
clip-path="url(#breeze-buil [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1435.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-58)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1435.2" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-58)">--answer&#160;</text><text 
class="breeze-build-docs-r6" x="158.6" y="1435.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-58)">-a</text><text 
class="breeze-build-docs-r1" x="207.4" y="1435.2" textLength="329.4" 
clip-path="url(#breeze [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1459.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-59)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1459.6" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-59)">--help&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r6" x="158.6" y="1459.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-59)">-h</text><text 
class="breeze-build-docs-r1" x="207.4" y="1459.6" textLength="329.4" 
clip-path="u [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1484" textLength="1464" 
clip-path="url(#breeze-build-docs-line-60)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1484" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-60)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_build-docs.txt 
b/dev/breeze/doc/images/output_build-docs.txt
index 0fa514dab7e..087af2222c3 100644
--- a/dev/breeze/doc/images/output_build-docs.txt
+++ b/dev/breeze/doc/images/output_build-docs.txt
@@ -1 +1 @@
-0b3599cfabb8a89ef291a916aead20ad
+3cdfae5aadaebb0e62a841f8cf18783e
diff --git a/dev/breeze/doc/images/output_shell.svg 
b/dev/breeze/doc/images/output_shell.svg
index 3d183fe886d..da26b3d8234 100644
--- a/dev/breeze/doc/images/output_shell.svg
+++ b/dev/breeze/doc/images/output_shell.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 4173.599999999999" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 4198.0" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-shell-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="4122.599999999999" />
+      <rect x="0" y="0" width="1463.0" height="4147.0" />
     </clipPath>
     <clipPath id="breeze-shell-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -549,9 +549,12 @@
 <clipPath id="breeze-shell-line-167">
     <rect x="0" y="4076.3" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-shell-line-168">
+    <rect x="0" y="4100.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="4171.6" rx="8"/><text 
class="breeze-shell-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;shell</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="4196" rx="8"/><text class="breeze-shell-title" 
fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;shell</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -727,9 +730,10 @@
 </text><text class="breeze-shell-r5" x="0" y="3997.2" textLength="24.4" 
clip-path="url(#breeze-shell-line-163)">╭─</text><text class="breeze-shell-r5" 
x="24.4" y="3997.2" textLength="195.2" 
clip-path="url(#breeze-shell-line-163)">&#160;Common&#160;options&#160;</text><text
 class="breeze-shell-r5" x="219.6" y="3997.2" textLength="1220" 
clip-path="url(#breeze-shell-line-163)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
 cl [...]
 </text><text class="breeze-shell-r5" x="0" y="4021.6" textLength="12.2" 
clip-path="url(#breeze-shell-line-164)">│</text><text class="breeze-shell-r4" 
x="24.4" y="4021.6" textLength="109.8" 
clip-path="url(#breeze-shell-line-164)">--answer&#160;</text><text 
class="breeze-shell-r6" x="158.6" y="4021.6" textLength="24.4" 
clip-path="url(#breeze-shell-line-164)">-a</text><text class="breeze-shell-r1" 
x="207.4" y="4021.6" textLength="329.4" 
clip-path="url(#breeze-shell-line-164)">Force&#160;ans [...]
 </text><text class="breeze-shell-r5" x="0" y="4046" textLength="12.2" 
clip-path="url(#breeze-shell-line-165)">│</text><text class="breeze-shell-r4" 
x="24.4" y="4046" textLength="109.8" 
clip-path="url(#breeze-shell-line-165)">--dry-run</text><text 
class="breeze-shell-r6" x="158.6" y="4046" textLength="24.4" 
clip-path="url(#breeze-shell-line-165)">-D</text><text class="breeze-shell-r1" 
x="207.4" y="4046" textLength="719.8" 
clip-path="url(#breeze-shell-line-165)">If&#160;dry-run&#160;is&#16 [...]
-</text><text class="breeze-shell-r5" x="0" y="4070.4" textLength="12.2" 
clip-path="url(#breeze-shell-line-166)">│</text><text class="breeze-shell-r4" 
x="24.4" y="4070.4" textLength="109.8" 
clip-path="url(#breeze-shell-line-166)">--verbose</text><text 
class="breeze-shell-r6" x="158.6" y="4070.4" textLength="24.4" 
clip-path="url(#breeze-shell-line-166)">-v</text><text class="breeze-shell-r1" 
x="207.4" y="4070.4" textLength="585.6" 
clip-path="url(#breeze-shell-line-166)">Print&#160;verbose& [...]
-</text><text class="breeze-shell-r5" x="0" y="4094.8" textLength="12.2" 
clip-path="url(#breeze-shell-line-167)">│</text><text class="breeze-shell-r4" 
x="24.4" y="4094.8" textLength="109.8" 
clip-path="url(#breeze-shell-line-167)">--help&#160;&#160;&#160;</text><text 
class="breeze-shell-r6" x="158.6" y="4094.8" textLength="24.4" 
clip-path="url(#breeze-shell-line-167)">-h</text><text class="breeze-shell-r1" 
x="207.4" y="4094.8" textLength="329.4" 
clip-path="url(#breeze-shell-line-167)">Show [...]
-</text><text class="breeze-shell-r5" x="0" y="4119.2" textLength="1464" 
clip-path="url(#breeze-shell-line-168)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-shell-r1" x="1464" y="4119.2" textLength="12.2" 
clip-path="url(#breeze-shell-line-168)">
+</text><text class="breeze-shell-r5" x="0" y="4070.4" textLength="12.2" 
clip-path="url(#breeze-shell-line-166)">│</text><text class="breeze-shell-r4" 
x="24.4" y="4070.4" textLength="109.8" 
clip-path="url(#breeze-shell-line-166)">--sdk&#160;&#160;&#160;&#160;</text><text
 class="breeze-shell-r1" x="207.4" y="4070.4" textLength="305" 
clip-path="url(#breeze-shell-line-166)">Install&#160;SDK&#160;toolchain(s)&#160;</text><text
 class="breeze-shell-r7" x="512.4" y="4070.4" textLength="73.2" cli [...]
+</text><text class="breeze-shell-r5" x="0" y="4094.8" textLength="12.2" 
clip-path="url(#breeze-shell-line-167)">│</text><text class="breeze-shell-r4" 
x="24.4" y="4094.8" textLength="109.8" 
clip-path="url(#breeze-shell-line-167)">--verbose</text><text 
class="breeze-shell-r6" x="158.6" y="4094.8" textLength="24.4" 
clip-path="url(#breeze-shell-line-167)">-v</text><text class="breeze-shell-r1" 
x="207.4" y="4094.8" textLength="585.6" 
clip-path="url(#breeze-shell-line-167)">Print&#160;verbose& [...]
+</text><text class="breeze-shell-r5" x="0" y="4119.2" textLength="12.2" 
clip-path="url(#breeze-shell-line-168)">│</text><text class="breeze-shell-r4" 
x="24.4" y="4119.2" textLength="109.8" 
clip-path="url(#breeze-shell-line-168)">--help&#160;&#160;&#160;</text><text 
class="breeze-shell-r6" x="158.6" y="4119.2" textLength="24.4" 
clip-path="url(#breeze-shell-line-168)">-h</text><text class="breeze-shell-r1" 
x="207.4" y="4119.2" textLength="329.4" 
clip-path="url(#breeze-shell-line-168)">Show [...]
+</text><text class="breeze-shell-r5" x="0" y="4143.6" textLength="1464" 
clip-path="url(#breeze-shell-line-169)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-shell-r1" x="1464" y="4143.6" textLength="12.2" 
clip-path="url(#breeze-shell-line-169)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_shell.txt 
b/dev/breeze/doc/images/output_shell.txt
index c6f0033fe49..672adb52e5b 100644
--- a/dev/breeze/doc/images/output_shell.txt
+++ b/dev/breeze/doc/images/output_shell.txt
@@ -1 +1 @@
-8870a64a6164fe50500283a4f1893b24
+268e5e72a6e6f5aba13c0dd76e5ba398
diff --git a/dev/breeze/doc/images/output_start-airflow.svg 
b/dev/breeze/doc/images/output_start-airflow.svg
index 963644f1ea3..b14cbe00c20 100644
--- a/dev/breeze/doc/images/output_start-airflow.svg
+++ b/dev/breeze/doc/images/output_start-airflow.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 3661.2" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 3685.6" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-start-airflow-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="3610.2" />
+      <rect x="0" y="0" width="1463.0" height="3634.6" />
     </clipPath>
     <clipPath id="breeze-start-airflow-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -486,9 +486,12 @@
 <clipPath id="breeze-start-airflow-line-146">
     <rect x="0" y="3563.9" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-start-airflow-line-147">
+    <rect x="0" y="3588.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="3659.2" rx="8"/><text 
class="breeze-start-airflow-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;start-airflow</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="3683.6" rx="8"/><text 
class="breeze-start-airflow-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;start-airflow</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -643,9 +646,10 @@
 </text><text class="breeze-start-airflow-r5" x="0" y="3484.8" 
textLength="24.4" 
clip-path="url(#breeze-start-airflow-line-142)">╭─</text><text 
class="breeze-start-airflow-r5" x="24.4" y="3484.8" textLength="195.2" 
clip-path="url(#breeze-start-airflow-line-142)">&#160;Common&#160;options&#160;</text><text
 class="breeze-start-airflow-r5" x="219.6" y="3484.8" textLength="1220" 
clip-path="url(#breeze-start-airflow-line-142)">───────────────────────────────────────────────────────────────────
 [...]
 </text><text class="breeze-start-airflow-r5" x="0" y="3509.2" 
textLength="12.2" clip-path="url(#breeze-start-airflow-line-143)">│</text><text 
class="breeze-start-airflow-r4" x="24.4" y="3509.2" textLength="109.8" 
clip-path="url(#breeze-start-airflow-line-143)">--answer&#160;</text><text 
class="breeze-start-airflow-r6" x="158.6" y="3509.2" textLength="24.4" 
clip-path="url(#breeze-start-airflow-line-143)">-a</text><text 
class="breeze-start-airflow-r1" x="207.4" y="3509.2" textLength="329.4 [...]
 </text><text class="breeze-start-airflow-r5" x="0" y="3533.6" 
textLength="12.2" clip-path="url(#breeze-start-airflow-line-144)">│</text><text 
class="breeze-start-airflow-r4" x="24.4" y="3533.6" textLength="109.8" 
clip-path="url(#breeze-start-airflow-line-144)">--dry-run</text><text 
class="breeze-start-airflow-r6" x="158.6" y="3533.6" textLength="24.4" 
clip-path="url(#breeze-start-airflow-line-144)">-D</text><text 
class="breeze-start-airflow-r1" x="207.4" y="3533.6" textLength="719.8" cli 
[...]
-</text><text class="breeze-start-airflow-r5" x="0" y="3558" textLength="12.2" 
clip-path="url(#breeze-start-airflow-line-145)">│</text><text 
class="breeze-start-airflow-r4" x="24.4" y="3558" textLength="109.8" 
clip-path="url(#breeze-start-airflow-line-145)">--verbose</text><text 
class="breeze-start-airflow-r6" x="158.6" y="3558" textLength="24.4" 
clip-path="url(#breeze-start-airflow-line-145)">-v</text><text 
class="breeze-start-airflow-r1" x="207.4" y="3558" textLength="585.6" 
clip-path=" [...]
-</text><text class="breeze-start-airflow-r5" x="0" y="3582.4" 
textLength="12.2" clip-path="url(#breeze-start-airflow-line-146)">│</text><text 
class="breeze-start-airflow-r4" x="24.4" y="3582.4" textLength="109.8" 
clip-path="url(#breeze-start-airflow-line-146)">--help&#160;&#160;&#160;</text><text
 class="breeze-start-airflow-r6" x="158.6" y="3582.4" textLength="24.4" 
clip-path="url(#breeze-start-airflow-line-146)">-h</text><text 
class="breeze-start-airflow-r1" x="207.4" y="3582.4" textLen [...]
-</text><text class="breeze-start-airflow-r5" x="0" y="3606.8" 
textLength="1464" 
clip-path="url(#breeze-start-airflow-line-147)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-start-airflow-r1" x="1464" y="3606.8" textLength="12.2" 
clip-path="url(#breeze-start-airflow-line-147)">
+</text><text class="breeze-start-airflow-r5" x="0" y="3558" textLength="12.2" 
clip-path="url(#breeze-start-airflow-line-145)">│</text><text 
class="breeze-start-airflow-r4" x="24.4" y="3558" textLength="109.8" 
clip-path="url(#breeze-start-airflow-line-145)">--sdk&#160;&#160;&#160;&#160;</text><text
 class="breeze-start-airflow-r1" x="207.4" y="3558" textLength="305" 
clip-path="url(#breeze-start-airflow-line-145)">Install&#160;SDK&#160;toolchain(s)&#160;</text><text
 class="breeze-start-airf [...]
+</text><text class="breeze-start-airflow-r5" x="0" y="3582.4" 
textLength="12.2" clip-path="url(#breeze-start-airflow-line-146)">│</text><text 
class="breeze-start-airflow-r4" x="24.4" y="3582.4" textLength="109.8" 
clip-path="url(#breeze-start-airflow-line-146)">--verbose</text><text 
class="breeze-start-airflow-r6" x="158.6" y="3582.4" textLength="24.4" 
clip-path="url(#breeze-start-airflow-line-146)">-v</text><text 
class="breeze-start-airflow-r1" x="207.4" y="3582.4" textLength="585.6" cli 
[...]
+</text><text class="breeze-start-airflow-r5" x="0" y="3606.8" 
textLength="12.2" clip-path="url(#breeze-start-airflow-line-147)">│</text><text 
class="breeze-start-airflow-r4" x="24.4" y="3606.8" textLength="109.8" 
clip-path="url(#breeze-start-airflow-line-147)">--help&#160;&#160;&#160;</text><text
 class="breeze-start-airflow-r6" x="158.6" y="3606.8" textLength="24.4" 
clip-path="url(#breeze-start-airflow-line-147)">-h</text><text 
class="breeze-start-airflow-r1" x="207.4" y="3606.8" textLen [...]
+</text><text class="breeze-start-airflow-r5" x="0" y="3631.2" 
textLength="1464" 
clip-path="url(#breeze-start-airflow-line-148)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-start-airflow-r1" x="1464" y="3631.2" textLength="12.2" 
clip-path="url(#breeze-start-airflow-line-148)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_start-airflow.txt 
b/dev/breeze/doc/images/output_start-airflow.txt
index fc5c2310f14..71b4385707e 100644
--- a/dev/breeze/doc/images/output_start-airflow.txt
+++ b/dev/breeze/doc/images/output_start-airflow.txt
@@ -1 +1 @@
-dc6fa1ae074c8aceab338e5fbdeab30a
+0b5bd6cfdae3da14beea1b9df4ed549c
diff --git a/dev/breeze/src/airflow_breeze/commands/common_options.py 
b/dev/breeze/src/airflow_breeze/commands/common_options.py
index 12d4b3f40d3..8d40ce1a179 100644
--- a/dev/breeze/src/airflow_breeze/commands/common_options.py
+++ b/dev/breeze/src/airflow_breeze/commands/common_options.py
@@ -32,6 +32,7 @@ from airflow_breeze.global_constants import (
     ALLOWED_MYSQL_VERSIONS,
     ALLOWED_POSTGRES_VERSIONS,
     ALLOWED_PYTHON_MAJOR_MINOR_VERSIONS,
+    ALLOWED_SDKS,
     ALLOWED_TERMINAL_MULTIPLEXERS,
     ALLOWED_TTY,
     ALLOWED_USE_AIRFLOW_VERSIONS,
@@ -611,6 +612,14 @@ option_worker_types = click.option(
     envvar="WORKER_TYPE",
 )
 
+option_sdk = click.option(
+    "--sdk",
+    help="Install SDK toolchain(s)",
+    type=BetterChoice(ALLOWED_SDKS),
+    multiple=True,
+    envvar="BREEZE_SDK",
+)
+
 # UI E2E Testing Options
 
 option_airflow_ui_base_url = click.option(
diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py 
b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
index b4c92b5af44..3768a3e2461 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
@@ -69,6 +69,7 @@ from airflow_breeze.commands.common_options import (
     option_project_name,
     option_python,
     option_run_db_tests_only,
+    option_sdk,
     option_skip_db_tests,
     option_standalone_dag_processor,
     option_terminal_multiplexer,
@@ -347,6 +348,7 @@ option_load_default_connections = click.option(
 @option_providers_skip_constraints
 @option_python
 @option_restart
+@option_sdk
 @option_run_db_tests_only
 @option_skip_db_tests
 @option_skip_environment_initialization
@@ -409,6 +411,7 @@ def shell(
     python: str,
     quiet: bool,
     restart: bool,
+    sdk: tuple[str, ...],
     run_db_tests_only: bool,
     skip_environment_initialization: bool,
     skip_db_tests: bool,
@@ -485,6 +488,7 @@ def shell(
         python=python,
         quiet=quiet,
         restart=restart,
+        sdk=sdk,
         run_db_tests_only=run_db_tests_only,
         skip_db_tests=skip_db_tests,
         skip_image_upgrade_check=skip_image_upgrade_check,
@@ -577,6 +581,7 @@ option_executor_start_airflow = click.option(
 @option_providers_skip_constraints
 @option_python
 @option_restart
+@option_sdk
 @option_standalone_dag_processor
 @option_terminal_multiplexer
 @option_use_uv
@@ -627,6 +632,7 @@ def start_airflow(
     providers_skip_constraints: bool,
     python: str,
     restart: bool,
+    sdk: tuple[str, ...],
     skip_assets_compilation: bool,
     standalone_dag_processor: bool,
     terminal_multiplexer: str,
@@ -714,6 +720,7 @@ def start_airflow(
         forward_credentials=forward_credentials,
         github_repository=github_repository,
         worker_type=worker_type,
+        sdk=sdk,
         integration=integration,
         install_selected_providers=install_selected_providers,
         install_airflow_with_constraints=install_airflow_with_constraints,
@@ -752,6 +759,161 @@ def start_airflow(
     sys.exit(result.returncode)
 
 
+def _get_java_sdk_version() -> str:
+    """Read the Java SDK version from 'java-sdk/gradle.properties'."""
+    props_path = AIRFLOW_ROOT_PATH / "java-sdk" / "gradle.properties"
+    for line in props_path.read_text().splitlines():
+        if match := re.match(r"^sdkVersion\s*=\s*(\S+)$", line.strip()):
+            return match.group(1)
+    raise RuntimeError(f"Java SDK version not found in {props_path}")
+
+
+def _build_java_sdk_docs(generated_path: Path) -> int:
+    """Run Dokka for the Java SDK and stage its output for the publish 
pipeline.
+
+    Runs ``./gradlew :sdk:dokkaGeneratePublicationHtml`` inside a container of
+    ``eclipse-temurin:11-jdk`` so no local JDK installation is required. The
+    resulting HTML tree is placed at::
+
+        generated/_build/docs/java-sdk/stable/
+
+    and a ``stable.txt`` file (containing the Java SDK version from
+    ``java-sdk/gradle.properties``) is written alongside it so that
+    ``breeze release-management publish-docs`` places the docs at
+    ``docs-archive/java-sdk/{version}/``.
+    """
+    java_sdk_root = AIRFLOW_ROOT_PATH / "java-sdk"
+    console_print("[info]Building Java SDK Javadoc with Dokka 
(eclipse-temurin:11-jdk)...")
+    result = run_command(
+        [
+            "docker",
+            "run",
+            "--rm",
+            "--user",
+            f"{os.getuid()}:{os.getgid()}",
+            # Persist the Gradle wrapper distribution and dependency cache 
between runs.
+            "-e",
+            "GRADLE_USER_HOME=/repo/java-sdk/.gradle",
+            "-v",
+            f"{AIRFLOW_ROOT_PATH}:/repo",
+            "-w",
+            "/repo/java-sdk",
+            "eclipse-temurin:11-jdk",
+            "./gradlew",
+            ":sdk:dokkaGeneratePublicationHtml",
+            "--no-daemon",
+        ],
+        check=False,
+    )
+    if result.returncode != 0:
+        console_print("[error]Dokka build failed.")
+        return result.returncode
+
+    src = java_sdk_root / "sdk" / "build" / "dokka" / "html"
+    dst = generated_path / "_build" / "docs" / "java-sdk" / "stable"
+    console_print(f"[info]Staging Dokka output: {src} -> {dst}")
+    dst.mkdir(parents=True, exist_ok=True)
+    shutil.copytree(src, dst, dirs_exist_ok=True)
+
+    # Write stable.txt so breeze release-management publish-docs treats this 
as a
+    # versioned package and places it at docs-archive/java-sdk/{version}/.
+    sdk_version = _get_java_sdk_version()
+    stable_txt = generated_path / "_build" / "docs" / "java-sdk" / "stable.txt"
+    stable_txt.write_text(sdk_version + "\n")
+    console_print(f"[success]Java SDK docs staged at {dst}  (version: 
{sdk_version})")
+    return 0
+
+
+def _build_python_docs(
+    *,
+    generated_path: Path,
+    builder: str,
+    clean_build: bool,
+    clean_inventory_cache: bool,
+    refresh_airflow_inventories: bool,
+    fail_on_missing_third_party_inventories: bool,
+    docs_only: bool,
+    github_repository: str,
+    include_not_ready_providers: bool,
+    include_removed_providers: bool,
+    include_commits: bool,
+    one_pass_only: bool,
+    package_filter: tuple[str, ...],
+    distributions_list: str,
+    spellcheck_only: bool,
+    doc_packages: tuple[str, ...],
+):
+    build_params = BuildCiParams(
+        github_repository=github_repository,
+        python=DEFAULT_PYTHON_MAJOR_MINOR_VERSION,
+        builder=builder,
+    )
+    rebuild_or_pull_ci_image_if_needed(command_params=build_params)
+    if clean_build:
+        directories_to_clean = ["_build", "_doctrees", "apis"]
+    else:
+        directories_to_clean = ["apis"]
+    for dir_name in directories_to_clean:
+        console_print("Removing all generated dirs.")
+        for directory in generated_path.rglob(dir_name):
+            console_print(f"[info]Removing {directory}")
+            shutil.rmtree(directory, ignore_errors=True)
+    if clean_inventory_cache:
+        inventory_cache_dir = generated_path / "_inventory_cache"
+        if inventory_cache_dir.exists():
+            console_print(f"[info]Removing inventory cache: 
{inventory_cache_dir}")
+            shutil.rmtree(inventory_cache_dir, ignore_errors=True)
+    if refresh_airflow_inventories and not clean_build:
+        console_print("Removing airflow inventories.")
+        package_globs = ["helm-chart", "docker-stack", "apache-airflow*"]
+        for package_glob in package_globs:
+            for directory in (generated_path / 
"_inventory_cache").rglob(package_glob):
+                console_print(f"[info]Removing {directory}")
+                shutil.rmtree(directory, ignore_errors=True)
+
+    docs_list_as_tuple: tuple[str, ...] = ()
+    if distributions_list and len(distributions_list):
+        console_print(f"\n[info]Populating provider list from 
DISTRIBUTIONS_LIST env as {distributions_list}")
+        docs_list_as_tuple = tuple(distributions_list.split(" "))
+    if doc_packages and docs_list_as_tuple:
+        console_print(
+            f"[warning]Both package arguments and --distributions-list / 
DISTRIBUTIONS_LIST passed. "
+            f"Overriding to {docs_list_as_tuple}"
+        )
+    doc_packages = docs_list_as_tuple or doc_packages
+    doc_builder = DocBuildParams(
+        package_filter=package_filter,
+        docs_only=docs_only,
+        spellcheck_only=spellcheck_only,
+        one_pass_only=one_pass_only,
+        include_commits=include_commits,
+        
fail_on_missing_third_party_inventories=fail_on_missing_third_party_inventories,
+        clean_inventory_cache=clean_inventory_cache,
+        short_doc_packages=expand_all_provider_distributions(
+            short_doc_packages=doc_packages,
+            include_removed=include_removed_providers,
+            include_not_ready=include_not_ready_providers,
+        ),
+    )
+    cmd = "/opt/airflow/scripts/in_container/run_docs_build.sh " + " ".join(
+        shlex.quote(arg) for arg in doc_builder.args_doc_builder
+    )
+    shell_params = ShellParams(
+        github_repository=github_repository,
+        python=DEFAULT_PYTHON_MAJOR_MINOR_VERSION,
+        mount_sources=MOUNT_ALL,
+    )
+    result = execute_command_in_shell(shell_params, 
project_name="breeze-docs", command=cmd)
+    fix_ownership_using_docker()
+    sphinx_returncode = result.returncode
+    if sphinx_returncode == 0:
+        console_print(
+            "Run ./docs/start_doc_server.sh for a lighter resource option and 
view "
+            "the built docs at http://localhost:8000";
+        )
+    return sphinx_returncode
+
+
 @main.command(name="build-docs")
 @option_builder
 @click.option(
@@ -807,6 +969,12 @@ def start_airflow(
     " arguments to every command. This overrides the packages passed as 
arguments.",
 )
 @click.option("-s", "--spellcheck-only", help="Only run spell checking.", 
is_flag=True)
+@option_sdk
[email protected](
+    "--sdk-docs-only",
+    is_flag=True,
+    help="Only build SDK docs. Requires at least one --sdk value to be 
useful.",
+)
 @option_verbose
 @option_answer
 @argument_doc_packages
@@ -825,6 +993,8 @@ def build_docs(
     package_filter: tuple[str, ...],
     distributions_list: str,
     spellcheck_only: bool,
+    sdk: tuple[str, ...],
+    sdk_docs_only: bool,
     doc_packages: tuple[str, ...],
 ):
     """
@@ -833,76 +1003,32 @@ def build_docs(
     perform_environment_checks()
     fix_ownership_using_docker()
     cleanup_python_generated_files()
-    build_params = BuildCiParams(
-        github_repository=github_repository,
-        python=DEFAULT_PYTHON_MAJOR_MINOR_VERSION,
-        builder=builder,
-    )
-    rebuild_or_pull_ci_image_if_needed(command_params=build_params)
-    if clean_build:
-        directories_to_clean = ["_build", "_doctrees", "apis"]
-    else:
-        directories_to_clean = ["apis"]
     generated_path = AIRFLOW_ROOT_PATH / "generated"
-    for dir_name in directories_to_clean:
-        console_print("Removing all generated dirs.")
-        for directory in generated_path.rglob(dir_name):
-            console_print(f"[info]Removing {directory}")
-            shutil.rmtree(directory, ignore_errors=True)
-    if clean_inventory_cache:
-        inventory_cache_dir = generated_path / "_inventory_cache"
-        if inventory_cache_dir.exists():
-            console_print(f"[info]Removing inventory cache: 
{inventory_cache_dir}")
-            shutil.rmtree(inventory_cache_dir, ignore_errors=True)
-    if refresh_airflow_inventories and not clean_build:
-        console_print("Removing airflow inventories.")
-        package_globs = ["helm-chart", "docker-stack", "apache-airflow*"]
-        for package_glob in package_globs:
-            for directory in (generated_path / 
"_inventory_cache").rglob(package_glob):
-                console_print(f"[info]Removing {directory}")
-                shutil.rmtree(directory, ignore_errors=True)
 
-    docs_list_as_tuple: tuple[str, ...] = ()
-    if distributions_list and len(distributions_list):
-        console_print(f"\n[info]Populating provider list from 
DISTRIBUTIONS_LIST env as {distributions_list}")
-        # Override doc_packages with values from DISTRIBUTIONS_LIST
-        docs_list_as_tuple = tuple(distributions_list.split(" "))
-    if doc_packages and docs_list_as_tuple:
-        console_print(
-            f"[warning]Both package arguments and --distributions-list / 
DISTRIBUTIONS_LIST passed. "
-            f"Overriding to {docs_list_as_tuple}"
-        )
-    doc_packages = docs_list_as_tuple or doc_packages
-    doc_builder = DocBuildParams(
-        package_filter=package_filter,
-        docs_only=docs_only,
-        spellcheck_only=spellcheck_only,
-        one_pass_only=one_pass_only,
-        include_commits=include_commits,
-        
fail_on_missing_third_party_inventories=fail_on_missing_third_party_inventories,
-        clean_inventory_cache=clean_inventory_cache,
-        short_doc_packages=expand_all_provider_distributions(
-            short_doc_packages=doc_packages,
-            include_removed=include_removed_providers,
-            include_not_ready=include_not_ready_providers,
-        ),
-    )
-    cmd = "/opt/airflow/scripts/in_container/run_docs_build.sh " + " ".join(
-        [shlex.quote(arg) for arg in doc_builder.args_doc_builder]
-    )
-    shell_params = ShellParams(
-        github_repository=github_repository,
-        python=DEFAULT_PYTHON_MAJOR_MINOR_VERSION,
-        mount_sources=MOUNT_ALL,
-    )
-    result = execute_command_in_shell(shell_params, 
project_name="breeze-docs", command=cmd)
-    fix_ownership_using_docker()
-    if result.returncode == 0:
-        console_print(
-            "Run ./docs/start_doc_server.sh for a lighter resource option and 
view "
-            "the built docs at http://localhost:8000";
+    returncode = 0
+    if not sdk_docs_only:
+        returncode = _build_python_docs(
+            generated_path=generated_path,
+            builder=builder,
+            clean_build=clean_build,
+            clean_inventory_cache=clean_inventory_cache,
+            refresh_airflow_inventories=refresh_airflow_inventories,
+            
fail_on_missing_third_party_inventories=fail_on_missing_third_party_inventories,
+            docs_only=docs_only,
+            github_repository=github_repository,
+            include_not_ready_providers=include_not_ready_providers,
+            include_removed_providers=include_removed_providers,
+            include_commits=include_commits,
+            one_pass_only=one_pass_only,
+            package_filter=package_filter,
+            distributions_list=distributions_list,
+            spellcheck_only=spellcheck_only,
+            doc_packages=doc_packages,
         )
-    sys.exit(result.returncode)
+    if "java" in sdk:
+        returncode = returncode or 
_build_java_sdk_docs(generated_path=generated_path)
+
+    sys.exit(returncode)
 
 
 @main.command(
diff --git 
a/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py 
b/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
index 74ca92841a1..fe27f84f696 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
@@ -170,6 +170,7 @@ DEVELOPER_PARAMETERS: dict[str, list[dict[str, str | 
list[str]]]] = {
                 "--allow-pre-releases",
                 "--use-distributions-from-dist",
                 "--install-airflow-python-client",
+                "--sdk",
             ],
         },
         {
@@ -253,6 +254,7 @@ DEVELOPER_PARAMETERS: dict[str, list[dict[str, str | 
list[str]]]] = {
                 "--github-repository",
                 "--builder",
                 "--use-uv",
+                "--sdk",
             ],
         },
         {
@@ -357,8 +359,8 @@ DEVELOPER_PARAMETERS: dict[str, list[dict[str, str | 
list[str]]]] = {
     ],
     "breeze build-docs": [
         {
-            "name": "Build scope (default is to build docs and spellcheck)",
-            "options": ["--docs-only", "--spellcheck-only"],
+            "name": "Build scope (default is to build Python docs and 
spellcheck)",
+            "options": ["--docs-only", "--sdk-docs-only", "--spellcheck-only"],
         },
         {
             "name": "Type of build",
@@ -376,6 +378,7 @@ DEVELOPER_PARAMETERS: dict[str, list[dict[str, str | 
list[str]]]] = {
         {
             "name": "Filtering options",
             "options": [
+                "--sdk",
                 "--package-filter",
                 "--include-not-ready-providers",
                 "--include-removed-providers",
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 f7dfa648f37..05a53805921 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -197,8 +197,13 @@ from airflow_breeze.utils.versions import is_pre_release
 from airflow_breeze.utils.virtualenv_utils import create_venv
 
 if TYPE_CHECKING:
+    from typing import TypeAlias
+
+    from github import Issue, PullRequest
     from packaging.version import Version
 
+    PullRequestOrIssue: TypeAlias = PullRequest.PullRequest | Issue.Issue
+
 argument_provider_distributions = click.argument(
     "provider_distributions",
     nargs=-1,
@@ -2642,7 +2647,7 @@ def generate_issue_content_providers(
     provider_distributions: list[str],
 ):
     import jinja2
-    from github import Github, Issue, PullRequest, UnknownObjectException
+    from github import Github, UnknownObjectException
 
     class ProviderPRInfo(NamedTuple):
         provider_id: str
@@ -4468,9 +4473,8 @@ def generate_issue_content(
     is_helm_chart: bool,
     is_airflow_ctl: bool = False,
 ):
-    from github import Github, Issue, PullRequest, UnknownObjectException
+    from github import Github, UnknownObjectException
 
-    PullRequestOrIssue = PullRequest.PullRequest | Issue.Issue
     verbose = get_verbose()
 
     previous = previous_release
@@ -4488,7 +4492,7 @@ def generate_issue_content(
     g = Github(github_token)
     repo = g.get_repo("apache/airflow")
     pull_requests: dict[int, PullRequestOrIssue] = {}
-    linked_issues: dict[int, list[Issue.Issue]] = defaultdict(lambda: [])
+    linked_issues: dict[int, list[Issue.Issue]] = defaultdict(list)
     users: dict[int, set[str]] = defaultdict(lambda: set())
     count_prs = limit_pr_count or len(prs)
 
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py 
b/dev/breeze/src/airflow_breeze/global_constants.py
index bdf280e44b6..9e121866c7c 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -196,6 +196,9 @@ FAB_AUTH_MANAGER = "FabAuthManager"
 
 GOLANG_WORKER = "go"
 
+JAVA_SDK = "java"
+ALLOWED_SDKS = [JAVA_SDK]
+
 DEFAULT_ALLOWED_EXECUTOR = ALLOWED_EXECUTORS[0]
 ALLOWED_AUTH_MANAGERS = [SIMPLE_AUTH_MANAGER, FAB_AUTH_MANAGER]
 START_AIRFLOW_ALLOWED_EXECUTORS = [LOCAL_EXECUTOR, CELERY_EXECUTOR, 
EDGE_EXECUTOR]
diff --git a/dev/breeze/src/airflow_breeze/params/shell_params.py 
b/dev/breeze/src/airflow_breeze/params/shell_params.py
index f900fb079f2..1a6f6701ca1 100644
--- a/dev/breeze/src/airflow_breeze/params/shell_params.py
+++ b/dev/breeze/src/airflow_breeze/params/shell_params.py
@@ -196,6 +196,7 @@ class ShellParams:
     github_actions: str = os.environ.get("GITHUB_ACTIONS", "false")
     github_repository: str = APACHE_AIRFLOW_GITHUB_REPOSITORY
     github_token: str = os.environ.get("GITHUB_TOKEN", "")
+    sdk: tuple[str, ...] = ()
     worker_type: tuple[str, ...] = ()
     include_mypy_volume: bool = False
     install_airflow_version: str = ""
@@ -663,6 +664,8 @@ services:
         _set_var(_env, "GITHUB_TOKEN", self.github_token)
         if "go" in self.worker_type:
             _set_var(_env, "GO_WORKER", True)
+        if "java" in self.sdk:
+            _set_var(_env, "INSTALL_SDK_JAVA", True)
         _set_var(_env, "HOST_GROUP_ID", self.host_group_id)
         _set_var(_env, "HOST_OS", self.host_os)
         _set_var(_env, "HOST_USER_ID", self.host_user_id)
diff --git a/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py 
b/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py
index 8b56ea3c4ee..756913e690c 100644
--- a/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py
+++ b/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py
@@ -30,7 +30,14 @@ from airflow_breeze.utils.parallel import 
check_async_run_results, run_with_pool
 
 PROVIDER_NAME_FORMAT = "apache-airflow-providers-{}"
 
-NON_SHORT_NAME_PACKAGES = ["apache-airflow", "apache-airflow-ctl", 
"docker-stack", "helm-chart", "task-sdk"]
+NON_SHORT_NAME_PACKAGES = [
+    "apache-airflow",
+    "apache-airflow-ctl",
+    "docker-stack",
+    "helm-chart",
+    "java-sdk",
+    "task-sdk",
+]
 
 
 s3_client = boto3.client("s3")
diff --git a/java-sdk/build.gradle.kts b/java-sdk/build.gradle.kts
index 950f09db542..7a812bab0c4 100644
--- a/java-sdk/build.gradle.kts
+++ b/java-sdk/build.gradle.kts
@@ -33,6 +33,11 @@ allprojects {
 
     repositories { mavenCentral() }
 
+    // Keep these in sync:
+    // - jvmTarget, languageVersion, and sourceCompatibility in 
java-sdk/build.gradle.kts
+    // - TEMURIN_VERSION in scripts/docker/install_jdk.sh
+    // - JAVA_VERSION in .github/workflows/ci-amd.yml and 
.github/workflows/ci-arm.yml
+    // - java-version in .github/workflows/codeql-analysis.yml
     java {
         toolchain {
             languageVersion.set(JavaLanguageVersion.of(11))
@@ -41,7 +46,6 @@ allprojects {
     }
     kotlin {
         compilerOptions {
-            // If this is changed, also change "Setup Java" in 
codeql-analysis.yml.
             jvmTarget = JvmTarget.JVM_11
         }
     }
diff --git a/java-sdk/gradle.properties b/java-sdk/gradle.properties
index cab8c837412..7add0f666b8 100644
--- a/java-sdk/gradle.properties
+++ b/java-sdk/gradle.properties
@@ -18,3 +18,5 @@
 org.gradle.configuration-cache=true
 
 airflowSupervisorSchemaVersion=2026-06-16
+
+sdkVersion=1.0.0-alpha-1
diff --git a/java-sdk/sdk/build.gradle.kts b/java-sdk/sdk/build.gradle.kts
index 08fd4624d5f..a5acd27f9c1 100644
--- a/java-sdk/sdk/build.gradle.kts
+++ b/java-sdk/sdk/build.gradle.kts
@@ -24,6 +24,12 @@ buildscript {
 }
 
 val airflowSupervisorSchemaVersion: String by project
+val sdkVersion: String by project
+
+// Full Maven coordinate: org.apache.airflow:airflow-sdk:<version>
+group = "org.apache.airflow"
+version = sdkVersion
+base.archivesName.set("airflow-sdk")
 
 plugins {
     kotlin("plugin.serialization") version "2.3.0"
@@ -75,7 +81,11 @@ abstract class GeneratePointersTask : DefaultTask() {
     @TaskAction
     fun generate() {
         val srcFile = schemaFile.get().asFile
-        val outDir = targetDirectory.get().asFile.also { it.mkdirs() }
+        val outDir =
+            targetDirectory.get().asFile.also {
+                it.deleteRecursively()
+                it.mkdirs()
+            }
 
         srcFile.copyTo(outDir.resolve(srcFile.name), overwrite = true)
 
@@ -191,6 +201,7 @@ sourceSets {
 }
 
 dokka {
+    moduleVersion.set(sdkVersion)
     dokkaSourceSets.configureEach {
         // Suppress everything in 'execution' since it's implementation detail.
         perPackageOption {
@@ -216,6 +227,10 @@ tasks.named("runKtlintCheckOverMainSourceSet") {
     dependsOn("generateJsonSchema2Pojo")
 }
 
+tasks.matching { it.name.startsWith("dokkaGenerate") }.configureEach {
+    dependsOn("generateJsonSchema2Pojo", "generateDiscriminator")
+}
+
 tasks.withType<Jar> {
     manifest {
         attributes(
diff --git a/scripts/docker/entrypoint_ci.sh b/scripts/docker/entrypoint_ci.sh
index 18f2efbe673..cb995496ee1 100755
--- a/scripts/docker/entrypoint_ci.sh
+++ b/scripts/docker/entrypoint_ci.sh
@@ -143,6 +143,10 @@ function environment_initialization() {
         export AIRFLOW__SCHEDULER__GO_WORKER=True
     fi
 
+    if [[ ${INSTALL_SDK_JAVA=} == "true" ]]; then
+        "${AIRFLOW_SOURCES}/scripts/docker/install_jdk.sh"
+    fi
+
     RUN_TESTS=${RUN_TESTS:="false"}
     CI=${CI:="false"}
 
diff --git a/scripts/docker/install_jdk.sh b/scripts/docker/install_jdk.sh
new file mode 100755
index 00000000000..afe6eb3a69e
--- /dev/null
+++ b/scripts/docker/install_jdk.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+# 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.
+# shellcheck shell=bash
+# shellcheck source=scripts/docker/common.sh
+. "$( dirname "${BASH_SOURCE[0]}" )/common.sh"
+
+set -euo pipefail
+
+common::get_colors
+
+# Keep these in sync:
+# - jvmTarget, languageVersion, and sourceCompatibility in 
java-sdk/build.gradle.kts
+# - TEMURIN_VERSION in scripts/docker/install_jdk.sh
+# - JAVA_VERSION in .github/workflows/ci-amd.yml and 
.github/workflows/ci-arm.yml
+# - java-version in .github/workflows/codeql-analysis.yml
+readonly TEMURIN_VERSION="11"
+
+# Fast path: skip if the right JDK is already on PATH (e.g. repeated container 
starts
+# where the container image was not rebuilt between runs).
+if java -version 2>&1 | grep -q "version \"${TEMURIN_VERSION}"; then
+    echo
+    echo "${COLOR_BLUE}Eclipse Temurin JDK ${TEMURIN_VERSION} is already 
installed, skipping.${COLOR_RESET}"
+    echo
+    exit 0
+fi
+
+echo
+echo "${COLOR_BLUE}Installing Eclipse Temurin JDK ${TEMURIN_VERSION} from the 
Adoptium apt repository...${COLOR_RESET}"
+echo
+
+# Add the Adoptium apt repository (https://adoptium.net/installation/linux/).
+# The Breeze CI image runs as the 'airflow' user which has passwordless sudo.
+sudo apt-get update -qq
+sudo apt-get install -y --no-install-recommends wget gnupg apt-transport-https 
ca-certificates
+
+sudo mkdir -p /etc/apt/keyrings
+wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public \
+    | sudo tee /etc/apt/keyrings/adoptium.asc > /dev/null
+
+# Derive the Debian codename from /etc/os-release (bookworm, focal, etc.).
+# shellcheck source=/dev/null
+DISTRO_CODENAME=$(. /etc/os-release; echo "${VERSION_CODENAME}")
+echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] \
+https://packages.adoptium.net/artifactory/deb ${DISTRO_CODENAME} main" \
+    | sudo tee /etc/apt/sources.list.d/adoptium.list > /dev/null
+
+sudo apt-get update -qq
+sudo apt-get install -y --no-install-recommends 
"temurin-${TEMURIN_VERSION}-jdk"
+sudo apt-get clean
+sudo rm -rf /var/lib/apt/lists/*
+
+echo
+echo "${COLOR_GREEN}Eclipse Temurin JDK ${TEMURIN_VERSION} installed 
successfully.${COLOR_RESET}"
+java -version
+echo

Reply via email to