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

potiuk pushed a commit to branch fix-build-docs-python-version
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 3261fb43918787fd3d642502b66cb0fc501afcb4
Author: Jarek Potiuk <[email protected]>
AuthorDate: Tue Jul 28 22:29:07 2026 +0200

    Honour the selected Python version when building docs
    
    `breeze build-docs` always used the default Python version, so a docs
    build asked to run on a different version silently looked for an image
    that was never prepared for it. In the docs publishing workflow, which
    builds, stashes and loads a 3.12 CI image, that meant the docs step
    discarded it and started a full from-scratch 3.10 image build instead —
    wasting the better part of an hour and documenting against a different
    interpreter than the workflow intended.
    
    The publish job's own hardcoded Python version was stale for the same
    reason and now follows the workflow default like every other job there.
---
 .github/workflows/publish-docs-to-s3.yml           |  2 +-
 dev/breeze/doc/images/output_build-docs.svg        | 44 ++++++++------
 dev/breeze/doc/images/output_build-docs.txt        |  2 +-
 .../airflow_breeze/commands/developer_commands.py  |  8 ++-
 .../commands/developer_commands_config.py          |  1 +
 dev/breeze/tests/test_developer_commands.py        | 68 ++++++++++++++++++++++
 6 files changed, 103 insertions(+), 22 deletions(-)

diff --git a/.github/workflows/publish-docs-to-s3.yml 
b/.github/workflows/publish-docs-to-s3.yml
index da8c17f1085..6345afa84b6 100644
--- a/.github/workflows/publish-docs-to-s3.yml
+++ b/.github/workflows/publish-docs-to-s3.yml
@@ -499,7 +499,7 @@ jobs:
       GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       GITHUB_USERNAME: ${{ github.actor }}
       INCLUDE_SUCCESS_OUTPUTS: false
-      PYTHON_MAJOR_MINOR_VERSION: "3.10"
+      PYTHON_MAJOR_MINOR_VERSION: "${{ 
needs.build-info.outputs.default-python-version }}"
       VERBOSE: "true"
     steps:
       - name: "Cleanup repo"
diff --git a/dev/breeze/doc/images/output_build-docs.svg 
b/dev/breeze/doc/images/output_build-docs.svg
index 99bc5dbc0de..78ab4748143 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 1538.3999999999999" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 1587.1999999999998" 
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="1487.3999999999999" />
+      <rect x="0" y="0" width="1463.0" height="1536.1999999999998" />
     </clipPath>
     <clipPath id="breeze-build-docs-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -225,9 +225,15 @@
 <clipPath id="breeze-build-docs-line-59">
     <rect x="0" y="1441.1" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-build-docs-line-60">
+    <rect x="0" y="1465.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-build-docs-line-61">
+    <rect x="0" y="1489.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="1536.4" rx="8"/><text 
class="breeze-build-docs-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;build-docs</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="1585.2" rx="8"/><text 
class="breeze-build-docs-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;build-docs</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -283,21 +289,23 @@
 </text><text class="breeze-build-docs-r5" x="0" y="1069.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-43)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1069.2" textLength="353.8" 
clip-path="url(#breeze-build-docs-line-43)">--include-removed-providers&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="402.6" y="1069.2" textLength="561.2" 
clip-path="url(#breeze-build-docs-line-43)">Whether&#160;to&#160;include&#160;providers&#160;that&#160;are&#160;removed.</te
 [...]
 </text><text class="breeze-build-docs-r5" x="0" y="1093.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-44)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1093.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-44)">
 </text><text class="breeze-build-docs-r5" x="0" y="1118" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-45)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1118" textLength="170.8" 
clip-path="url(#breeze-build-docs-line-45)">&#160;Misc&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="195.2" y="1118" textLength="1244.4" 
clip-path="url(#breeze-build-docs-line-45)">──────────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-46)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1142.4" textLength="244" 
clip-path="url(#breeze-build-docs-line-46)">--include-commits&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1142.4" textLength="451.4" 
clip-path="url(#breeze-build-docs-line-46)">Include&#160;commits&#160;in&#160;the&#160;documentation.</text><text
 class="breeze-bu [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-47)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1166.8" textLength="244" 
clip-path="url(#breeze-build-docs-line-47)">--github-repository&#160;</text><text
 class="breeze-build-docs-r6" x="292.8" y="1166.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-47)">-g</text><text 
