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

potiuk pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-1-test by this push:
     new d29f5323c00 [v3-1-test] Warn instead of failing on missing 3rd-party 
doc inventories (#63630) (#63646)
d29f5323c00 is described below

commit d29f5323c006770e9a650922955013d84a35b425
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sun Mar 15 21:08:01 2026 +0100

    [v3-1-test] Warn instead of failing on missing 3rd-party doc inventories 
(#63630) (#63646)
    
    * Warn instead of failing on missing 3rd-party doc inventories
    
    Third-party Sphinx intersphinx inventories (e.g., Pandas) are sometimes
    temporarily unavailable. Previously, any download failure terminated the
    entire doc build. Now missing 3rd-party inventories produce warnings and
    fall back to cached versions when available. A marker file is written for
    CI to detect missing inventories and send Slack notifications on canary
    builds. Publishing workflows fail by default but can opt out.
    
    - Add --fail-on-missing-third-party-inventories flag (default: off)
    - Add --clean-inventory-cache flag (--clean-build no longer deletes cache)
    - Cache inventories via stash action in CI and publish workflows
    - Send Slack warning on canary builds when inventories are missing
    
    * Add documentation for inventory cache handling options
    
    Document the new --clean-inventory-cache, 
--fail-on-missing-third-party-inventories,
    and --ignore-missing-inventories flags in the contributing docs, Breeze 
developer
    tasks, and release management docs.
    
    * Skip missing third-party inventories in intersphinx mapping
    
    When a third-party inventory file doesn't exist in the cache,
    skip it from the Sphinx intersphinx_mapping instead of referencing
    a non-existent file. This prevents Sphinx build errors when
    third-party inventory downloads fail.
    (cherry picked from commit afda438816b8e8cd43ef105630c8f33da8ec98b5)
---
 .github/workflows/ci-amd-arm.yml                   |  1 +
 .github/workflows/ci-image-checks.yml              | 40 +++++++++-
 contributing-docs/11_documentation_building.rst    | 25 ++++++-
 dev/breeze/doc/03_developer_tasks.rst              | 13 ++++
 dev/breeze/doc/09_release_management_tasks.rst     |  4 +
 dev/breeze/doc/images/output_build-docs.svg        | 86 +++++++++++++---------
 dev/breeze/doc/images/output_build-docs.txt        |  2 +-
 .../images/output_workflow-run_publish-docs.svg    | 22 ++++--
 .../images/output_workflow-run_publish-docs.txt    |  2 +-
 .../airflow_breeze/commands/developer_commands.py  | 26 ++++++-
 .../commands/developer_commands_config.py          |  7 +-
 .../airflow_breeze/commands/workflow_commands.py   |  7 ++
 .../commands/workflow_commands_config.py           |  6 ++
 .../src/airflow_breeze/params/doc_build_params.py  |  6 ++
 devel-common/src/docs/build_docs.py                | 32 ++++++--
 devel-common/src/docs/utils/conf_constants.py      | 31 +++++---
 .../sphinx_exts/docs_build/fetch_inventories.py    | 47 ++++++++----
 17 files changed, 280 insertions(+), 77 deletions(-)

diff --git a/.github/workflows/ci-amd-arm.yml b/.github/workflows/ci-amd-arm.yml
index 99dbeaf1532..0faa6f16b10 100644
--- a/.github/workflows/ci-amd-arm.yml
+++ b/.github/workflows/ci-amd-arm.yml
@@ -331,6 +331,7 @@ jobs:
     secrets:
       DOCS_AWS_ACCESS_KEY_ID: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }}
       DOCS_AWS_SECRET_ACCESS_KEY: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }}
+      SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
 
   providers:
     name: "provider distributions tests"
diff --git a/.github/workflows/ci-image-checks.yml 
b/.github/workflows/ci-image-checks.yml
index 7d23dce54a7..1e6c70e99f5 100644
--- a/.github/workflows/ci-image-checks.yml
+++ b/.github/workflows/ci-image-checks.yml
@@ -117,6 +117,8 @@ on:  # yamllint disable-line rule:truthy
         required: true
       DOCS_AWS_SECRET_ACCESS_KEY:
         required: true
+      SLACK_BOT_TOKEN:
+        required: false
 
 
 permissions:
@@ -252,23 +254,55 @@ jobs:
         uses: 
apache/infrastructure-actions/stash/restore@1c35b5ccf8fba5d4c3fdf25a045ca91aa0cbc468
         with:
           path: ./generated/_inventory_cache/
-          key: cache-docs-inventory-v1-${{ hashFiles('**/pyproject.toml') }}
+          key: cache-docs-inventory-v1
         id: restore-docs-inventory-cache
       - name: "Building docs with ${{ matrix.flag }} flag"
         env:
           DOCS_LIST_AS_STRING: ${{ inputs.docs-list-as-string }}
         run: >
           breeze build-docs ${DOCS_LIST_AS_STRING} ${{ matrix.flag }} 
--refresh-airflow-inventories
+      - name: "Check for missing third-party inventories"
+        id: check-missing-inventories
+        if: always()
+        shell: bash
+        run: |
+          
MARKER_FILE="./generated/_inventory_cache/.missing_third_party_inventories"
+          if [[ -f "${MARKER_FILE}" ]]; then
+            echo "missing=true" >> "${GITHUB_OUTPUT}"
+            echo "::warning::Missing third-party inventories:"
+            cat "${MARKER_FILE}"
+            echo "packages<<EOF" >> "${GITHUB_OUTPUT}"
+            cat "${MARKER_FILE}" >> "${GITHUB_OUTPUT}"
+            echo "EOF" >> "${GITHUB_OUTPUT}"
+          else
+            echo "missing=false" >> "${GITHUB_OUTPUT}"
+          fi
+      - name: "Notify Slack about missing inventories (canary only)"
+        if: >-
+          inputs.canary-run == 'true' &&
+          steps.check-missing-inventories.outputs.missing == 'true' &&
+          matrix.flag == '--docs-only'
+        uses: 
slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a  # v2.1.1
+        with:
+          method: chat.postMessage
+          token: ${{ env.SLACK_BOT_TOKEN }}
+          # yamllint disable rule:line-length
+          payload: |
+            channel: "internal-airflow-ci-cd"
+            text: "⚠️ Missing 3rd-party doc inventories in canary build on 
*${{ github.ref_name }}*\n\nPackages:\n${{ 
steps.check-missing-inventories.outputs.packages }}\n\n<https://github.com/${{ 
github.repository }}/actions/runs/${{ github.run_id }}|View build log>"
+          # yamllint enable rule:line-length
+        env:
+          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
       - name: "Save docs inventory cache"
         uses: 
