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

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new f193bbde89d Fix docs publishing when java-sdk is in the packages list 
(#69434)
f193bbde89d is described below

commit f193bbde89d5c7cae2c4cb35814a3513672a7d7d
Author: Jason(Zhe-You) Liu <[email protected]>
AuthorDate: Tue Jul 7 09:51:40 2026 +0900

    Fix docs publishing when java-sdk is in the packages list (#69434)
    
    * Fix docs publishing when java-sdk is in the packages list
    
    Publishing the Java SDK docs never worked end to end: passing java-sdk in
    include-docs failed the Sphinx build job (java-sdk is a Dokka build, not a
    Sphinx package), and breeze release-management publish-docs could not
    resolve the java-sdk package name at all, so even full 'all' publishes from
    a ref containing java-sdk/ would have crashed at the publish step. Filter
    java-sdk out of the Sphinx build (skipping it entirely for a java-sdk-only
    run), teach breeze the java-sdk doc package, and skip packages whose docs
    were not staged instead of failing on version resolution, so publishes from
    refs without java-sdk keep working unchanged.
    
    * Resolve java-sdk docs version from gradle.properties when stable.txt is 
missing
    
    Review follow-up: a staged-but-incomplete java-sdk docs dir (stable/ 
present,
    stable.txt missing) crashed publish-docs with "Unsupported package"; fall 
back
    to the version in java-sdk/gradle.properties like the other doc packages 
fall
    back to their sources. Also cover the publish skip-ordering and the 
stable.txt
    version resolution with tests.
    
    * Trim redundant comments and merge the java-sdk unversioned check
    
    Review follow-up: the workflow echo messages already describe the skip
    behaviour, the java-sdk None-return folds into the adjacent check, and the
    skip-before-version-resolution comment claimed a stale SystemExit reason
    instead of the real one (no version resolution and no output-dir deletion
    for packages with nothing staged).
    
    * Cover preserving published docs when a publish run has nothing staged
    
    Review follow-up: pin the destructive pre-reorder behaviour where an
    override-versioned publish deleted an already-published directory and then
    skipped because the build dir was missing.
---
 .github/workflows/publish-docs-to-s3.yml           |  32 +++++--
 dev/breeze/doc/images/output-commands.svg          |   2 +-
 dev/breeze/doc/images/output_build-docs.svg        |  12 +--
 dev/breeze/doc/images/output_build-docs.txt        |   2 +-
 ...tput_release-management_add-back-references.svg |  12 +--
 ...tput_release-management_add-back-references.txt |   2 +-
 .../output_release-management_publish-docs.svg     |  12 +--
 .../output_release-management_publish-docs.txt     |   2 +-
 .../images/output_workflow-run_publish-docs.svg    |  12 +--
 .../images/output_workflow-run_publish-docs.txt    |   2 +-
 .../airflow_breeze/commands/developer_commands.py  |  12 +--
 .../commands/release_management_commands.py        |   3 +-
 dev/breeze/src/airflow_breeze/global_constants.py  |  11 +++
 .../src/airflow_breeze/utils/docs_publisher.py     |  20 +++-
 dev/breeze/tests/test_docs_publisher.py            | 106 +++++++++++++++++++++
 dev/breeze/tests/test_packages.py                  |   3 +
 .../tests/test_release_management_commands.py      |  21 ++++
 17 files changed, 214 insertions(+), 52 deletions(-)

diff --git a/.github/workflows/publish-docs-to-s3.yml 
b/.github/workflows/publish-docs-to-s3.yml
index 06f188b84b3..dd43f9c0218 100644
--- a/.github/workflows/publish-docs-to-s3.yml
+++ b/.github/workflows/publish-docs-to-s3.yml
@@ -323,15 +323,34 @@ jobs:
           key: cache-docs-inventory-v1
         id: restore-docs-inventory-cache
       - name: "Building docs with --docs-only flag using ${{ inputs.ref }} 
reference breeze"
+        id: build-sphinx-docs
         env:
           INCLUDE_DOCS: ${{ needs.build-info.outputs.include-docs }}
           INCLUDE_COMMITS: ${{ startsWith(inputs.ref, 'providers') && 'true' 
|| 'false' }}
           FAIL_ON_INVENTORIES: ${{ inputs.ignore-missing-inventories != true 
&& '--fail-on-missing-third-party-inventories' || '' }}
-        run: >
-          breeze build-docs ${INCLUDE_DOCS} --docs-only ${FAIL_ON_INVENTORIES}
+        run: |
+          # The Java SDK docs are built with Dokka by the separate 
build-java-sdk-docs job;
+          # java-sdk is not a Sphinx package, so it must not be passed to 
breeze build-docs.
+          SPHINX_INCLUDE_DOCS=""
+          for package in ${INCLUDE_DOCS}; do
+            if [[ "${package}" != "java-sdk" ]]; then
+              SPHINX_INCLUDE_DOCS="${SPHINX_INCLUDE_DOCS} ${package}"
+            fi
+          done
+          if [[ -n "${INCLUDE_DOCS}" && -z "${SPHINX_INCLUDE_DOCS// /}" ]]; 
then
+            echo "Only java-sdk docs were requested - skipping the Sphinx docs 
build."
+            mkdir -p generated/_build/docs
+            echo "The Sphinx docs build was skipped: only java-sdk docs were 
requested." \
+              > generated/_build/docs/sphinx-build-skipped.txt
+            echo "sphinx-build-skipped=true" >> "${GITHUB_OUTPUT}"
+          else
+            breeze build-docs ${SPHINX_INCLUDE_DOCS} --docs-only 
${FAIL_ON_INVENTORIES}
+          fi
       - name: "Save docs inventory cache"
         uses: 
apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec
-        if: steps.restore-docs-inventory-cache.outputs.stash-hit != 'true'
+        if: >-
+          steps.restore-docs-inventory-cache.outputs.stash-hit != 'true' &&
+          steps.build-sphinx-docs.outputs.sphinx-build-skipped != 'true'
         with:
           path: ./generated/_inventory_cache/
           key: cache-docs-inventory-v1
@@ -415,8 +434,8 @@ jobs:
           # builds (include-docs == 'all') or when 'java-sdk' is explicitly 
listed.
           # When a specific list of packages is passed (e.g. a provider release
           # wave like "amazon cncf.kubernetes ..."), the Java SDK must NOT be 
added
-          # automatically — otherwise the publish step drags java-sdk into a
-          # providers-only publish and the S3 publish fails.
+          # automatically — a providers-only publish should not suddenly 
refresh the
+          # java-sdk docs as a side effect.
           if [[ "${INCLUDE_DOCS}" != "all" && " ${INCLUDE_DOCS} " != *" 
java-sdk "* ]]; then
             echo "exists=false" >> "${GITHUB_OUTPUT}"
             echo "include-docs='${INCLUDE_DOCS}' is a specific package list 
without 'java-sdk' — skipping Javadoc build."
@@ -519,10 +538,9 @@ jobs:
       - name: "Publish docs to /mnt/airflow-site directory using ${{ 
inputs.ref }} reference breeze"
         env:
           INCLUDE_DOCS: ${{ needs.build-info.outputs.include-docs }}
-          JAVA_SDK_DOCS: ${{ needs.build-java-sdk-docs.outputs.built == 'true' 
&& 'java-sdk' || '' }}
         run: >
           breeze release-management publish-docs --override-versioned 
--run-in-parallel
-          ${INCLUDE_DOCS} ${JAVA_SDK_DOCS}
+          ${INCLUDE_DOCS}
       - name: Check disk space available
         run: df -H
       - name: "Update watermarks"
diff --git a/dev/breeze/doc/images/output-commands.svg 
b/dev/breeze/doc/images/output-commands.svg
index 4891c30ed51..6dfe7e09c52 100644
--- a/dev/breeze/doc/images/output-commands.svg
+++ b/dev/breeze/doc/images/output-commands.svg
@@ -367,7 +367,7 @@
     
     <g class="breeze-help-matrix">
     <text class="breeze-help-r1" x="1464" y="20" textLength="12.2" 
clip-path="url(#breeze-help-line-0)">
-</text><text class="breeze-help-r2" x="12.2" y="44.4" textLength="73.2" 
clip-path="url(#breeze-help-line-1)">Usage:</text><text class="breeze-help-r3" 
x="97.6" y="44.4" textLength="73.2" 
clip-path="url(#breeze-help-line-1)">breeze</text><text class="breeze-help-r1" 
x="183" y="44.4" textLength="12.2" 
clip-path="url(#breeze-help-line-1)">[</text><text class="breeze-help-r4" 
x="195.2" y="44.4" textLength="85.4" 
clip-path="url(#breeze-help-line-1)">OPTIONS</text><text class="breeze-help-r1" 
 [...]
+</text><text class="breeze-help-r2" x="12.2" y="44.4" textLength="73.2" 
clip-path="url(#breeze-help-line-1)">Usage:</text><text class="breeze-help-r3" 
x="97.6" y="44.4" textLength="73.2" 
clip-path="url(#breeze-help-line-1)">breeze</text><text class="breeze-help-r1" 
x="183" y="44.4" textLength="12.2" 
clip-path="url(#breeze-help-line-1)">[</text><text class="breeze-help-r4" 
x="195.2" y="44.4" textLength="85.4" 
clip-path="url(#breeze-help-line-1)">OPTIONS</text><text class="breeze-help-r1" 
 [...]
 </text><text class="breeze-help-r1" x="1464" y="68.8" textLength="12.2" 
clip-path="url(#breeze-help-line-2)">
 </text><text class="breeze-help-r5" x="0" y="93.2" textLength="24.4" 
clip-path="url(#breeze-help-line-3)">╭─</text><text class="breeze-help-r5" 
x="24.4" y="93.2" textLength="195.2" 
clip-path="url(#breeze-help-line-3)">&#160;Common&#160;options&#160;</text><text
 class="breeze-help-r5" x="219.6" y="93.2" textLength="1220" 
clip-path="url(#breeze-help-line-3)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
 class="breeze-help-r [...]
 </text><text class="breeze-help-r5" x="0" y="117.6" textLength="12.2" 
clip-path="url(#breeze-help-line-4)">│</text><text class="breeze-help-r4" 
x="24.4" y="117.6" textLength="109.8" 
clip-path="url(#breeze-help-line-4)">--answer&#160;</text><text 
class="breeze-help-r6" x="158.6" y="117.6" textLength="24.4" 
clip-path="url(#breeze-help-line-4)">-a</text><text class="breeze-help-r1" 
x="207.4" y="117.6" textLength="329.4" 
clip-path="url(#breeze-help-line-4)">Force&#160;answer&#160;to&#160;que [...]
diff --git a/dev/breeze/doc/images/output_build-docs.svg 
b/dev/breeze/doc/images/output_build-docs.svg
index 21272cc6229..ca5cb1775bc 100644
--- a/dev/breeze/doc/images/output_build-docs.svg
+++ b/dev/breeze/doc/images/output_build-docs.svg
@@ -246,12 +246,12 @@
 </text><text class="breeze-build-docs-r1" x="12.2" y="166.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-6)">|&#160;</text><text 
class="breeze-build-docs-r4" x="36.6" y="166.4" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-6)">apache</text><text 
class="breeze-build-docs-r1" x="109.8" y="166.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-6)">.</text><text 
class="breeze-build-docs-r4" x="122" y="166.4" textLength="109.8" 
clip-path="url(#breeze-build-doc [...]
 </text><text class="breeze-build-docs-r1" x="12.2" y="190.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-7)">|&#160;</text><text 
class="breeze-build-docs-r4" x="36.6" y="190.8" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-7)">cohere</text><text 
class="breeze-build-docs-r1" x="109.8" y="190.8" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-7)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="146.4" y="190.8" textLength="73.2" 
clip-path="url(#bre [...]
 </text><text class="breeze-build-docs-r4" x="12.2" y="215.2" textLength="97.6" 
clip-path="url(#breeze-build-docs-line-8)">dingding</text><text 
class="breeze-build-docs-r1" x="109.8" y="215.2" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-8)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="146.4" y="215.2" textLength="85.4" 
clip-path="url(#breeze-build-docs-line-8)">discord</text><text 
class="breeze-build-docs-r1" x="231.8" y="215.2" textLength="36.6" 
clip-path="url(# [...]
-</text><text class="breeze-build-docs-r4" x="12.2" y="239.6" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-9)">google</text><text 
class="breeze-build-docs-r1" x="85.4" y="239.6" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-9)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="122" y="239.6" textLength="48.8" 
clip-path="url(#breeze-build-docs-line-9)">grpc</text><text 
class="breeze-build-docs-r1" x="170.8" y="239.6" textLength="36.6" 
clip-path="url(#breeze-b [...]
-</text><text class="breeze-build-docs-r4" x="12.2" y="264" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-10)">microsoft</text><text 
class="breeze-build-docs-r1" x="122" y="264" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-10)">.</text><text 
class="breeze-build-docs-r4" x="134.2" y="264" textLength="61" 
clip-path="url(#breeze-build-docs-line-10)">azure</text><text 
class="breeze-build-docs-r1" x="195.2" y="264" textLength="36.6" 
clip-path="url(#breeze-build-docs-lin [...]
-</text><text class="breeze-build-docs-r4" x="12.2" y="288.4" textLength="97.6" 
clip-path="url(#breeze-build-docs-line-11)">openfaas</text><text 
class="breeze-build-docs-r1" x="109.8" y="288.4" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-11)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="146.4" y="288.4" textLength="134.2" 
clip-path="url(#breeze-build-docs-line-11)">openlineage</text><text 
class="breeze-build-docs-r1" x="280.6" y="288.4" textLength="36.6" clip-pat 
[...]
-</text><text class="breeze-build-docs-r4" x="12.2" y="312.8" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-12)">presto</text><text 
class="breeze-build-docs-r1" x="85.4" y="312.8" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-12)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="122" y="312.8" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-12)">qdrant</text><text 
class="breeze-build-docs-r1" x="195.2" y="312.8" textLength="36.6" 
clip-path="url(#bre [...]
-</text><text class="breeze-build-docs-r4" x="12.2" y="337.2" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-13)">sqlite</text><text 
class="breeze-build-docs-r1" x="85.4" y="337.2" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-13)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="122" y="337.2" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-13)">ssh</text><text 
class="breeze-build-docs-r1" x="158.6" y="337.2" textLength="36.6" 
clip-path="url(#breeze [...]
-</text><text class="breeze-build-docs-r1" x="12.2" y="361.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-14)">|&#160;</text><text 
class="breeze-build-docs-r4" x="36.6" y="361.6" textLength="85.4" 
clip-path="url(#breeze-build-docs-line-14)">zendesk</text><text 
class="breeze-build-docs-r1" x="122" y="361.6" textLength="1329.8" 
clip-path="url(#breeze-build-docs-line-14)">]...&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
+</text><text class="breeze-build-docs-r4" x="12.2" y="239.6" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-9)">google</text><text 
class="breeze-build-docs-r1" x="85.4" y="239.6" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-9)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="122" y="239.6" textLength="48.8" 
clip-path="url(#breeze-build-docs-line-9)">grpc</text><text 
class="breeze-build-docs-r1" x="170.8" y="239.6" textLength="36.6" 
clip-path="url(#breeze-b [...]
+</text><text class="breeze-build-docs-r4" x="12.2" y="264" textLength="97.6" 
clip-path="url(#breeze-build-docs-line-10)">keycloak</text><text 
class="breeze-build-docs-r1" x="109.8" y="264" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-10)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="146.4" y="264" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-10)">microsoft</text><text 
class="breeze-build-docs-r1" x="256.2" y="264" textLength="12.2" 
clip-path="url(#br [...]
+</text><text class="breeze-build-docs-r4" x="12.2" y="288.4" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-11)">openai</text><text 
class="breeze-build-docs-r1" x="85.4" y="288.4" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-11)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="122" y="288.4" textLength="97.6" 
clip-path="url(#breeze-build-docs-line-11)">openfaas</text><text 
class="breeze-build-docs-r1" x="219.6" y="288.4" textLength="36.6" 
clip-path="url(#b [...]
+</text><text class="breeze-build-docs-r4" x="12.2" y="312.8" textLength="97.6" 
clip-path="url(#breeze-build-docs-line-12)">postgres</text><text 
class="breeze-build-docs-r1" x="109.8" y="312.8" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-12)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="146.4" y="312.8" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-12)">presto</text><text 
class="breeze-build-docs-r1" x="219.6" y="312.8" textLength="36.6" 
clip-path="url [...]
+</text><text class="breeze-build-docs-r4" x="12.2" y="337.2" 
textLength="109.8" 
clip-path="url(#breeze-build-docs-line-13)">snowflake</text><text 
class="breeze-build-docs-r1" x="122" y="337.2" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-13)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="158.6" y="337.2" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-13)">sqlite</text><text 
class="breeze-build-docs-r1" x="231.8" y="337.2" textLength="36.6" 
clip-path="url [...]
+</text><text class="breeze-build-docs-r4" x="12.2" y="361.6" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-14)">yandex</text><text 
class="breeze-build-docs-r1" x="85.4" y="361.6" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-14)">&#160;|&#160;</text><text 
class="breeze-build-docs-r4" x="122" y="361.6" textLength="36.6" 
clip-path="url(#breeze-build-docs-line-14)">ydb</text><text 
class="breeze-build-docs-r1" x="158.6" y="361.6" textLength="36.6" 
clip-path="url(#breeze [...]
 </text><text class="breeze-build-docs-r1" x="1464" y="386" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-15)">
 </text><text class="breeze-build-docs-r1" x="12.2" y="410.4" 