class="breeze-build-docs-r1" x="341.6" y="1166.8" textLength="597.8" 
clip-path="ur [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1191.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-48)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1191.2" textLength="244" 
clip-path="url(#breeze-build-docs-line-48)">--builder&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1191.2" textLength="768.6" 
clip-path="url(#breeze-build-docs-line-48)">Buildx&#160;builder&#160;used&#160;to&#160;per
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-49)">│</text><text 
class="breeze-build-docs-r7" x="341.6" y="1215.6" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-49)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-49)">│</text><text 
class="breeze-build-docs-r1" x="1464" y="1215.6" textLength="12.2" 
clip-path="url(#breeze-build-doc [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1240" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-50)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1240" textLength="244" 
clip-path="url(#breeze-build-docs-line-50)">--distributions-list</text><text 
class="breeze-build-docs-r1" x="341.6" y="1240" textLength="1098" 
clip-path="url(#breeze-build-docs-line-50)">Optional,&#160;contains&#160;space&#160;separated&#160;list&#160;of&#160;package&#160;ids&#160;that&#160;are
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-51)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1264.4" textLength="1098" 
clip-path="url(#breeze-build-docs-line-51)">documentation&#160;building,&#160;and&#160;document&#160;publishing.&#160;It&#160;is&#160;an&#160;easier&#160;alternative&#160;to&#160;adding&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1264.4" textLength="12.2 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1288.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-52)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1288.8" textLength="1098" 
clip-path="url(#breeze-build-docs-line-52)">individual&#160;packages&#160;as&#160;arguments&#160;to&#160;every&#160;command.&#160;This&#160;overrides&#160;the&#160;packages&#160;passed&#160;as&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1288.8" textLength="12.2" cli [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1313.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-53)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1313.2" textLength="134.2" 
clip-path="url(#breeze-build-docs-line-53)">arguments.&#160;</text><text 
class="breeze-build-docs-r7" x="475.8" y="1313.2" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-53)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1313.2" textLength="12.2" 
clip-path="url( [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1337.6" textLength="1464" 
clip-path="url(#breeze-build-docs-line-54)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1337.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-54)">
-</text><text class="breeze-build-docs-r5" x="0" y="1362" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-55)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1362" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-55)">&#160;Common&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="219.6" y="1362" textLength="1220" 
clip-path="url(#breeze-build-docs-line-55)">──────────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1386.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-56)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1386.4" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-56)">--dry-run</text><text 
class="breeze-build-docs-r6" x="158.6" y="1386.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-56)">-D</text><text 
class="breeze-build-docs-r1" x="207.4" y="1386.4" textLength="719.8" 
clip-path="url(#breeze-buil [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1410.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-57)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1410.8" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-57)">--verbose</text><text 
class="breeze-build-docs-r6" x="158.6" y="1410.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-57)">-v</text><text 
class="breeze-build-docs-r1" x="207.4" y="1410.8" textLength="585.6" 
clip-path="url(#breeze-buil [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1435.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-58)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1435.2" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-58)">--answer&#160;</text><text 
class="breeze-build-docs-r6" x="158.6" y="1435.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-58)">-a</text><text 
class="breeze-build-docs-r1" x="207.4" y="1435.2" textLength="329.4" 
clip-path="url(#breeze [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1459.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-59)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1459.6" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-59)">--help&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r6" x="158.6" y="1459.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-59)">-h</text><text 
class="breeze-build-docs-r1" x="207.4" y="1459.6" textLength="329.4" 
clip-path="u [...]
-</text><text class="breeze-build-docs-r5" x="0" y="1484" textLength="1464" 
clip-path="url(#breeze-build-docs-line-60)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1484" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-60)">
+</text><text class="breeze-build-docs-r5" x="0" y="1142.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-46)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1142.4" textLength="244" 
clip-path="url(#breeze-build-docs-line-46)">--python&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r6" x="292.8" y="1142.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-46)">-p</text><text 
class="breeze-build-docs-r1 [...]
+</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="317.2" 
clip-path="url(#breeze-build-docs-line-47)">3.11&#160;|&#160;3.12&#160;|&#160;3.13&#160;|&#160;3.14)</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1166.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-47)">│</text><text 
class="breeze-build-docs-r1" x="1464" y="1166.8" [...]
+</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)">--include-commits&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1191.2" textLength="451.4" 
clip-path="url(#breeze-build-docs-line-48)">Include&#160;commits&#160;in&#160;the&#160;documentation.</text><text
 class="breeze-bu [...]
+</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-r4" x="24.4" y="1215.6" textLength="244" 
clip-path="url(#breeze-build-docs-line-49)">--github-repository&#160;</text><text
 class="breeze-build-docs-r6" x="292.8" y="1215.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-49)">-g</text><text 
class="breeze-build-docs-r1" x="341.6" y="1215.6" textLength="597.8" 
clip-path="ur [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1240" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-50)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1240" textLength="244" 
clip-path="url(#breeze-build-docs-line-50)">--builder&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r1" x="341.6" y="1240" textLength="768.6" 
clip-path="url(#breeze-build-docs-line-50)">Buildx&#160;builder&#160;used&#160;to&#160;perform&#
 [...]