apache/infrastructure-actions/stash/save@1c35b5ccf8fba5d4c3fdf25a045ca91aa0cbc468
         with:
           path: ./generated/_inventory_cache/
-          key: cache-docs-inventory-v1-${{ hashFiles('**/pyproject.toml') }}
+          key: cache-docs-inventory-v1
           if-no-files-found: 'error'
           retention-days: '2'
         # If we upload from multiple matrix jobs we could end up with a race 
condition. so just pick one job
         # to be responsible for updating it. 
https://github.com/actions/upload-artifact/issues/506
-        if: steps.restore-docs-inventory-cache != 'true' && matrix.flag == 
'--docs-only'
+        if: steps.restore-docs-inventory-cache.outputs.stash-hit != 'true' && 
matrix.flag == '--docs-only'
       - name: "Upload build docs"
         uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f 
 # v7.0.0
         with:
diff --git a/contributing-docs/11_documentation_building.rst 
b/contributing-docs/11_documentation_building.rst
index b7dfe3abf52..7ae771fd212 100644
--- a/contributing-docs/11_documentation_building.rst
+++ b/contributing-docs/11_documentation_building.rst
@@ -239,7 +239,30 @@ For example:
 
     breeze build-docs --doc-only --clean fab
 
-Will build ``fab`` provider documentation and clean inventories and other 
build artifacts before.
+Will build ``fab`` provider documentation and clean build artifacts before.
+
+Inventory cache handling
+........................
+
+When building documentation, Sphinx downloads intersphinx inventories from 
external sources (both Airflow
+packages hosted on S3 and third-party packages like Pandas, SQLAlchemy, etc.). 
These inventories enable
+cross-references between documentation sets.
+
+By default, missing third-party inventories produce warnings but do **not** 
fail the build. This is
+because third-party inventory servers can be temporarily unavailable and 
should not block documentation
+builds. If a cached version of the inventory exists, it will be used instead.
+
+The following flags control inventory behavior:
+
+- ``--clean-inventory-cache`` — deletes the inventory cache before fetching. 
Use this when you want
+  to force a completely fresh download of all inventories.
+- ``--clean-build`` — cleans build artifacts (``_build``, ``_doctrees``, 
``apis``) but does **not**
+  delete the inventory cache. This allows rebuilding docs from scratch while 
preserving cached
+  inventories.
+- ``--refresh-airflow-inventories`` — forces a refresh of only Airflow package 
inventories, without
+  cleaning build artifacts or external inventories.
+- ``--fail-on-missing-third-party-inventories`` — fails the build if any 
third-party inventory cannot
+  be downloaded (useful for publishing workflows where complete 
cross-references are important).
 
 You can also use ``breeze build-docs --help`` to see available options and 
head to
 `breeze documentation <../dev/breeze/doc/03_developer_tasks.rst>`__ to learn 
more about the ``breeze``
diff --git a/dev/breeze/doc/03_developer_tasks.rst 
b/dev/breeze/doc/03_developer_tasks.rst
index b61aa6a17da..0c519001803 100644
--- a/dev/breeze/doc/03_developer_tasks.rst
+++ b/dev/breeze/doc/03_developer_tasks.rst
@@ -278,6 +278,19 @@ package names and can be used to select more than one 
package with single filter
 
      breeze build-docs --package-filter apache-airflow-providers-*
 
+Inventory cache handling
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+When building documentation, Sphinx downloads intersphinx inventories to 
enable cross-references
+between documentation sets. By default, missing third-party inventories (e.g., 
Pandas, SQLAlchemy)
+produce warnings but do **not** fail the build — third-party servers can be 
temporarily unavailable.
+If a cached version exists, it will be used with a warning.
+
+Use ``--clean-inventory-cache`` to force a fresh download of all inventories, 
or
+``--fail-on-missing-third-party-inventories`` to fail the build when any 
third-party inventory
+is missing (useful for publishing). Note that ``--clean-build`` cleans build 
artifacts but
+preserves the inventory cache.
+
 Often errors during documentation generation come from the docstrings of 
auto-api generated classes.
 During the docs building auto-api generated files are stored in the 
``generated`` folder. This helps you
 easily identify the location the problems with documentation originated from.
diff --git a/dev/breeze/doc/09_release_management_tasks.rst 
b/dev/breeze/doc/09_release_management_tasks.rst
index 3d3108c6df2..372c9978f3e 100644
--- a/dev/breeze/doc/09_release_management_tasks.rst
+++ b/dev/breeze/doc/09_release_management_tasks.rst
@@ -933,6 +933,10 @@ These are all available flags of ``workflow-run`` command:
 ``--site-env`` specifies the environment to use for the site (e.g., auto, 
live, staging). the default is auto, based on the ref it decides live or 
staging.
 ``--refresh-site`` specifies whether to refresh the site after publishing the 
documentation. This triggers workflow on apache/airflow-site repository to 
refresh the site.
 ``--skip-write-to-stable-folder`` specifies the documentation packages to skip 
writing to the stable folder.
+``--ignore-missing-inventories`` when set, the publish workflow will not fail 
if third-party intersphinx
+inventories cannot be downloaded. By default, the publish workflow fails on 
missing inventories to ensure
+complete cross-references in published documentation. Use this flag only when 
you need to publish despite
+temporary third-party inventory outages.
 
 
 These are all available flags of ``workflow-run publish-docs`` command:
diff --git a/dev/breeze/doc/images/output_build-docs.svg 
b/dev/breeze/doc/images/output_build-docs.svg
index ee242c74903..cd1ec59a584 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 1392.0" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 1514.0" 
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="1341.0" />
+      <rect x="0" y="0" width="1463.0" height="1463.0" />
     </clipPath>
     <clipPath id="breeze-build-docs-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -207,9 +207,24 @@
 <clipPath id="breeze-build-docs-line-53">
     <rect x="0" y="1294.7" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-build-docs-line-54">