textLength="195.2" 
clip-path="url(#breeze-build-docs-line-16)">Build&#160;documents.</text><text 
class="breeze-build-docs-r1" x="1464" y="410.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-16)">
 </text><text class="breeze-build-docs-r1" x="1464" y="434.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-17)">
diff --git a/dev/breeze/doc/images/output_build-docs.txt 
b/dev/breeze/doc/images/output_build-docs.txt
index 48b11286965..7e869646226 100644
--- a/dev/breeze/doc/images/output_build-docs.txt
+++ b/dev/breeze/doc/images/output_build-docs.txt
@@ -1 +1 @@
-28c9a42f6270c2fa37c15cca78a8c38b
+22cd66d36e80473f4fac0fa311c5e846
diff --git 
a/dev/breeze/doc/images/output_release-management_add-back-references.svg 
b/dev/breeze/doc/images/output_release-management_add-back-references.svg
index 814f0d28ea3..09e78ba8811 100644
--- a/dev/breeze/doc/images/output_release-management_add-back-references.svg
+++ b/dev/breeze/doc/images/output_release-management_add-back-references.svg
@@ -155,12 +155,12 @@
 </text><text class="breeze-release-management-add-back-references-r1" x="12.2" 
y="166.4" textLength="24.4" 
clip-path="url(#breeze-release-management-add-back-references-line-6)">|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="36.6" y="166.4" 
textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-6)">apache</text><text
 class="breeze-release-management-add-back-references-r1" x="109.8" y="166.4" 
