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: 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: 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 documentation in one pass only. This is useful for 
[...]
</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)"> Cleaning inventories </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 the build directory before building the documentation and 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 cache (including external inventories).                             
[...]
-</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 set, only airflow package inventories will be 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 already downloaded. With `</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)"> Filtering options </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) to use more than one can be specified. You 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 full package name, for example `apache-airflow-providers-*`. Useful when you   </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 to selectseveral similarly named packages together.                           
[...]
-</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)                                        &
[...]
-</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 to include providers that are not yet ready 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 to include providers that are 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)"> Misc options </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 commits in the 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 builder used to perform `docker buildx build` 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: autodetect]                                    &#
[...]
-</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, contains space separated list of package ids that
[...]
-</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 building, and document publishing. It is an easier alternative to adding    </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 packages as arguments to every command. This overrides the packages passed as  </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.                                       &
[...]
-</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)                                        
[...]
-</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)"> Common options </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 the build directory before building the documentation. Does 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 inventory cache (use </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 the inventory cache before fetching 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 set, only airflow package inventories will be 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 if they are already downloaded. With `</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 is cleaned..                                    &
[...]
+</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 the build if any third-party inventory 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, missing third-party inventories are warned about but do not   </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 the build.                                     
[...]
+</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)"> Filtering options </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) to use more than one can be specified. You 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 full package name, for example `apache-airflow-providers-*`. Useful when you   </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 to selectseveral similarly named packages together.                           
[...]
+</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)                                        &
[...]
+</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 to include providers that are not yet ready 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 to include providers that are 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)"> Misc options </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 commits in the 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 builder used to perform `docker buildx build` 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: autodetect]                                    &#
[...]
+</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, contains space separated list of package ids that
[...]
+</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 building, and document publishing. It is an easier alternative to adding    </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 packages as arguments to every command. This overrides the packages passed as  </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.                                       &
[...]
+</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)                                        
[...]
+</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)"> Common options </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: workflow-run 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: workflow-run 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 bucket to 
[...]
</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 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)"> Common options </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)"> Inventory handling </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)"> Common options </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)