+</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-r7" x="341.6" y="1264.4" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-51)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-51)">│</text><text 
class="breeze-build-docs-r1" x="1464" y="1264.4" textLength="12.2" 
clip-path="url(#breeze-build-doc [...]
+</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="244" 
clip-path="url(#breeze-build-docs-line-52)">--distributions-list</text><text 
class="breeze-build-docs-r1" x="341.6" y="1288.8" textLength="1098" 
clip-path="url(#breeze-build-docs-line-52)">Optional,&#160;contains&#160;space&#160;separated&#160;list&#160;of&#160;package&#160;ids&#160;that&#1
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1313.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-53)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1313.2" textLength="1098" 
clip-path="url(#breeze-build-docs-line-53)">documentation&#160;building,&#160;and&#160;document&#160;publishing.&#160;It&#160;is&#160;an&#160;easier&#160;alternative&#160;to&#160;adding&#160;&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1313.2" textLength="12.2 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1337.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-54)">│</text><text 
class="breeze-build-docs-r1" x="341.6" y="1337.6" textLength="1098" 
clip-path="url(#breeze-build-docs-line-54)">individual&#160;packages&#160;as&#160;arguments&#160;to&#160;every&#160;command.&#160;This&#160;overrides&#160;the&#160;packages&#160;passed&#160;as&#160;&#160;</text><text
 class="breeze-build-docs-r5" x="1451.8" y="1337.6" textLength="12.2" cli [...]
+</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-r1" x="341.6" y="1362" textLength="134.2" 
clip-path="url(#breeze-build-docs-line-55)">arguments.&#160;</text><text 
class="breeze-build-docs-r7" x="475.8" y="1362" textLength="73.2" 
clip-path="url(#breeze-build-docs-line-55)">(TEXT)</text><text 
class="breeze-build-docs-r5" x="1451.8" y="1362" textLength="12.2" 
clip-path="url(#breeze- [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1386.4" textLength="1464" 
clip-path="url(#breeze-build-docs-line-56)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1386.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-56)">
+</text><text class="breeze-build-docs-r5" x="0" y="1410.8" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-57)">╭─</text><text 
class="breeze-build-docs-r5" x="24.4" y="1410.8" textLength="195.2" 
clip-path="url(#breeze-build-docs-line-57)">&#160;Common&#160;options&#160;</text><text
 class="breeze-build-docs-r5" x="219.6" y="1410.8" textLength="1220" 
clip-path="url(#breeze-build-docs-line-57)">────────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1435.2" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-58)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1435.2" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-58)">--dry-run</text><text 
class="breeze-build-docs-r6" x="158.6" y="1435.2" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-58)">-D</text><text 
class="breeze-build-docs-r1" x="207.4" y="1435.2" textLength="719.8" 
clip-path="url(#breeze-buil [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1459.6" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-59)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1459.6" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-59)">--verbose</text><text 
class="breeze-build-docs-r6" x="158.6" y="1459.6" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-59)">-v</text><text 
class="breeze-build-docs-r1" x="207.4" y="1459.6" textLength="585.6" 
clip-path="url(#breeze-buil [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1484" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-60)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1484" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-60)">--answer&#160;</text><text 
class="breeze-build-docs-r6" x="158.6" y="1484" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-60)">-a</text><text 
class="breeze-build-docs-r1" x="207.4" y="1484" textLength="329.4" 
clip-path="url(#breeze-build-d [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1508.4" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-61)">│</text><text 
class="breeze-build-docs-r4" x="24.4" y="1508.4" textLength="109.8" 
clip-path="url(#breeze-build-docs-line-61)">--help&#160;&#160;&#160;</text><text
 class="breeze-build-docs-r6" x="158.6" y="1508.4" textLength="24.4" 