textLength="12.2" clip-path="url( [...]
 </text><text class="breeze-release-management-add-back-references-r1" x="12.2" 
y="190.8" textLength="24.4" 
clip-path="url(#breeze-release-management-add-back-references-line-7)">|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="36.6" y="190.8" 
textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-7)">cohere</text><text
 class="breeze-release-management-add-back-references-r1" x="109.8" y="190.8" 
textLength="36.6" clip-path="url( [...]
 </text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="215.2" textLength="97.6" 
clip-path="url(#breeze-release-management-add-back-references-line-8)">dingding</text><text
 class="breeze-release-management-add-back-references-r1" x="109.8" y="215.2" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-8)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="146.4" y="215.2" 
textLength="85.4" clip-p [...]
-</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="239.6" textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-9)">google</text><text
 class="breeze-release-management-add-back-references-r1" x="85.4" y="239.6" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-9)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="122" y="239.6" 
textLength="48.8" clip-path=" [...]
-</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="264" textLength="109.8" 
clip-path="url(#breeze-release-management-add-back-references-line-10)">microsoft</text><text
 class="breeze-release-management-add-back-references-r1" x="122" y="264" 
textLength="12.2" 
clip-path="url(#breeze-release-management-add-back-references-line-10)">.</text><text
 class="breeze-release-management-add-back-references-r4" x="134.2" y="264" 