+    <rect x="0" y="1319.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-build-docs-line-55">
+    <rect x="0" y="1343.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-build-docs-line-56">
+    <rect x="0" y="1367.9" width="1464" height="24.65"/>
+            </clipPath>
+<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>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="1390" 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="1512" 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"/>
@@ -244,36 +259,41 @@
 </text><text class="breeze-build-docs-r5" x="0" y="556.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-22)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="556.8" textLength="183" 
clip-path="url(#breeze-build-docs-line-22)">--one-pass-only</text><text 
class="breeze-build-docs-r1" x="256.2" y="556.8" textLength="1000.4" 
clip-path="url(#breeze-build-docs-line-22)">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="581.2" textLength="1464" 
clip-path="url(#breeze-build-docs-line-23)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="581.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-23)">
 </text><text class="breeze-build-docs-r5" x="0" y="605.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-24)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="605.6" textLength="268.4" 
clip-path="url(#breeze-build-docs-line-24)">&#160;Cleaning&#160;inventories&#160;</text><text
 class="breeze-build-docs-r5" x="292.8" y="605.6" textLength="1146.8" 
clip-path="url(#breeze-build-docs-line-24)">───────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="630" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-25)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="630" textLength="158.6" 
clip-path="url(#breeze-build-docs-line-25)">--clean-build</text><text 
class="breeze-build-docs-r1" x="427" y="630" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-25)">Cleans&#160;the&#160;build&#160;directory&#160;before&#160;building&#160;the&#160;documentation&#160;and&#160;remove
 [...]
-</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-r1" x="427" y="654.4" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-26)">inventory&#160;cache&#160;(including&#160;external&#160;inventories).&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16
 [...]
-</text><text class="breeze-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="353.8" 
clip-path="url(#breeze-build-docs-line-27)">--refresh-airflow-inventories</text><text
 class="breeze-build-docs-r1" x="427" y="678.8" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-27)">When&#160;set,&#160;only&#160;airflow&#160;package&#160;inventories&#160;will&#160;be&#160;ref
 [...]
-</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="427" y="703.2" textLength="366" 
clip-path="url(#breeze-build-docs-line-28)">are&#160;already&#160;downloaded.&#160;With&#160;`</text><text
 class="breeze-build-docs-r4" x="793" y="703.2" textLength="158.6" 
clip-path="url(#breeze-build-docs-line-28)">--clean-build</text><text 
class="breeze-build-docs-r1" x="951.6" y="703.2" te [...]
-</text><text class="breeze-build-docs-r5" x="0" y="727.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-29)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="727.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-29)">
-</text><text class="breeze-build-docs-r5" x="0" y="752" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-30)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="752" textLength="231.8" 
clip-path="url(#breeze-build-docs-line-30)">&#160;Filtering&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="256.2" y="752" textLength="1183.4" 
clip-path="url(#breeze-build-docs-line-30)">────────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</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-r4" x="24.4" y="776.4" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-31)">--package-filter</text><text 
class="breeze-build-docs-r1" x="427" y="776.4" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-31)">Filter(s)&#160;to&#160;use&#160;more&#160;than&#160;one&#160;can&#160;be&#160;specified.&#160;You&#160;can&
 [...]
-</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="427" y="800.8" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-32)">the&#160;full&#160;package&#160;name,&#160;for&#160;example&#160;`apache-airflow-providers-*`.&#160;Useful&#160;when&#160;you&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="800.8" textLength="12.2" 
clip-path="url(#breeze- [...]
-</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="427" y="825.2" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-33)">want&#160;to&#160;selectseveral&#160;similarly&#160;named&#160;packages&#160;together.&#160;&#160;&#160;&#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="849.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-34)">│</text><text 
class="breeze-build-docs-r7" x="427" y="849.6" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-34)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
-</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-r4" x="24.4" y="874" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-35)">--include-not-ready-providers</text><text
 class="breeze-build-docs-r1" x="427" y="874" textLength="817.4" 
clip-path="url(#breeze-build-docs-line-35)">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="898.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-36)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="898.4" textLength="329.4" 
clip-path="url(#breeze-build-docs-line-36)">--include-removed-providers</text><text
 class="breeze-build-docs-r1" x="427" y="898.4" textLength="561.2" 
clip-path="url(#breeze-build-docs-line-36)">Whether&#160;to&#160;include&#160;providers&#160;that&#160;are&#160;removed.</text><text
 class="b [...]
-</text><text class="breeze-build-docs-r5" x="0" y="922.8" textLength="1464" 
clip-path="url(#breeze-build-docs-line-37)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="922.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-37)">
-</text><text class="breeze-build-docs-r5" x="0" y="947.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-38)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="947.2" textLength="170.8" 
clip-path="url(#breeze-build-docs-line-38)">&#160;Misc&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="195.2" y="947.2" textLength="1244.4" 
clip-path="url(#breeze-build-docs-line-38)">───────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</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="207.4" 
clip-path="url(#breeze-build-docs-line-39)">--include-commits</text><text 
class="breeze-build-docs-r1" x="341.6" y="971.6" textLength="451.4" 
clip-path="url(#breeze-build-docs-line-39)">Include&#160;commits&#160;in&#160;the&#160;documentation.</text><text
 class="breeze-build-docs-r5" x="145 [...]
-</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="231.8" 
clip-path="url(#breeze-build-docs-line-40)">--github-repository</text><text 
class="breeze-build-docs-r6" x="292.8" y="996" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-40)">-g</text><text 
class="breeze-build-docs-r1" x="341.6" y="996" textLength="585.6" 
clip-path="url(#breeze-build- [...]
-</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="109.8" 
clip-path="url(#breeze-build-docs-line-41)">--builder</text><text 
class="breeze-build-docs-r1" x="341.6" y="1020.4" textLength="756.4" 
clip-path="url(#breeze-build-docs-line-41)">Buildx&#160;builder&#160;used&#160;to&#160;perform&#160;`docker&#160;buildx&#160;build`&#160;commands.</text><
 [...]