clip-path="url(#breeze-build-docs-line-61)">-h</text><text 
class="breeze-build-docs-r1" x="207.4" y="1508.4" textLength="329.4" 
clip-path="u [...]
+</text><text class="breeze-build-docs-r5" x="0" y="1532.8" textLength="1464" 
clip-path="url(#breeze-build-docs-line-62)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-build-docs-r1" x="1464" y="1532.8" textLength="12.2" 
clip-path="url(#breeze-build-docs-line-62)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_build-docs.txt 
b/dev/breeze/doc/images/output_build-docs.txt
index 75dd9355bcf..cc79708d4cd 100644
--- a/dev/breeze/doc/images/output_build-docs.txt
+++ b/dev/breeze/doc/images/output_build-docs.txt
@@ -1 +1 @@
-e22969fb5e92a3efafb744881fea5ef8
+c6881341938aadc0176ded803153998d
diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py 
b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
index 29df6c2111b..0233a6919b0 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
@@ -814,6 +814,7 @@ def _build_python_docs(
     *,
     generated_path: Path,
     builder: str,
+    python: str,
     clean_build: bool,
     clean_inventory_cache: bool,
     refresh_airflow_inventories: bool,
@@ -831,7 +832,7 @@ def _build_python_docs(
 ):
     build_params = BuildCiParams(
         github_repository=github_repository,
-        python=DEFAULT_PYTHON_MAJOR_MINOR_VERSION,
+        python=python,
         builder=builder,
     )
     rebuild_or_pull_ci_image_if_needed(command_params=build_params)
@@ -886,7 +887,7 @@ def _build_python_docs(
     )
     shell_params = ShellParams(
         github_repository=github_repository,
-        python=DEFAULT_PYTHON_MAJOR_MINOR_VERSION,
+        python=python,
         mount_sources=MOUNT_ALL,
     )
     result = execute_command_in_shell(shell_params, 
project_name="breeze-docs", command=cmd)
@@ -933,6 +934,7 @@ def _build_python_docs(
 @option_github_repository
 @option_include_not_ready_providers
 @option_include_removed_providers
+@option_python
 @click.option(
     "--one-pass-only",
     help="Builds documentation in one pass only. This is useful for debugging 
sphinx errors.",
@@ -977,6 +979,7 @@ def build_docs(
     include_commits: bool,
     one_pass_only: bool,
     package_filter: tuple[str, ...],
+    python: str,
     distributions_list: str,
     spellcheck_only: bool,
     sdk: tuple[str, ...],
@@ -1007,6 +1010,7 @@ def build_docs(
             include_commits=include_commits,
             one_pass_only=one_pass_only,
             package_filter=package_filter,
+            python=python,
             distributions_list=distributions_list,
             spellcheck_only=spellcheck_only,
             doc_packages=doc_packages,
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 17d32146110..f3816139abe 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
@@ -385,6 +385,7 @@ DEVELOPER_PARAMETERS: dict[str, list[dict[str, str | 
list[str]]]] = {
         {
             "name": "Misc options",
             "options": [
+                "--python",
                 "--include-commits",
                 "--github-repository",
                 "--builder",
diff --git a/dev/breeze/tests/test_developer_commands.py 
b/dev/breeze/tests/test_developer_commands.py
new file mode 100644
index 00000000000..d5b0ca1a070
--- /dev/null
+++ b/dev/breeze/tests/test_developer_commands.py
@@ -0,0 +1,68 @@
+# 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 unittest.mock import patch
+
+import pytest
+from click.testing import CliRunner
+
+from airflow_breeze.commands.developer_commands import build_docs
+
+
[email protected]
+def runner():
+    return CliRunner()
+
+
+class TestBuildDocsPythonVersion:
+    """`breeze build-docs` must document with the Python version it was asked 
for."""
+
+    @pytest.fixture(autouse=True)
+    def _no_docker(self, monkeypatch):
+        monkeypatch.setenv("SKIP_SAVING_CHOICES", "true")
+        for name in (
+            "perform_environment_checks",
+            "fix_ownership_using_docker",
+            "cleanup_python_generated_files",
+        ):
+            
monkeypatch.setattr(f"airflow_breeze.commands.developer_commands.{name}", 
lambda *a, **kw: None)
+
+    def _invoke(self, runner: CliRunner, args: list[str], env: dict[str, str] 
| None = None):
+        with (
+            patch(
+                
"airflow_breeze.commands.developer_commands.rebuild_or_pull_ci_image_if_needed"
+            ) as mock_rebuild,
+            
patch("airflow_breeze.commands.developer_commands.execute_command_in_shell") as 
mock_shell,
+        ):
+            mock_shell.return_value.returncode = 0
+            runner.invoke(build_docs, args, env=env, catch_exceptions=False)
+        return mock_rebuild, mock_shell
+
+    @pytest.mark.parametrize(
+        ("args", "env"),
+        [
+            pytest.param(["--python", "3.12"], None, id="python-option"),
+            pytest.param([], {"PYTHON_MAJOR_MINOR_VERSION": "3.12"}, 
id="python-env-var"),
+        ],
+    )
+    def test_selected_python_is_used_for_image_and_shell(self, runner, args, 
env):
+        mock_rebuild, mock_shell = self._invoke(runner, [*args, 
"--docs-only"], env=env)
+
+        assert mock_rebuild.call_args.kwargs["command_params"].python == "3.12"
+        assert mock_shell.call_args.args[0].python == "3.12"

Reply via email to