textLength="61" clip-path="url(#breeze-r [...]
-</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="288.4" textLength="97.6" 
clip-path="url(#breeze-release-management-add-back-references-line-11)">openfaas</text><text
 class="breeze-release-management-add-back-references-r1" x="109.8" y="288.4" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-11)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="146.4" y="288.4" 
textLength="134.2" cli [...]
-</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="312.8" textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-12)">presto</text><text
 class="breeze-release-management-add-back-references-r1" x="85.4" y="312.8" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-12)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="122" y="312.8" 
textLength="73.2" clip-path [...]
-</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="337.2" textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-13)">sqlite</text><text
 class="breeze-release-management-add-back-references-r1" x="85.4" y="337.2" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-13)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="122" y="337.2" 
textLength="36.6" clip-path [...]
-</text><text class="breeze-release-management-add-back-references-r1" x="12.2" 
y="361.6" textLength="24.4" 
clip-path="url(#breeze-release-management-add-back-references-line-14)">|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="36.6" y="361.6" 
textLength="85.4" 
clip-path="url(#breeze-release-management-add-back-references-line-14)">zendesk</text><text
 class="breeze-release-management-add-back-references-r1" x="122" y="361.6" 
textLength="1329.8" clip-path="u [...]
+</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="239.6" textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-9)">google</text><text
 class="breeze-release-management-add-back-references-r1" x="85.4" y="239.6" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-9)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="122" y="239.6" 
textLength="48.8" clip-path=" [...]
+</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="264" textLength="97.6" 
clip-path="url(#breeze-release-management-add-back-references-line-10)">keycloak</text><text
 class="breeze-release-management-add-back-references-r1" x="109.8" y="264" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-10)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="146.4" y="264" 
textLength="109.8" clip-path [...]
+</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="288.4" textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-11)">openai</text><text
 class="breeze-release-management-add-back-references-r1" x="85.4" y="288.4" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-11)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="122" y="288.4" 
textLength="97.6" clip-path [...]
+</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="312.8" textLength="97.6" 
clip-path="url(#breeze-release-management-add-back-references-line-12)">postgres</text><text
 class="breeze-release-management-add-back-references-r1" x="109.8" y="312.8" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-12)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="146.4" y="312.8" 
textLength="73.2" clip [...]
+</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="337.2" textLength="109.8" 
clip-path="url(#breeze-release-management-add-back-references-line-13)">snowflake</text><text
 class="breeze-release-management-add-back-references-r1" x="122" y="337.2" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-13)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="158.6" y="337.2" 
textLength="73.2" clip [...]
+</text><text class="breeze-release-management-add-back-references-r4" x="12.2" 
y="361.6" textLength="73.2" 
clip-path="url(#breeze-release-management-add-back-references-line-14)">yandex</text><text
 class="breeze-release-management-add-back-references-r1" x="85.4" y="361.6" 
textLength="36.6" 
clip-path="url(#breeze-release-management-add-back-references-line-14)">&#160;|&#160;</text><text
 class="breeze-release-management-add-back-references-r4" x="122" y="361.6" 
textLength="36.6" clip-path [...]
 </text><text class="breeze-release-management-add-back-references-r1" x="1464" 
y="386" textLength="12.2" 
clip-path="url(#breeze-release-management-add-back-references-line-15)">
 </text><text class="breeze-release-management-add-back-references-r1" x="12.2" 
y="410.4" textLength="976" 
clip-path="url(#breeze-release-management-add-back-references-line-16)">Command&#160;to&#160;add&#160;back&#160;references&#160;for&#160;documentation&#160;to&#160;make&#160;it&#160;backward&#160;compatible.</text><text
 class="breeze-release-management-add-back-references-r1" x="1464" y="410.4" 
textLength="12.2" 
clip-path="url(#breeze-release-management-add-back-references-line-16)">
 </text><text class="breeze-release-management-add-back-references-r1" x="1464" 
y="434.8" textLength="12.2" 
clip-path="url(#breeze-release-management-add-back-references-line-17)">
diff --git 
a/dev/breeze/doc/images/output_release-management_add-back-references.txt 
b/dev/breeze/doc/images/output_release-management_add-back-references.txt
index 8562a83f6d2..672e05eb6b2 100644
--- a/dev/breeze/doc/images/output_release-management_add-back-references.txt
+++ b/dev/breeze/doc/images/output_release-management_add-back-references.txt
@@ -1 +1 @@
-a100217703deb9fddf97c53ef7e959a5
+2700b8a52b9a04bb3cf5e365e70c2f40
diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.svg 
b/dev/breeze/doc/images/output_release-management_publish-docs.svg
index 6c08dc6c566..9416d6183c5 100644
--- a/dev/breeze/doc/images/output_release-management_publish-docs.svg
+++ b/dev/breeze/doc/images/output_release-management_publish-docs.svg
@@ -194,12 +194,12 @@
 </text><text class="breeze-release-management-publish-docs-r1" x="12.2" 