-</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-r5" x="341.6" y="1044.8" textLength="756.4" 
clip-path="url(#breeze-build-docs-line-42)">[default:&#160;autodetect]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
-</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="244" 
clip-path="url(#breeze-build-docs-line-43)">--distributions-list</text><text 
class="breeze-build-docs-r1" x="341.6" y="1069.2" textLength="1098" 
clip-path="url(#breeze-build-docs-line-43)">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="1093.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-44)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1093.6" textLength="1098" 
clip-path="url(#breeze-build-docs-line-44)">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="1093.6" textLength="12.2 [...]
-</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-r1" x="341.6" y="1118" textLength="1098" 
clip-path="url(#breeze-build-docs-line-45)">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="1118" textLength="12.2" clip-path 
[...]
-</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-r1" x="341.6" y="1142.4" textLength="1098" 
clip-path="url(#breeze-build-docs-line-46)">arguments.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#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="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="1098" 
clip-path="url(#breeze-build-docs-line-47)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1191.2" textLength="1464" 
clip-path="url(#breeze-build-docs-line-48)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1191.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-48)">
-</text><text class="breeze-build-docs-r5" x="0" y="1215.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-49)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1215.6" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-49)">&#160;Common&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="219.6" y="1215.6" textLength="1220" 
clip-path="url(#breeze-build-docs-line-49)">────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</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="109.8" 
clip-path="url(#breeze-build-docs-line-50)">--dry-run</text><text 
class="breeze-build-docs-r6" x="158.6" y="1240" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-50)">-D</text><text 
class="breeze-build-docs-r1" x="207.4" y="1240" textLength="719.8" 
clip-path="url(#breeze-build-docs-l [...]
-</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-r4" x="24.4" y="1264.4" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-51)">--verbose</text><text 
class="breeze-build-docs-r6" x="158.6" y="1264.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-51)">-v</text><text 
class="breeze-build-docs-r1" x="207.4" y="1264.4" textLength="585.6" 
clip-path="url(#breeze-buil [...]
-</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-r4" x="24.4" y="1288.8" textLength="97.6" 
clip-path="url(#breeze-build-docs-line-52)">--answer</text><text 
class="breeze-build-docs-r6" x="158.6" y="1288.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-52)">-a</text><text 
class="breeze-build-docs-r1" x="207.4" y="1288.8" textLength="317.2" 
clip-path="url(#breeze-build- [...]
-</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-r4" x="24.4" y="1313.2" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-53)">--help</text><text 
class="breeze-build-docs-r6" x="158.6" y="1313.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-53)">-h</text><text 
class="breeze-build-docs-r1" x="207.4" y="1313.2" textLength="329.4" 
clip-path="url(#breeze-build-do [...]
-</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="630" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-25)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="630" textLength="158.6" 
clip-path="url(#breeze-build-docs-line-25)">--clean-build</text><text 
class="breeze-build-docs-r1" x="573.4" y="630" textLength="866.2" 
clip-path="url(#breeze-build-docs-line-25)">Cleans&#160;the&#160;build&#160;directory&#160;before&#160;building&#160;the&#160;documentation.&#160;Does&#160;not
 [...]
+</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-r1" x="573.4" y="654.4" textLength="341.6" 
clip-path="url(#breeze-build-docs-line-26)">delete&#160;inventory&#160;cache&#160;(use&#160;</text><text
 class="breeze-build-docs-r4" x="915" y="654.4" textLength="280.6" 
clip-path="url(#breeze-build-docs-line-26)">--clean-inventory-cache</text><text 
class="breeze-build-docs-r1" x="1195.6" [...]
+</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="280.6" 
clip-path="url(#breeze-build-docs-line-27)">--clean-inventory-cache</text><text 
class="breeze-build-docs-r1" x="573.4" y="678.8" textLength="671" 
clip-path="url(#breeze-build-docs-line-27)">Cleans&#160;the&#160;inventory&#160;cache&#160;before&#160;fetching&#160;inventories.</text><text
 cla [...]
+</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="353.8" 
clip-path="url(#breeze-build-docs-line-28)">--refresh-airflow-inventories</text><text
 class="breeze-build-docs-r1" x="573.4" y="703.2" textLength="866.2" 
clip-path="url(#breeze-build-docs-line-28)">When&#160;set,&#160;only&#160;airflow&#160;package&#160;inventories&#160;will&#160;be&#160;re
 [...]
+</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-r1" x="573.4" y="727.6" textLength="597.8" 
clip-path="url(#breeze-build-docs-line-29)">regardless&#160;if&#160;they&#160;are&#160;already&#160;downloaded.&#160;With&#160;`</text><text
 class="breeze-build-docs-r4" x="1171.2" y="727.6" textLength="158.6" 
clip-path="url(#breeze-build-docs-line-29)">--clean-build</text><text 
class="bre [...]
+</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="573.4" y="752" textLength="866.2" 
clip-path="url(#breeze-build-docs-line-30)">everything&#160;is&#160;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;&
 [...]
+</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-r4" x="24.4" y="776.4" textLength="500.2" 
clip-path="url(#breeze-build-docs-line-31)">--fail-on-missing-third-party-inventories</text><text
 class="breeze-build-docs-r1" x="573.4" y="776.4" textLength="866.2" 
clip-path="url(#breeze-build-docs-line-31)">Fail&#160;the&#160;build&#160;if&#160;any&#160;third-party&#160;inventory&#160;ca
 [...]
+</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="573.4" y="800.8" textLength="866.2" 
clip-path="url(#breeze-build-docs-line-32)">default,&#160;missing&#160;third-party&#160;inventories&#160;are&#160;warned&#160;about&#160;but&#160;do&#160;not&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="800.8" textLength="12.2" 
clip-path="url(#breeze-build-docs- [...]
+</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="573.4" y="825.2" textLength="866.2" 
clip-path="url(#breeze-build-docs-line-33)">fail&#160;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
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="849.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-34)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" 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="24.4" 
clip-path="url(#breeze-build-docs-line-35)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="874" textLength="231.8" 
clip-path="url(#breeze-build-docs-line-35)">&#160;Filtering&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="256.2" y="874" textLength="1183.4" 
clip-path="url(#breeze-build-docs-line-35)">────────────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="898.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-36)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="898.4" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-36)">--package-filter</text><text 
class="breeze-build-docs-r1" x="427" y="898.4" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-36)">Filter(s)&#160;to&#160;use&#160;more&#160;than&#160;one&#160;can&#160;be&#160;specified.&#160;You&#160;can&
 [...]