y="166.4" textLength="24.4" 
clip-path="url(#breeze-release-management-publish-docs-line-6)">|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="36.6" y="166.4" 
textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-6)">apache</text><text
 class="breeze-release-management-publish-docs-r1" x="109.8" y="166.4" 
textLength="12.2" clip-path="url(#breeze-release-management-publish- [...]
 </text><text class="breeze-release-management-publish-docs-r1" x="12.2" 
y="190.8" textLength="24.4" 
clip-path="url(#breeze-release-management-publish-docs-line-7)">|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="36.6" y="190.8" 
textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-7)">cohere</text><text
 class="breeze-release-management-publish-docs-r1" x="109.8" y="190.8" 
textLength="36.6" clip-path="url(#breeze-release-management-publish- [...]
 </text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="215.2" textLength="97.6" 
clip-path="url(#breeze-release-management-publish-docs-line-8)">dingding</text><text
 class="breeze-release-management-publish-docs-r1" x="109.8" y="215.2" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-8)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="146.4" y="215.2" 
textLength="85.4" clip-path="url(#breeze-release-management [...]
-</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="239.6" textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-9)">google</text><text
 class="breeze-release-management-publish-docs-r1" x="85.4" y="239.6" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-9)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="122" y="239.6" 
textLength="48.8" clip-path="url(#breeze-release-management-publ [...]
-</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="264" textLength="109.8" 
clip-path="url(#breeze-release-management-publish-docs-line-10)">microsoft</text><text
 class="breeze-release-management-publish-docs-r1" x="122" y="264" 
textLength="12.2" 
clip-path="url(#breeze-release-management-publish-docs-line-10)">.</text><text 
class="breeze-release-management-publish-docs-r4" x="134.2" y="264" 
textLength="61" clip-path="url(#breeze-release-management-publish-docs-line 
[...]
-</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="288.4" textLength="97.6" 
clip-path="url(#breeze-release-management-publish-docs-line-11)">openfaas</text><text
 class="breeze-release-management-publish-docs-r1" x="109.8" y="288.4" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-11)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="146.4" y="288.4" 
textLength="134.2" clip-path="url(#breeze-release-managem [...]
-</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="312.8" textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-12)">presto</text><text
 class="breeze-release-management-publish-docs-r1" x="85.4" y="312.8" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-12)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="122" y="312.8" 
textLength="73.2" clip-path="url(#breeze-release-management-pu [...]
-</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="337.2" textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-13)">sqlite</text><text
 class="breeze-release-management-publish-docs-r1" x="85.4" y="337.2" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-13)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="122" y="337.2" 
textLength="36.6" clip-path="url(#breeze-release-management-pu [...]
-</text><text class="breeze-release-management-publish-docs-r1" x="12.2" 
y="361.6" textLength="24.4" 
clip-path="url(#breeze-release-management-publish-docs-line-14)">|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="36.6" y="361.6" 
textLength="85.4" 
clip-path="url(#breeze-release-management-publish-docs-line-14)">zendesk</text><text
 class="breeze-release-management-publish-docs-r1" x="122" y="361.6" 
textLength="1329.8" clip-path="url(#breeze-release-management-publi [...]
+</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="239.6" textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-9)">google</text><text
 class="breeze-release-management-publish-docs-r1" x="85.4" y="239.6" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-9)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="122" y="239.6" 
textLength="48.8" clip-path="url(#breeze-release-management-publ [...]
+</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="264" textLength="97.6" 
clip-path="url(#breeze-release-management-publish-docs-line-10)">keycloak</text><text
 class="breeze-release-management-publish-docs-r1" x="109.8" y="264" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-10)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="146.4" y="264" 
textLength="109.8" clip-path="url(#breeze-release-management-pu [...]
+</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="288.4" textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-11)">openai</text><text
 class="breeze-release-management-publish-docs-r1" x="85.4" y="288.4" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-11)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="122" y="288.4" 
textLength="97.6" clip-path="url(#breeze-release-management-pu [...]
+</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="312.8" textLength="97.6" 
clip-path="url(#breeze-release-management-publish-docs-line-12)">postgres</text><text
 class="breeze-release-management-publish-docs-r1" x="109.8" y="312.8" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-12)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="146.4" y="312.8" 
textLength="73.2" clip-path="url(#breeze-release-manageme [...]
+</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="337.2" textLength="109.8" 
clip-path="url(#breeze-release-management-publish-docs-line-13)">snowflake</text><text
 class="breeze-release-management-publish-docs-r1" x="122" y="337.2" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-13)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="158.6" y="337.2" 
textLength="73.2" clip-path="url(#breeze-release-manageme [...]
+</text><text class="breeze-release-management-publish-docs-r4" x="12.2" 
y="361.6" textLength="73.2" 
clip-path="url(#breeze-release-management-publish-docs-line-14)">yandex</text><text
 class="breeze-release-management-publish-docs-r1" x="85.4" y="361.6" 
textLength="36.6" 
clip-path="url(#breeze-release-management-publish-docs-line-14)">&#160;|&#160;</text><text
 class="breeze-release-management-publish-docs-r4" x="122" y="361.6" 
textLength="36.6" clip-path="url(#breeze-release-management-pu [...]
 </text><text class="breeze-release-management-publish-docs-r1" x="1464" 
y="386" textLength="12.2" 
clip-path="url(#breeze-release-management-publish-docs-line-15)">
 </text><text class="breeze-release-management-publish-docs-r1" x="12.2" 
y="410.4" textLength="707.6" 
clip-path="url(#breeze-release-management-publish-docs-line-16)">Command&#160;to&#160;publish&#160;generated&#160;documentation&#160;to&#160;airflow-site</text><text
 class="breeze-release-management-publish-docs-r1" x="1464" y="410.4" 
textLength="12.2" 
clip-path="url(#breeze-release-management-publish-docs-line-16)">
 </text><text class="breeze-release-management-publish-docs-r1" x="1464" 
y="434.8" textLength="12.2" 
clip-path="url(#breeze-release-management-publish-docs-line-17)">
diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.txt 
b/dev/breeze/doc/images/output_release-management_publish-docs.txt
index 9c2563d46b8..b6433c39bb9 100644
--- a/dev/breeze/doc/images/output_release-management_publish-docs.txt
+++ b/dev/breeze/doc/images/output_release-management_publish-docs.txt
@@ -1 +1 @@
-71cd889146297a3b78c71773b6bb5bcd
+cc4ad6886b5ff0da1d4f819d2c5dc80d
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 ff1db47a5f2..dfb0027b3d7 100644
--- a/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
+++ b/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
@@ -209,12 +209,12 @@
 </text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="166.4" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-6)">|&#160;</text><text 