+</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-r1" x="427" y="922.8" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-37)">the&#160;full&#160;package&#160;name,&#160;for&#160;example&#160;`apache-airflow-providers-*`.&#160;Useful&#160;when&#160;you&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="922.8" textLength="12.2" 
clip-path="url(#breeze- [...]
+</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="427" y="947.2" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-38)">want&#160;to&#160;selectseveral&#160;similarly&#160;named&#160;packages&#160;together.&#160;&#160;&#160;&#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="971.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-39)">│</text><text 
class="breeze-build-docs-r7" x="427" y="971.6" textLength="1012.6" 
clip-path="url(#breeze-build-docs-line-39)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&
 [...]
+</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="427" 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="329.4" 
clip-path="url(#breeze-build-docs-line-41)">--include-removed-providers</text><text
 class="breeze-build-docs-r1" x="427" 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.</text><text
 class [...]
+</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="207.4" 
clip-path="url(#breeze-build-docs-line-44)">--include-commits</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-build-docs-r5" x=" [...]
+</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="231.8" 
clip-path="url(#breeze-build-docs-line-45)">--github-repository</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="585.6" 
clip-path="url(#breeze-bu [...]
+</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="109.8" 
clip-path="url(#breeze-build-docs-line-46)">--builder</text><text 
class="breeze-build-docs-r1" x="341.6" y="1142.4" textLength="756.4" 
clip-path="url(#breeze-build-docs-line-46)">Buildx&#160;builder&#160;used&#160;to&#160;perform&#160;`docker&#160;buildx&#160;build`&#160;commands.</text><
 [...]
+</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-r5" x="341.6" y="1166.8" textLength="756.4" 
clip-path="url(#breeze-build-docs-line-47)">[default:&#160;autodetect]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
+</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="1098" 
clip-path="url(#breeze-build-docs-line-51)">arguments.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#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="1288.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-52)">│</text><text 
class="breeze-build-docs-r7" x="341.6" y="1288.8" textLength="1098" 
clip-path="url(#breeze-build-docs-line-52)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1313.2" textLength="1464" 
clip-path="url(#breeze-build-docs-line-53)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1313.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-53)">
+</text><text class="breeze-build-docs-r5" x="0" y="1337.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-54)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1337.6" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-54)">&#160;Common&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="219.6" y="1337.6" textLength="1220" 
clip-path="url(#breeze-build-docs-line-54)">────────────────────────────────────────────────────────────────────────────────────────
 [...]
+</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)">--dry-run</text><text 
class="breeze-build-docs-r6" x="158.6" y="1362" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-55)">-D</text><text 
class="breeze-build-docs-r1" x="207.4" y="1362" textLength="719.8" 
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)">--verbose</text><text 
class="breeze-build-docs-r6" x="158.6" y="1386.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-56)">-v</text><text 
class="breeze-build-docs-r1" x="207.4" y="1386.4" textLength="585.6" 
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="97.6" 
clip-path="url(#breeze-build-docs-line-57)">--answer</text><text 
class="breeze-build-docs-r6" x="158.6" y="1410.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-57)">-a</text><text 
class="breeze-build-docs-r1" x="207.4" y="1410.8" textLength="317.2" 
clip-path="url(#breeze-build- [...]
+</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="73.2" 
clip-path="url(#breeze-build-docs-line-58)">--help</text><text 
class="breeze-build-docs-r6" x="158.6" y="1435.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-58)">-h</text><text 
class="breeze-build-docs-r1" x="207.4" y="1435.2" textLength="329.4" 
clip-path="url(#breeze-build-do [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1459.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-59)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1459.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-59)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_build-docs.txt 
b/dev/breeze/doc/images/output_build-docs.txt
index 7c465674b0f..ed2b111ec6b 100644
--- a/dev/breeze/doc/images/output_build-docs.txt
+++ b/dev/breeze/doc/images/output_build-docs.txt
@@ -1 +1 @@
-e85cc9911cbd648287a9b2b6e4291edd
+719d34813661417c2c648ac0eaa7db58
diff --git a/dev/breeze/doc/images/output_workflow-run_publish-docs.svg 
b/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
index 147181e423c..11d1d3e6d81 100644
--- a/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
+++ b/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 1148.0" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 1221.1999999999998" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -45,7 +45,7 @@
 
     <defs>
     <clipPath id="breeze-workflow-run-publish-docs-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="1097.0" />
+      <rect x="0" y="0" width="1463.0" height="1170.1999999999998" />
     </clipPath>
     <clipPath id="breeze-workflow-run-publish-docs-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -179,9 +179,18 @@
 <clipPath id="breeze-workflow-run-publish-docs-line-43">
     <rect x="0" y="1050.7" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-44">
+    <rect x="0" y="1075.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-45">
+    <rect x="0" y="1099.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-46">
+    <rect x="0" y="1123.9" 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="1146" rx="8"/><text 
class="breeze-workflow-run-publish-docs-title" fill="#c5c8c6" 
text-anchor="middle" x="740" 
y="27">Command:&#160;workflow-run&#160;publish-docs</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="1219.2" rx="8"/><text 
class="breeze-workflow-run-publish-docs-title" fill="#c5c8c6" 
text-anchor="middle" x="740" 
y="27">Command:&#160;workflow-run&#160;publish-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"/>
@@ -233,9 +242,12 @@
 </text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="971.6" 
textLength="12.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-39)">│</text><text 
class="breeze-workflow-run-publish-docs-r4" x="24.4" y="971.6" textLength="122" 
clip-path="url(#breeze-workflow-run-publish-docs-line-39)">--site-env</text><text
 class="breeze-workflow-run-publish-docs-r1" x="427" y="971.6" textLength="671" 
clip-path="url(#breeze-workflow-run-publish-docs-line-39)">S3&#160;bucket&#160;to&#160;
 [...]
 </text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="996" 
textLength="12.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-40)">│</text><text 
class="breeze-workflow-run-publish-docs-r4" x="24.4" y="996" textLength="353.8" 
clip-path="url(#breeze-workflow-run-publish-docs-line-40)">--skip-write-to-stable-folder</text><text
 class="breeze-workflow-run-publish-docs-r1" x="427" y="996" textLength="366" 
clip-path="url(#breeze-workflow-run-publish-docs-line-40)">Skip&#160;wri [...]
 </text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1020.4" 
textLength="1464" 
clip-path="url(#breeze-workflow-run-publish-docs-line-41)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-workflow-run-publish-docs-r1" x="1464" y="1020.4" 
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-41)">
-</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1044.8" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-42)">╭─</text><text 
class="breeze-workflow-run-publish-docs-r5" x="24.4" y="1044.8" 
textLength="195.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-42)">&#160;Common&#160;options&#160;</text><text
 class="breeze-workflow-run-publish-docs-r5" x="219.6" y="1044.8" 