class="breeze-workflow-run-publish-docs-r4" x="36.6" y="166.4" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-6)">apache</text><text 
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="166.4" 
textLength="12.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-6)">.</text><text 
class="b [...]
 </text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="190.8" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-7)">|&#160;</text><text 
class="breeze-workflow-run-publish-docs-r4" x="36.6" y="190.8" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-7)">cohere</text><text 
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="190.8" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-7)">&#160;|&#160;</text><t
 [...]
 </text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="215.2" 
textLength="97.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-8)">dingding</text><text 
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="215.2" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-8)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="146.4" y="215.2" 
textLength="85.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-8)">discord</text [...]
-</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="239.6" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">google</text><text 
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="239.6" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="122" y="239.6" 
textLength="48.8" 
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">grpc</text><text c 
[...]
-</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="264" 
textLength="109.8" 
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">microsoft</text><text
 class="breeze-workflow-run-publish-docs-r1" x="122" y="264" textLength="12.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">.</text><text 
class="breeze-workflow-run-publish-docs-r4" x="134.2" y="264" textLength="61" 
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">azure</text><text 
class="breez [...]
-</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="288.4" 
textLength="97.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">openfaas</text><text 
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="288.4" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="146.4" y="288.4" 
textLength="134.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">openlinea [...]
-</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="312.8" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">presto</text><text 
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="312.8" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="122" y="312.8" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">qdrant</text><t [...]
-</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="337.2" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">sqlite</text><text 
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="337.2" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="122" y="337.2" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">ssh</text><text [...]
-</text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="361.6" 
textLength="24.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-14)">|&#160;</text><text 
class="breeze-workflow-run-publish-docs-r4" x="36.6" y="361.6" 
textLength="85.4" 
clip-path="url(#breeze-workflow-run-publish-docs-line-14)">zendesk</text><text 
class="breeze-workflow-run-publish-docs-r1" x="122" y="361.6" 
textLength="1329.8" 
clip-path="url(#breeze-workflow-run-publish-docs-line-14)">]...&#160;&#160;&# 
[...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="239.6" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">google</text><text 
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="239.6" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="122" y="239.6" 
textLength="48.8" 
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">grpc</text><text c 
[...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="264" 
textLength="97.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">keycloak</text><text 
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="264" textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="146.4" y="264" 
textLength="109.8" 
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">microsoft</text [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="288.4" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">openai</text><text 
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="288.4" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="122" y="288.4" 
textLength="97.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">openfaas</text> [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="312.8" 
textLength="97.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">postgres</text><text 
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="312.8" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="146.4" y="312.8" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">presto</te [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="337.2" 
textLength="109.8" 
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">snowflake</text><text
 class="breeze-workflow-run-publish-docs-r1" x="122" y="337.2" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="158.6" y="337.2" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">sqlite</te [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="361.6" 
textLength="73.2" 
clip-path="url(#breeze-workflow-run-publish-docs-line-14)">yandex</text><text 
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="361.6" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-14)">&#160;|&#160;</text><text
 class="breeze-workflow-run-publish-docs-r4" x="122" y="361.6" 
textLength="36.6" 
clip-path="url(#breeze-workflow-run-publish-docs-line-14)">ydb</text><text [...]
 </text><text class="breeze-workflow-run-publish-docs-r1" x="1464" y="386" 
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-15)">
 </text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="410.4" 
textLength="427" 
clip-path="url(#breeze-workflow-run-publish-docs-line-16)">Trigger&#160;publish&#160;docs&#160;to&#160;S3&#160;workflow</text><text
 class="breeze-workflow-run-publish-docs-r1" x="1464" y="410.4" 
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-16)">
 </text><text class="breeze-workflow-run-publish-docs-r1" x="1464" y="434.8" 
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-17)">
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 01d247c7318..4c6ec79dba1 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 @@
-6a419bdaebbe36070dfea872c87a2a23
+e784b5234a05d958f84df96cd5d8d562
diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py 
b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
index 4c53d752236..29df6c2111b 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
@@ -107,6 +107,7 @@ from airflow_breeze.global_constants import (
     MOUNT_ALL,
     START_AIRFLOW_ALLOWED_EXECUTORS,
     START_AIRFLOW_DEFAULT_ALLOWED_EXECUTOR,
+    get_java_sdk_version,
 )
 from airflow_breeze.params.build_ci_params import BuildCiParams
 from airflow_breeze.params.doc_build_params import DocBuildParams