textLength="1220" clip-path="url(#breeze-workflow-run-publish-docs-line-42) 
[...]
-</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1069.2" 
textLength="12.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-43)">│</text><text 
class="breeze-workflow-run-publish-docs-r4" x="24.4" y="1069.2" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-43)">--help</text><text 
class="breeze-workflow-run-publish-docs-r9" x="122" y="1069.2" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-43)">-h</text><text 
class="breez [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1044.8" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-42)">╭─</text><text 
class="breeze-workflow-run-publish-docs-r5" x="24.4" y="1044.8" 
textLength="244" 
clip-path="url(#breeze-workflow-run-publish-docs-line-42)">&#160;Inventory&#160;handling&#160;</text><text
 class="breeze-workflow-run-publish-docs-r5" x="268.4" y="1044.8" 
textLength="1171.2" clip-path="url(#breeze-workflow-run-publish-docs-line [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1069.2" 
textLength="12.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-43)">│</text><text 
class="breeze-workflow-run-publish-docs-r4" x="24.4" y="1069.2" 
textLength="341.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-43)">--ignore-missing-inventories</text><text
 class="breeze-workflow-run-publish-docs-r1" x="414.8" y="1069.2" 
textLength="695.4" clip-path="url(#breeze-workflow-run-publish-docs-line-43)">D 
[...]
 </text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1093.6" 
textLength="1464" 
clip-path="url(#breeze-workflow-run-publish-docs-line-44)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-workflow-run-publish-docs-r1" x="1464" y="1093.6" 
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-44)">
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1118" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-45)">╭─</text><text 
class="breeze-workflow-run-publish-docs-r5" x="24.4" y="1118" 
textLength="195.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-45)">&#160;Common&#160;options&#160;</text><text
 class="breeze-workflow-run-publish-docs-r5" x="219.6" y="1118" 
textLength="1220" 
clip-path="url(#breeze-workflow-run-publish-docs-line-45)">──── [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1142.4" 
textLength="12.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-46)">│</text><text 
class="breeze-workflow-run-publish-docs-r4" x="24.4" y="1142.4" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-46)">--help</text><text 
class="breeze-workflow-run-publish-docs-r9" x="122" y="1142.4" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-46)">-h</text><text 
class="breez [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="1166.8" 
textLength="1464" 
clip-path="url(#breeze-workflow-run-publish-docs-line-47)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-workflow-run-publish-docs-r1" x="1464" y="1166.8" 
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-47)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_workflow-run_publish-docs.txt 
b/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
index 766844968d5..c8da55705d4 100644
--- a/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
+++ b/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
@@ -1 +1 @@
-cbc65829535f05db7d7cf55869ccbed1
+298d50352dfbd1d30944bd0b45d497ea
diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py 
b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
index a32cf74ec2a..cb763cc9762 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
@@ -728,8 +728,13 @@ def start_airflow(
 @click.option(
     "--clean-build",
     is_flag=True,
-    help="Cleans the build directory before building the documentation and 
removes all inventory "
-    "cache (including external inventories).",
+    help="Cleans the build directory before building the documentation. "
+    "Does not delete inventory cache (use --clean-inventory-cache for that).",
+)
[email protected](
+    "--clean-inventory-cache",
+    is_flag=True,
+    help="Cleans the inventory cache before fetching inventories.",
 )
 @click.option(
     "--refresh-airflow-inventories",
@@ -737,6 +742,12 @@ def start_airflow(
     help="When set, only airflow package inventories will be refreshed, 
regardless "
     "if they are already downloaded. With `--clean-build` - everything is 
cleaned..",
 )
[email protected](
+    "--fail-on-missing-third-party-inventories",
+    is_flag=True,
+    help="Fail the build if any third-party inventory cannot be downloaded. "
+    "By default, missing third-party inventories are warned about but do not 
fail the build.",
+)
 @click.option("-d", "--docs-only", help="Only build documentation.", 
is_flag=True)
 @click.option(
     "--include-commits", help="Include commits in the documentation.", 
is_flag=True, envvar="INCLUDE_COMMITS"
@@ -773,7 +784,9 @@ def start_airflow(
 def build_docs(
     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,
@@ -798,7 +811,7 @@ def build_docs(
     )
     rebuild_or_pull_ci_image_if_needed(command_params=build_params)
     if clean_build:
-        directories_to_clean = ["_build", "_doctrees", "_inventory_cache", 
"apis"]
+        directories_to_clean = ["_build", "_doctrees", "apis"]
     else:
         directories_to_clean = ["apis"]
     generated_path = AIRFLOW_ROOT_PATH / "generated"
@@ -807,6 +820,11 @@ def build_docs(
         for directory in generated_path.rglob(dir_name):
             get_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():
+            get_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:
         get_console().print("Removing airflow inventories.")
         package_globs = ["helm-chart", "docker-stack", "apache-airflow*"]
@@ -834,6 +852,8 @@ def build_docs(
         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,
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 aee23d9c248..a0d06a5dece 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
@@ -354,7 +354,12 @@ DEVELOPER_PARAMETERS: dict[str, list[dict[str, str | 
list[str]]]] = {
         },
         {
             "name": "Cleaning inventories",
-            "options": ["--clean-build", "--refresh-airflow-inventories"],
+            "options": [
+                "--clean-build",
+                "--clean-inventory-cache",
+                "--refresh-airflow-inventories",
+                "--fail-on-missing-third-party-inventories",
+            ],
         },
         {
             "name": "Filtering options",
diff --git a/dev/breeze/src/airflow_breeze/commands/workflow_commands.py 
b/dev/breeze/src/airflow_breeze/commands/workflow_commands.py
index b1ff6ffd3d7..22f763b159c 100644
--- a/dev/breeze/src/airflow_breeze/commands/workflow_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/workflow_commands.py
@@ -102,6 +102,11 @@ def workflow_run_group():
     default="main",
     type=str,
 )
[email protected](
+    "--ignore-missing-inventories",
+    help="Do not fail the build on missing third-party inventories.",
+    is_flag=True,
+)
 @argument_doc_packages
 def workflow_run_publish(
     ref: str,
@@ -114,6 +119,7 @@ def workflow_run_publish(
     airflow_base_version: str | None = None,
     apply_commits: str | None = None,
     workflow_branch: str = "main",
+    ignore_missing_inventories: bool = False,
 ):
     if len(doc_packages) == 0:
         get_console().print(
@@ -191,6 +197,7 @@ def workflow_run_publish(
         "skip-write-to-stable-folder": skip_write_to_stable_folder,
         "build-sboms": "true" if "apache-airflow" in doc_packages else "false",
         "apply-commits": apply_commits if apply_commits else "",
+        "ignore-missing-inventories": str(ignore_missing_inventories).lower(),
     }
 
     if airflow_version:
diff --git a/dev/breeze/src/airflow_breeze/commands/workflow_commands_config.py 
b/dev/breeze/src/airflow_breeze/commands/workflow_commands_config.py
index 2856e722ae4..239a5e46a6a 100644
--- a/dev/breeze/src/airflow_breeze/commands/workflow_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/workflow_commands_config.py
@@ -47,5 +47,11 @@ WORKFLOW_RUN_PARAMETERS: dict[str, list[dict[str, str | 
list[str]]]] = {
                 "--skip-write-to-stable-folder",
             ],
         },
+        {
+            "name": "Inventory handling",
+            "options": [
+                "--ignore-missing-inventories",
+            ],
+        },
     ],
 }
diff --git a/dev/breeze/src/airflow_breeze/params/doc_build_params.py 
b/dev/breeze/src/airflow_breeze/params/doc_build_params.py
index eb0100a3359..fc5e1df9674 100644
--- a/dev/breeze/src/airflow_breeze/params/doc_build_params.py
+++ b/dev/breeze/src/airflow_breeze/params/doc_build_params.py
@@ -30,6 +30,8 @@ class DocBuildParams:
     short_doc_packages: tuple[str, ...]
     one_pass_only: bool = False
     include_commits: bool = False
+    fail_on_missing_third_party_inventories: bool = False
+    clean_inventory_cache: bool = False
     github_actions = os.environ.get("GITHUB_ACTIONS", "false")
 
     @property
@@ -43,6 +45,10 @@ class DocBuildParams:
             doc_args.append("--one-pass-only")
         if self.include_commits:
             doc_args.append("--include-commits")
+        if self.fail_on_missing_third_party_inventories:
+            doc_args.append("--fail-on-missing-third-party-inventories")
+        if self.clean_inventory_cache:
+            doc_args.append("--clean-inventory-cache")
         if self.package_filter:
             for filter in self.package_filter:
                 doc_args.extend(["--package-filter", filter])
diff --git a/devel-common/src/docs/build_docs.py 
b/devel-common/src/docs/build_docs.py
index a504669a4ce..001541bbe5b 100755
--- a/devel-common/src/docs/build_docs.py
+++ b/devel-common/src/docs/build_docs.py
@@ -135,8 +135,9 @@ def _promote_new_flags():
     console.print()
     console.print("You can run clean build - refreshing inter-sphinx 
inventories or refresh airflow ones.\n")
     console.print(
-        "   [bright_blue]--clean-build                 - Refresh inventories 
and build files for all inter-sphinx references (including external ones)[/]"
+        "   [bright_blue]--clean-build                 - Clean build files 
(without cleaning inventory cache)[/]"
     )
+    console.print("   [bright_blue]--clean-inventory-cache        - Clean 
inventory cache before fetching[/]")
     console.print(
         "   [bright_blue]--refresh-airflow-inventories - Force refresh only 
airflow inventories (without cleaning build files or external inventories).[/]"
     )
@@ -464,7 +465,12 @@ click.rich_click.OPTION_GROUPS = {
         },
         {
             "name": "Cleaning inventories",
-            "options": ["--clean-build", "--refresh-airflow-inventories"],
+            "options": [
+                "--clean-build",
+                "--clean-inventory-cache",
+                "--refresh-airflow-inventories",
+                "--fail-on-missing-third-party-inventories",
+            ],
         },
         {
             "name": "Filtering options",
@@ -527,8 +533,13 @@ click.rich_click.OPTION_GROUPS = {
 @click.option(
     "--clean-build",
     is_flag=True,
-    help="Cleans the build directory before building the documentation and 
removes all inventory "
-    "cache (including external inventories).",
+    help="Cleans the build directory before building the documentation. "
+    "Does not delete inventory cache (use --clean-inventory-cache for that).",
+)
[email protected](
+    "--clean-inventory-cache",
+    is_flag=True,
+    help="Cleans the inventory cache before fetching inventories.",
 )
 @click.option(
     "--refresh-airflow-inventories",
@@ -536,6 +547,12 @@ click.rich_click.OPTION_GROUPS = {
     help="When set, only airflow package inventories will be refreshed, 
regardless "
     "if they are already downloaded. With `--clean-build` - everything is 
cleaned..",
 )
[email protected](
+    "--fail-on-missing-third-party-inventories",
+    is_flag=True,
+    help="Fail the build if any third-party inventory cannot be downloaded. "
+    "By default, missing third-party inventories are warned about but do not 
fail the build.",
+)
 @click.option(
     "-v",
     "--verbose",
@@ -553,12 +570,14 @@ def build_docs(
     one_pass_only,
     package_filters,
     clean_build,
+    clean_inventory_cache,
     docs_only,
     spellcheck_only,
     include_commits,
     jobs,
     list_packages,
     refresh_airflow_inventories,
+    fail_on_missing_third_party_inventories,
     verbose,
     packages,
 ):
@@ -602,7 +621,10 @@ def build_docs(
         # Inventories that could not be retrieved should be built first. This 
may mean this is a
         # new package.
         packages_without_inventories = fetch_inventories(
-            clean_build=clean_build, 
refresh_airflow_inventories=refresh_airflow_inventories
+            clean_build=clean_build,
+            refresh_airflow_inventories=refresh_airflow_inventories,
+            
fail_on_missing_third_party=fail_on_missing_third_party_inventories,
+            clean_inventory_cache=clean_inventory_cache,
         )
     normal_packages, priority_packages = partition(
         lambda d: d in packages_without_inventories, packages_to_build
diff --git a/devel-common/src/docs/utils/conf_constants.py 
b/devel-common/src/docs/utils/conf_constants.py
index 4b5fd30a760..4eb6e2467f6 100644
--- a/devel-common/src/docs/utils/conf_constants.py
+++ b/devel-common/src/docs/utils/conf_constants.py
@@ -273,10 +273,23 @@ def get_autodoc_mock_imports() -> list[str]:
     ]
 
 
+def _get_third_party_mapping(pkg_names: list[str]) -> dict[str, tuple[str, 
tuple[str]]]:
+    """Build intersphinx mapping for third-party packages, skipping those 
without cached inventories."""
+    mapping: dict[str, tuple[str, tuple[str]]] = {}
+    for pkg_name in pkg_names:
+        inv_path = INVENTORY_CACHE_DIR / pkg_name / "objects.inv"
+        if not inv_path.exists():
+            continue
+        mapping[pkg_name] = (
+            f"{THIRD_PARTY_INDEXES[pkg_name]}/",
+            (str(inv_path),),
+        )
+    return mapping
+
+
 def get_intersphinx_mapping() -> dict[str, tuple[str, tuple[str]]]:
-    return {
-        pkg_name: (f"{THIRD_PARTY_INDEXES[pkg_name]}/", 
(f"{INVENTORY_CACHE_DIR}/{pkg_name}/objects.inv",))
-        for pkg_name in [
+    return _get_third_party_mapping(
+        [
             "boto3",
             "celery",
             "docker",
@@ -288,16 +301,12 @@ def get_intersphinx_mapping() -> dict[str, tuple[str, 
tuple[str]]]:
             "requests",
             "sqlalchemy",
         ]
-    }
+    )
 
 
 def get_google_intersphinx_mapping() -> dict[str, tuple[str, tuple[str]]]:
-    return {
-        pkg_name: (
-            f"{THIRD_PARTY_INDEXES[pkg_name]}/",
-            (f"{INVENTORY_CACHE_DIR}/{pkg_name}/objects.inv",),
-        )
-        for pkg_name in [
+    return _get_third_party_mapping(
+        [
             "google-api-core",
             "google-cloud-automl",
             "google-cloud-bigquery",
@@ -323,7 +332,7 @@ def get_google_intersphinx_mapping() -> dict[str, 
tuple[str, tuple[str]]]:
             "google-cloud-videointelligence",
             "google-cloud-vision",
         ]
-    }
+    )
 
 
 BASIC_AUTOAPI_IGNORE_PATTERNS = [
diff --git a/devel-common/src/sphinx_exts/docs_build/fetch_inventories.py 
b/devel-common/src/sphinx_exts/docs_build/fetch_inventories.py
index ce472095b4a..a35e8b3cbfb 100644
--- a/devel-common/src/sphinx_exts/docs_build/fetch_inventories.py
+++ b/devel-common/src/sphinx_exts/docs_build/fetch_inventories.py
@@ -106,10 +106,15 @@ def is_airflow_package(pkg_name: str) -> bool:
     return pkg_name.startswith("apache-airflow") or pkg_name in ["helm-chart", 
"docker-stack", "task-sdk"]
 
 
-def fetch_inventories(clean_build: bool, refresh_airflow_inventories: bool = 
False) -> list[str]:
+def fetch_inventories(
+    clean_build: bool,
+    refresh_airflow_inventories: bool = False,
+    fail_on_missing_third_party: bool = False,
+    clean_inventory_cache: bool = False,
+) -> list[str]:
     """Fetch all inventories for Airflow documentation packages and store in 
cache."""
-    if clean_build:
-        shutil.rmtree(CACHE_PATH)
+    if clean_inventory_cache:
+        shutil.rmtree(CACHE_PATH, ignore_errors=True)
         print()
         print("[yellow]Inventory Cache cleaned!")
         print()
@@ -172,24 +177,40 @@ def fetch_inventories(clean_build: bool, 
refresh_airflow_inventories: bool = Fal
     failed, success = list(failed), list(success)
     print(f"Result: {len(success)} success, {len(failed)} failed")
     if failed:
-        terminate = False
+        missing_third_party: list[str] = []
         missing_airflow_packages = False
         print("Failed packages:")
         for pkg_no, (pkg_name, _) in enumerate(failed, start=1):
             print(f"{pkg_no}. {pkg_name}")
             if not is_airflow_package(pkg_name):
-                print(
-                    f"[yellow]Missing {pkg_name} inventory is not for an 
Airflow package: "
-                    f"it will terminate the execution."
-                )
-                terminate = True
+                cached_path = CACHE_PATH / pkg_name / "objects.inv"
+                if fail_on_missing_third_party:
+                    print(
+                        f"[yellow]Missing {pkg_name} inventory is not for an 
Airflow package: "
+                        f"it will terminate the execution."
+                    )
+                    missing_third_party.append(pkg_name)
+                elif cached_path.exists():
+                    print(
+                        f"[yellow]Using cached inventory for {pkg_name} "
+                        f"(download failed but cached version exists)."
+                    )
+                else:
+                    print(f"[yellow]No inventory available for {pkg_name}, 
cross-references will be broken.")
+                    missing_third_party.append(pkg_name)
             else:
                 print(
                     f"[yellow]Missing {pkg_name} inventory is for an Airflow 
package, "
                     f"it will be built from sources."
                 )
                 missing_airflow_packages = True
-        if terminate:
+        # Write marker file for CI to detect missing third-party inventories
+        marker_file = CACHE_PATH / ".missing_third_party_inventories"
+        if missing_third_party:
+            marker_file.write_text("\n".join(missing_third_party) + "\n")
+        elif marker_file.exists():
+            marker_file.unlink()
+        if fail_on_missing_third_party and missing_third_party:
             print(
                 "[red]Terminate execution[/]\n\n"
                 "[yellow]Some non-airflow inventories are missing. If missing 
inventory is really "
@@ -204,8 +225,8 @@ def fetch_inventories(clean_build: bool, 
refresh_airflow_inventories: bool = Fal
 if __name__ == "__main__":
     if len(sys.argv) > 1 and sys.argv[1] == "clean":
         print("[bright_blue]Cleaning inventory cache before fetching 
inventories")
-        clean_build = True
+        clean_inventory_cache = True
     else:
         print("[bright_blue]Just fetching inventories without cleaning cache")
-        clean_build = False
-    fetch_inventories(clean_build=clean_build)
+        clean_inventory_cache = False
+    fetch_inventories(clean_build=False, 
clean_inventory_cache=clean_inventory_cache)

Reply via email to