@@ -753,15 +754,6 @@ def start_airflow(
     sys.exit(result.returncode)
 
 
-def _get_java_sdk_version() -> str:
-    """Read the Java SDK version from 'java-sdk/gradle.properties'."""
-    props_path = AIRFLOW_ROOT_PATH / "java-sdk" / "gradle.properties"
-    for line in props_path.read_text().splitlines():
-        if match := re.match(r"^projectVersion\s*=\s*(\S+)$", line.strip()):
-            return match.group(1)
-    raise RuntimeError(f"Java SDK version not found in {props_path}")
-
-
 def _build_java_sdk_docs(generated_path: Path) -> int:
     """Run Dokka for the Java SDK and stage its output for the publish 
pipeline.
 
@@ -811,7 +803,7 @@ def _build_java_sdk_docs(generated_path: Path) -> int:
 
     # Write stable.txt so breeze release-management publish-docs treats this 
as a
     # versioned package and places it at docs-archive/java-sdk/{version}/.
-    sdk_version = _get_java_sdk_version()
+    sdk_version = get_java_sdk_version()
     stable_txt = generated_path / "_build" / "docs" / "java-sdk" / "stable.txt"
     stable_txt.write_text(sdk_version + "\n")
     console_print(f"[success]Java SDK docs staged at {dst}  (version: 
{sdk_version})")
diff --git 
a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py 
b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index c866d903ed3..a2e79615057 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -2035,7 +2035,8 @@ def 
get_package_version_possibly_from_stable_txt(package_name: str) -> str | Non
     if package_name == "helm-chart":
         return chart_version()
 
-    if package_name in ("docker-stack", "apache-airflow-providers"):
+    if package_name in ("docker-stack", "apache-airflow-providers", 
"java-sdk"):
+        # Non-versioned packages; java-sdk is versioned but only via a staged 
stable.txt.
         return None
 
     if package_name.startswith("apache-airflow-providers-"):
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py 
b/dev/breeze/src/airflow_breeze/global_constants.py
index 4d31303879c..abd6237606f 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -21,6 +21,7 @@ Global constants that are used by all other Breeze components.
 from __future__ import annotations
 
 import platform
+import re
 from enum import Enum
 from pathlib import Path
 
@@ -308,6 +309,7 @@ REGULAR_DOC_PACKAGES = [
     "docker-stack",
     "helm-chart",
     "apache-airflow-providers",
+    "java-sdk",
     "task-sdk",
     "apache-airflow-ctl",
 ]
@@ -730,6 +732,15 @@ def get_task_sdk_version():
     return task_sdk_version
 
 
+def get_java_sdk_version() -> str:
+    """Read the Java SDK version from 'java-sdk/gradle.properties'."""
+    props_path = AIRFLOW_ROOT_PATH / "java-sdk" / "gradle.properties"
+    for line in props_path.read_text().splitlines():
+        if match := re.match(r"^projectVersion\s*=\s*(\S+)$", line.strip()):
+            return match.group(1)
+    raise RuntimeError(f"Java SDK version not found in {props_path}")
+
+
 @clearable_cache
 def get_airflow_extras():
     airflow_dockerfile = AIRFLOW_ROOT_PATH / "Dockerfile"
diff --git a/dev/breeze/src/airflow_breeze/utils/docs_publisher.py 
b/dev/breeze/src/airflow_breeze/utils/docs_publisher.py
index 068d73d5b6f..1596b3ab857 100644
--- a/dev/breeze/src/airflow_breeze/utils/docs_publisher.py
+++ b/dev/breeze/src/airflow_breeze/utils/docs_publisher.py
@@ -19,7 +19,12 @@ from __future__ import annotations
 import os
 import shutil
 
-from airflow_breeze.global_constants import get_airflow_version, 
get_airflowctl_version, get_task_sdk_version
+from airflow_breeze.global_constants import (
+    get_airflow_version,
+    get_airflowctl_version,
+    get_java_sdk_version,
+    get_task_sdk_version,
+)
 from airflow_breeze.utils.console import Output, get_console
 from airflow_breeze.utils.helm_chart_utils import chart_version
 from airflow_breeze.utils.packages import get_provider_distributions_metadata, 
get_short_package_name
@@ -80,6 +85,8 @@ class DocsPublisher:
             return chart_version()
         if self.package_name == "apache-airflow-ctl":
             return get_airflowctl_version()
+        if self.package_name == "java-sdk":
+            return get_java_sdk_version()
         raise SystemExit(f"Unsupported package: {self.package_name}")
 
     @property
@@ -91,6 +98,13 @@ class DocsPublisher:
     def publish(self, override_versioned: bool, airflow_site_dir: str):
         """Copy documentation packages files to airflow-site repository."""
         get_console(output=self.output).print(f"Publishing docs for 
{self.package_name}")
+        # Nothing staged for this package: skip before _publish_dir resolves a 
version
+        # that may not be resolvable, and before an existing output dir is 
deleted below
+        # with nothing to replace it.
+        if not os.path.exists(self._build_dir):
+            get_console(output=self.output).print(f"Build directory 
{self._build_dir} does not exist!")
+            get_console(output=self.output).print()
+            return 0, f"Skipping {self.package_name}: Build directory does not 
exist"
         output_dir = os.path.join(airflow_site_dir, self._publish_dir)
         pretty_source = pretty_format_path(self._build_dir, os.getcwd())
         pretty_target = pretty_format_path(output_dir, airflow_site_dir)
@@ -108,10 +122,6 @@ class DocsPublisher:
                     return 1, f"Skipping {self.package_name}: Previously 
existing directory"
             # If output directory exists and is not versioned, delete it
             shutil.rmtree(output_dir)
-        if not os.path.exists(self._build_dir):
-            get_console(output=self.output).print(f"Build directory 
{self._build_dir} does not exist!")
-            get_console(output=self.output).print()
-            return 0, f"Skipping {self.package_name}: Build directory does not 
exist"
         shutil.copytree(self._build_dir, output_dir)
         if self.is_versioned:
             with open(os.path.join(output_dir, "..", "stable.txt"), "w") as 
stable_file:
diff --git a/dev/breeze/tests/test_docs_publisher.py 
b/dev/breeze/tests/test_docs_publisher.py
new file mode 100644
index 00000000000..45aa8a5228f
--- /dev/null
+++ b/dev/breeze/tests/test_docs_publisher.py
@@ -0,0 +1,106 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from pathlib import Path
+
+import pytest
+
+from airflow_breeze.utils import docs_publisher
+from airflow_breeze.utils.docs_publisher import DocsPublisher
+
+
[email protected]
+def generated_path(tmp_path, monkeypatch):
+    generated = tmp_path / "generated"
+    monkeypatch.setattr(docs_publisher, "GENERATED_PATH", generated)
+    return generated
+
+
[email protected]
+def airflow_site_dir(tmp_path):
+    site_dir = tmp_path / "airflow-site"
+    site_dir.mkdir()
+    return str(site_dir)
+
+
+def _stage_java_sdk_docs(generated_path: Path, version: str | None) -> None:
+    build_dir = generated_path / "_build" / "docs" / "java-sdk"
+    (build_dir / "stable").mkdir(parents=True)
+    (build_dir / "stable" / "index.html").write_text("docs")
+    if version:
+        (build_dir / "stable.txt").write_text(version + "\n")
+
+
+def test_publish_skips_package_without_staged_docs_before_resolving_version(
+    generated_path, airflow_site_dir, monkeypatch
+):
+    def fail_version_resolution():
+        raise SystemExit("Version must not be resolved when the docs were not 
staged")
+
+    monkeypatch.setattr(docs_publisher, "get_java_sdk_version", 
fail_version_resolution)
+    publisher = DocsPublisher(package_name="java-sdk", output=None, 
verbose=False)
+
+    return_code, message = publisher.publish(override_versioned=False, 
airflow_site_dir=airflow_site_dir)
+
+    assert return_code == 0
+    assert message == "Skipping java-sdk: Build directory does not exist"
+
+
+def test_publish_preserves_existing_docs_when_build_dir_missing(
+    generated_path, airflow_site_dir, monkeypatch
+):
+    # A previous version is already published to airflow-site, but nothing is 
staged
+    # for this run (build dir missing). Publishing with --override-versioned 
must not
+    # delete the existing docs when there is nothing to copy in their place.
+    monkeypatch.setattr(docs_publisher, "get_java_sdk_version", lambda: 
"1.2.3")
+    existing = Path(airflow_site_dir) / "docs-archive" / "java-sdk" / "1.2.3"
+    existing.mkdir(parents=True)
+    (existing / "index.html").write_text("previously published")
+
+    publisher = DocsPublisher(package_name="java-sdk", output=None, 
verbose=False)
+    return_code, message = publisher.publish(override_versioned=True, 
airflow_site_dir=airflow_site_dir)
+
+    assert (return_code, message) == (0, "Skipping java-sdk: Build directory 
does not exist")
+    assert (existing / "index.html").read_text() == "previously published"
+
+
+def test_publish_java_sdk_docs_with_staged_stable_txt(generated_path, 
airflow_site_dir):
+    _stage_java_sdk_docs(generated_path, version="1.2.3")
+    publisher = DocsPublisher(package_name="java-sdk", output=None, 
verbose=False)
+
+    return_code, message = publisher.publish(override_versioned=False, 
airflow_site_dir=airflow_site_dir)
+
+    assert (return_code, message) == (0, "Docs published: java-sdk")
+    java_sdk_archive = Path(airflow_site_dir) / "docs-archive" / "java-sdk"
+    assert (java_sdk_archive / "1.2.3" / "index.html").read_text() == "docs"
+    assert (java_sdk_archive / "stable.txt").read_text() == "1.2.3\n"
+
+
+def test_publish_java_sdk_version_falls_back_to_gradle_properties(
+    generated_path, airflow_site_dir, monkeypatch
+):
+    monkeypatch.setattr(docs_publisher, "get_java_sdk_version", lambda: 
"9.9.9")
+    _stage_java_sdk_docs(generated_path, version=None)
+    publisher = DocsPublisher(package_name="java-sdk", output=None, 
verbose=False)
+
+    return_code, message = publisher.publish(override_versioned=False, 
airflow_site_dir=airflow_site_dir)
+
+    assert (return_code, message) == (0, "Docs published: java-sdk")
+    java_sdk_archive = Path(airflow_site_dir) / "docs-archive" / "java-sdk"
+    assert (java_sdk_archive / "9.9.9" / "index.html").read_text() == "docs"
+    assert (java_sdk_archive / "stable.txt").read_text() == "9.9.9\n"
diff --git a/dev/breeze/tests/test_packages.py 
b/dev/breeze/tests/test_packages.py
index 2ce4db25463..60ded346be4 100644
--- a/dev/breeze/tests/test_packages.py
+++ b/dev/breeze/tests/test_packages.py
@@ -89,6 +89,7 @@ def test_get_short_package_name():
     assert get_short_package_name("apache-airflow") == "apache-airflow"
     assert get_short_package_name("docker-stack") == "docker-stack"
     assert get_short_package_name("task-sdk") == "task-sdk"
+    assert get_short_package_name("java-sdk") == "java-sdk"
     assert get_short_package_name("apache-airflow-providers-amazon") == 
"amazon"
     assert get_short_package_name("apache-airflow-providers-apache-hdfs") == 
"apache.hdfs"
 
@@ -102,6 +103,7 @@ def test_get_long_package_name():
     assert get_long_package_name("apache-airflow") == "apache-airflow"
     assert get_long_package_name("docker-stack") == "docker-stack"
     assert get_long_package_name("task-sdk") == "task-sdk"
+    assert get_long_package_name("java-sdk") == "java-sdk"
     assert get_long_package_name("amazon") == "apache-airflow-providers-amazon"
     assert get_long_package_name("apache.hdfs") == 
"apache-airflow-providers-apache-hdfs"
 
@@ -134,6 +136,7 @@ def test_get_suspended_provider_folders():
     ("short_packages", "filters", "long_packages"),
     [
         (("amazon",), (), ("apache-airflow-providers-amazon",)),
+        (("java-sdk",), (), ("java-sdk",)),
         (("apache.hdfs",), (), ("apache-airflow-providers-apache-hdfs",)),
         (
             ("apache.hdfs",),
diff --git a/dev/breeze/tests/test_release_management_commands.py 
b/dev/breeze/tests/test_release_management_commands.py
index 15148871f43..3e735222c22 100644
--- a/dev/breeze/tests/test_release_management_commands.py
+++ b/dev/breeze/tests/test_release_management_commands.py
@@ -21,10 +21,12 @@ from types import SimpleNamespace
 
 import pytest
 
+from airflow_breeze.commands import release_management_commands
 from airflow_breeze.commands.release_management_commands import (
     _ensure_default_python_for_reproducible_client,
     _is_initial_provider_release,
     _should_include_provider_in_issue,
+    get_package_version_possibly_from_stable_txt,
     get_prs_from_git_log_for_new_provider,
     get_suffix_from_package_in_dist,
     is_package_in_dist,
@@ -202,3 +204,22 @@ def test_is_package_in_dist(dist_files: list[str], 
package: str, expected: bool)
 )
 def test_get_suffix_from_package_in_dist(dist_files: list[str], package: str, 
expected: str | None):
     assert get_suffix_from_package_in_dist(dist_files, package) == expected
+
+
[email protected](
+    ("stable_txt_content", "expected_version"),
+    [
+        # No stable.txt staged (docs not built for this ref) -> None, not an 
error
+        (None, None),
+        ("0.1.0\n", "0.1.0"),
+    ],
+)
+def test_get_package_version_possibly_from_stable_txt_for_java_sdk(
+    tmp_path: Path, monkeypatch, stable_txt_content: str | None, 
expected_version: str | None
+):
+    monkeypatch.setattr(release_management_commands, "AIRFLOW_ROOT_PATH", 
tmp_path)
+    if stable_txt_content is not None:
+        stable_txt = tmp_path / "generated" / "_build" / "docs" / "java-sdk" / 
"stable.txt"
+        stable_txt.parent.mkdir(parents=True)
+        stable_txt.write_text(stable_txt_content)
+    assert get_package_version_possibly_from_stable_txt("java-sdk") == 
expected_version

Reply via email to