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

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


The following commit(s) were added to refs/heads/v3-2-test by this push:
     new 2eeff98486f [v3-2-test] Replace upgrade-check build failure with 
scheduled upgrade PR workflow (#64836) (#64915)
2eeff98486f is described below

commit 2eeff98486f794b014bd5ba74aeea5ecafca55a7
Author: Jarek Potiuk <[email protected]>
AuthorDate: Wed Apr 8 22:41:55 2026 +0300

    [v3-2-test] Replace upgrade-check build failure with scheduled upgrade PR 
workflow (#64836) (#64915)
    
    Move upgrade checks from basic-tests.yml (where they failed the build)
    to a scheduled workflow that runs Mon/Wed/Fri for main and Tue/Thu for
    v3-2-test. The workflow uses `breeze ci upgrade` to run all upgrade
    steps and create a draft PR. A Slack notification is sent to
    #internal-airflow-ci-cd when a PR needs review.
    
    Changes:
    - Remove upgrade-check job from basic-tests.yml
    - Add reusable upgrade-check.yml workflow (workflow_call)
    - Add scheduled-upgrade-check.yml caller (cron + workflow_dispatch)
    - Enhance breeze ci upgrade: --draft flag, stable branch naming,
      existing PR detection, no -w flag for CI compatibility
    (cherry picked from commit dd0ff5ad8d288401e261cb2e7fa2b971abc6f58e)
---
 .github/workflows/basic-tests.yml                  |  83 --------------
 .github/workflows/scheduled-upgrade-check-main.yml |  34 ++++++
 .../scheduled-upgrade-check-v3-2-test.yml          |  34 ++++++
 .github/workflows/upgrade-check.yml                | 125 +++++++++++++++++++++
 dev/breeze/doc/images/output_ci_upgrade.svg        |  68 ++++++-----
 dev/breeze/doc/images/output_ci_upgrade.txt        |   2 +-
 .../src/airflow_breeze/commands/ci_commands.py     |  97 ++++++++++++----
 .../airflow_breeze/commands/ci_commands_config.py  |   1 +
 8 files changed, 311 insertions(+), 133 deletions(-)

diff --git a/.github/workflows/basic-tests.yml 
b/.github/workflows/basic-tests.yml
index 7b71ae5c6e6..86360ee6def 100644
--- a/.github/workflows/basic-tests.yml
+++ b/.github/workflows/basic-tests.yml
@@ -301,89 +301,6 @@ jobs:
           fetch-depth: 2
           persist-credentials: false
 
-  upgrade-check:
-    timeout-minutes: 45
-    name: "Upgrade checks"
-    runs-on: ${{ fromJSON(inputs.runners) }}
-    env:
-      PYTHON_MAJOR_MINOR_VERSION: "${{ inputs.default-python-version }}"
-    if: inputs.canary-run == 'true'
-    steps:
-      - name: "Cleanup repo"
-        shell: bash
-        run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm 
-rf /workspace/*"
-      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # 
v6.0.2
-        with:
-          persist-credentials: false
-      - name: "Install Breeze"
-        uses: ./.github/actions/breeze
-        id: breeze
-      - name: "Install prek"
-        uses: ./.github/actions/install-prek
-        id: prek
-        with:
-          python-version: ${{ steps.breeze.outputs.host-python-version }}
-          platform: ${{ inputs.platform }}
-          save-cache: false
-      - name: "Autoupdate all prek hooks"
-        run: prek autoupdate --cooldown-days 4 --freeze
-      - name: "Check if there are any changes in prek hooks"
-        run: |
-          if ! git diff --exit-code; then
-            echo -e "\n\033[0;31mThere are changes in prek hooks after upgrade 
check.\033[0m"
-            echo -e "\n\033[0;33mHow to fix:\033[0m Run \`breeze ci upgrade\` 
locally to fix it!.\n"
-            exit 1
-          fi
-      - name: "Run automated upgrade for chart dependencies"
-        run: >
-          prek
-          --all-files --show-diff-on-failure --color always --verbose
-          --stage manual
-          update-chart-dependencies
-        if: always()
-      # For UV we are not failing the upgrade installers check if it is 
updated because
-      # it is upgraded very frequently, so we want to manually upgrade it 
rather than
-      # get notified about it - until it stabilizes in 1.* version
-      - name: "Run automated upgrade for uv,  prek (not failing - just 
informational)"
-        run: >
-          prek
-          --all-files --show-diff-on-failure --color always --verbose
-          --stage manual upgrade-important-versions || true
-        if: always()
-        env:
-          UPGRADE_FLIT: "false"
-          UPGRADE_GITPYTHON: "false"
-          UPGRADE_GOLANG: "false"
-          UPGRADE_HATCH: "false"
-          UPGRADE_HATCHLING: "false"
-          UPGRADE_MYPY: "false"
-          UPGRADE_NODE_LTS: "false"
-          UPGRADE_PIP: "false"
-          UPGRADE_PYTHON: "false"
-          UPGRADE_PYYAML: "false"
-          UPGRADE_RICH: "false"
-          UPGRADE_RUFF: "false"
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-      - name: "Run automated upgrade for important versions minus uv (failing 
if needed)"
-        run: |
-          if ! prek \
-            --all-files --show-diff-on-failure --color always --verbose \
-            --stage manual upgrade-important-versions; then
-              echo -e "\n\033[0;31mThere are changes in prek hooks after 
upgrade check.\033[0m"
-              echo -e "\n\033[0;33mHow to fix:\033[0m Run \`breeze ci 
upgrade\` locally to fix it!.\n"
-              exit 1
-          fi
-        if: always()
-        env:
-          UPGRADE_UV: "false"
-          UPGRADE_PREK: "false"
-          UPGRADE_MPROCS: "false"
-          UPGRADE_PROTOC: "false"
-          UPGRADE_OPENAPI_GENERATOR: "false"
-          UPGRADE_COOLDOWN_DAYS: "4"
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
   test-airflow-release-commands:
     timeout-minutes: 80
     name: "Test Airflow release commands"
diff --git a/.github/workflows/scheduled-upgrade-check-main.yml 
b/.github/workflows/scheduled-upgrade-check-main.yml
new file mode 100644
index 00000000000..5978721b971
--- /dev/null
+++ b/.github/workflows/scheduled-upgrade-check-main.yml
@@ -0,0 +1,34 @@
+# 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.
+#
+---
+name: "[main] Scheduled CI upgrade check"
+on:  # yamllint disable-line rule:truthy
+  schedule:
+    # Mon, Wed, Fri at 06:00 UTC
+    - cron: '0 6 * * 1,3,5'
+  workflow_dispatch:
+permissions:
+  contents: read
+jobs:
+  upgrade-main:
+    name: "[main] Upgrade"
+    uses: ./.github/workflows/upgrade-check.yml
+    with:
+      target-branch: main
+    secrets:
+      SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
diff --git a/.github/workflows/scheduled-upgrade-check-v3-2-test.yml 
b/.github/workflows/scheduled-upgrade-check-v3-2-test.yml
new file mode 100644
index 00000000000..268dd798f2e
--- /dev/null
+++ b/.github/workflows/scheduled-upgrade-check-v3-2-test.yml
@@ -0,0 +1,34 @@
+# 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.
+#
+---
+name: "[v3-2-test] Scheduled CI upgrade check"
+on:  # yamllint disable-line rule:truthy
+  schedule:
+    # Tue, Thu at 06:00 UTC
+    - cron: '0 6 * * 2,4'
+  workflow_dispatch:
+permissions:
+  contents: read
+jobs:
+  upgrade-v3-2-test:
+    name: "[v3-2-test] Upgrade"
+    uses: ./.github/workflows/upgrade-check.yml
+    with:
+      target-branch: v3-2-test
+    secrets:
+      SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
diff --git a/.github/workflows/upgrade-check.yml 
b/.github/workflows/upgrade-check.yml
new file mode 100644
index 00000000000..55a7383665e
--- /dev/null
+++ b/.github/workflows/upgrade-check.yml
@@ -0,0 +1,125 @@
+# 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.
+#
+---
+name: Upgrade check
+on:  # yamllint disable-line rule:truthy
+  workflow_call:
+    inputs:
+      target-branch:
+        description: >-
+          Branch to upgrade (e.g. 'main' or 'v3-2-test')
+        required: true
+        type: string
+    secrets:
+      SLACK_BOT_TOKEN:
+        description: "Slack bot token for notifications"
+        required: true
+permissions:
+  contents: write
+  pull-requests: write
+env:
+  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+  SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
+  TARGET_BRANCH: ${{ inputs.target-branch }}
+jobs:
+  createupgrade-check:
+    timeout-minutes: 45
+    name: >-
+      [${{ inputs.target-branch }}] Upgrade checks and PR
+    runs-on: ["ubuntu-22.04"]
+    steps:
+      - name: >-
+          [${{ inputs.target-branch }}] Cleanup repo
+        shell: bash
+        run: >
+          docker run -v "${GITHUB_WORKSPACE}:/workspace"
+          -u 0:0 bash -c "rm -rf /workspace/*"
+      - name: >-
+          [${{ inputs.target-branch }}] Checkout
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # 
v6.0.2
+        with:
+          ref: ${{ inputs.target-branch }}
+          fetch-depth: 0
+          persist-credentials: false
+      - name: >-
+          [${{ inputs.target-branch }}] Configure git credentials
+        run: |
+          git remote set-url origin \
+            
"https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git";
+          git config user.name "github-actions[bot]"
+          git config user.email \
+            "41898282+github-actions[bot]@users.noreply.github.com"
+      - name: >-
+          [${{ inputs.target-branch }}] Install Breeze
+        uses: ./.github/actions/breeze
+        id: breeze
+      - name: >-
+          [${{ inputs.target-branch }}] Install prek
+        uses: ./.github/actions/install-prek
+        id: prek
+        with:
+          python-version: >-
+            ${{ steps.breeze.outputs.host-python-version }}
+          platform: "linux/amd64"
+          save-cache: false
+      - name: >-
+          [${{ inputs.target-branch }}] Run breeze ci upgrade
+        run: >
+          breeze ci upgrade
+          --target-branch "${TARGET_BRANCH}"
+          --create-pr
+          --draft
+          --switch-to-base
+          --no-k8s-schema-sync
+          --answer yes
+      - name: >-
+          [${{ inputs.target-branch }}] Find upgrade PR
+        id: find-pr
+        run: |
+          PR_URL=$(gh pr list \
+            --repo "${GITHUB_REPOSITORY}" \
+            --head "ci-upgrade-${TARGET_BRANCH}" \
+            --base "${TARGET_BRANCH}" \
+            --state open \
+            --json url \
+            --jq '.[0].url' 2>/dev/null || true)
+          echo "pr-url=${PR_URL}" >> "${GITHUB_OUTPUT}"
+      - name: >-
+          [${{ inputs.target-branch }}] Notify Slack
+        if: steps.find-pr.outputs.pr-url != ''
+        uses: >-
+          slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95
+        with:
+          method: chat.postMessage
+          token: ${{ env.SLACK_BOT_TOKEN }}
+          payload: |
+            channel: "internal-airflow-ci-cd"
+            text: >-
+              🔧 [${{ inputs.target-branch }}] CI upgrade PR
+              ready for review. Please undraft, review and
+              merge: ${{ steps.find-pr.outputs.pr-url }}
+            blocks:
+              - type: section
+                text:
+                  type: mrkdwn
+                  text: >-
+                    🔧 *[${{ inputs.target-branch }}] CI upgrade
+                    PR ready for review*
+
+                    Please undraft, review and merge:
+                    <${{ steps.find-pr.outputs.pr-url }}|View PR>
diff --git a/dev/breeze/doc/images/output_ci_upgrade.svg 
b/dev/breeze/doc/images/output_ci_upgrade.svg
index 5370d25bff3..4dd0007a643 100644
--- a/dev/breeze/doc/images/output_ci_upgrade.svg
+++ b/dev/breeze/doc/images/output_ci_upgrade.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 952.8" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 1482 1001.5999999999999" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-ci-upgrade-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="901.8" />
+      <rect x="0" y="0" width="1463.0" height="950.5999999999999" />
     </clipPath>
     <clipPath id="breeze-ci-upgrade-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -153,9 +153,15 @@
 <clipPath id="breeze-ci-upgrade-line-35">
     <rect x="0" y="855.5" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-ci-upgrade-line-36">
+    <rect x="0" y="879.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-ci-upgrade-line-37">
+    <rect x="0" y="904.3" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="950.8" rx="8"/><text 
class="breeze-ci-upgrade-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;ci&#160;upgrade</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="1480" height="999.6" rx="8"/><text 
class="breeze-ci-upgrade-title" fill="#c5c8c6" text-anchor="middle" x="740" 
y="27">Command:&#160;ci&#160;upgrade</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -175,33 +181,35 @@
 </text><text class="breeze-ci-upgrade-r5" x="0" y="190.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-7)">│</text><text 
class="breeze-ci-upgrade-r5" x="488" y="190.8" textLength="122" 
clip-path="url(#breeze-ci-upgrade-line-7)">v3-2-test]</text><text 
class="breeze-ci-upgrade-r6" x="622.2" y="190.8" textLength="73.2" 
clip-path="url(#breeze-ci-upgrade-line-7)">(TEXT)</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="190.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrad [...]
 </text><text class="breeze-ci-upgrade-r5" x="0" y="215.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-8)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="215.2" textLength="134.2" 
clip-path="url(#breeze-ci-upgrade-line-8)">--create-pr</text><text 
class="breeze-ci-upgrade-r1" x="158.6" y="215.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-8)">/</text><text 
class="breeze-ci-upgrade-r4" x="170.8" y="215.2" textLength="170.8" 
clip-path="url(#breeze-ci-upgrade [...]
 </text><text class="breeze-ci-upgrade-r5" x="0" y="239.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-9)">│</text><text 
class="breeze-ci-upgrade-r1" x="488" y="239.6" textLength="951.6" 
clip-path="url(#breeze-ci-upgrade-line-9)">ask)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
 [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="264" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-10)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="264" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-10)">--switch-to-base</text><text 
class="breeze-ci-upgrade-r1" x="219.6" y="264" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-10)">/</text><text 
class="breeze-ci-upgrade-r4" x="231.8" y="264" textLength="231.8" 
clip-path="url(#breeze-ci-upgrade [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="288.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-11)">│</text><text 
class="breeze-ci-upgrade-r1" x="488" y="288.4" textLength="951.6" 
clip-path="url(#breeze-ci-upgrade-line-11)">specified,&#160;will&#160;ask)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="312.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-12)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="312.8" textLength="439.2" 
clip-path="url(#breeze-ci-upgrade-line-12)">--airflow-site&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r1" x="488" y="312.8" textLength="695.4" 
clip-path="url(#breeze [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="337.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-13)">│</text><text 
class="breeze-ci-upgrade-r5" x="488" y="337.2" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-13)">../airflow-site]</text><text 
class="breeze-ci-upgrade-r6" x="695.4" y="337.2" textLength="134.2" 
clip-path="url(#breeze-ci-upgrade-line-13)">(DIRECTORY)</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="337.2" textLength="12.2" 
clip-path="url( [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="361.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-14)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="361.6" textLength="439.2" 
clip-path="url(#breeze-ci-upgrade-line-14)">--force-k8s-schema-sync&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r1" x="488" y="361.6" textLength="951.6" 
clip-path="url(#breeze-ci-upgrade-line-14)">Force&#160;syncing&#160 [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="386" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-15)">│</text><text 
class="breeze-ci-upgrade-r1" x="488" y="386" textLength="951.6" 
clip-path="url(#breeze-ci-upgrade-line-15)">published&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1
 [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="410.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-16)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="410.4" textLength="439.2" 
clip-path="url(#breeze-ci-upgrade-line-16)">--github-token&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r1" x="488" y="410.4" textLength="512.4" 
clip-path="url(#breeze [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="434.8" textLength="1464" 
clip-path="url(#breeze-ci-upgrade-line-17)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-ci-upgrade-r1" x="1464" y="434.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-17)">
-</text><text class="breeze-ci-upgrade-r5" x="0" y="459.2" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-18)">╭─</text><text 
class="breeze-ci-upgrade-r5" x="24.4" y="459.2" textLength="183" 
clip-path="url(#breeze-ci-upgrade-line-18)">&#160;Upgrade&#160;steps&#160;</text><text
 class="breeze-ci-upgrade-r5" x="207.4" y="459.2" textLength="1232.2" 
clip-path="url(#breeze-ci-upgrade-line-18)">────────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="483.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-19)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="483.6" textLength="146.4" 
clip-path="url(#breeze-ci-upgrade-line-19)">--autoupdate</text><text 
class="breeze-ci-upgrade-r1" x="170.8" y="483.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-19)">/</text><text 
class="breeze-ci-upgrade-r4" x="183" y="483.6" textLength="183" 
clip-path="url(#breeze-ci-upgrade [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="508" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-20)">│</text><text 
class="breeze-ci-upgrade-r5" x="744.2" y="508" textLength="134.2" 
clip-path="url(#breeze-ci-upgrade-line-20)">autoupdate]</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="508" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-20)">│</text><text 
class="breeze-ci-upgrade-r1" x="1464" y="508" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-20)">
-</text><text class="breeze-ci-upgrade-r5" x="0" y="532.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-21)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="532.4" textLength="329.4" 
clip-path="url(#breeze-ci-upgrade-line-21)">--update-chart-dependencies</text><text
 class="breeze-ci-upgrade-r1" x="353.8" y="532.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-21)">/</text><text 
class="breeze-ci-upgrade-r4" x="366" y="532.4" textLength="353.8" 
clip-path="url(# [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="556.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-22)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="556.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-22)">s</text><text 
class="breeze-ci-upgrade-r1" x="744.2" y="556.8" textLength="158.6" 
clip-path="url(#breeze-ci-upgrade-line-22)">dependencies&#160;</text><text 
class="breeze-ci-upgrade-r5" x="902.8" y="556.8" textLength="439.2" 
clip-path="url(#breeze- [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="581.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-23)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="581.2" textLength="341.6" 
clip-path="url(#breeze-ci-upgrade-line-23)">--upgrade-important-versions</text><text
 class="breeze-ci-upgrade-r1" x="366" y="581.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-23)">/</text><text 
class="breeze-ci-upgrade-r4" x="378.2" y="581.2" textLength="341.6" 
clip-path="url( [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="605.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-24)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="605.6" textLength="36.6" 
clip-path="url(#breeze-ci-upgrade-line-24)">ons</text><text 
class="breeze-ci-upgrade-r1" x="744.2" y="605.6" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-24)">versions&#160;</text><text 
class="breeze-ci-upgrade-r5" x="854" y="605.6" textLength="451.4" 
clip-path="url(#breeze-ci-u [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="630" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-25)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="630" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-25)">--update-uv-lock</text><text 
class="breeze-ci-upgrade-r1" x="219.6" y="630" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-25)">/</text><text 
class="breeze-ci-upgrade-r4" x="231.8" y="630" textLength="231.8" 
clip-path="url(#breeze-ci-upgrade [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="654.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-26)">│</text><text 
class="breeze-ci-upgrade-r1" x="744.2" y="654.4" textLength="427" 
clip-path="url(#breeze-ci-upgrade-line-26)">resolutions&#160;inside&#160;Breeze&#160;CI&#160;image&#160;</text><text
 class="breeze-ci-upgrade-r5" x="1171.2" y="654.4" textLength="122" 
clip-path="url(#breeze-ci-upgrade-line-26)">[default:&#160;</text><text 
class="breeze-ci-upgrade-r5" x="1451 [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="678.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-27)">│</text><text 
class="breeze-ci-upgrade-r5" x="744.2" y="678.8" textLength="183" 
clip-path="url(#breeze-ci-upgrade-line-27)">update-uv-lock]</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="678.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-27)">│</text><text 
class="breeze-ci-upgrade-r1" x="1464" y="678.8" textLength="12.2" 
clip-path="url(#breeze-ci-up [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="703.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-28)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="703.2" textLength="207.4" 
clip-path="url(#breeze-ci-upgrade-line-28)">--k8s-schema-sync</text><text 
class="breeze-ci-upgrade-r1" x="231.8" y="703.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-28)">/</text><text 
class="breeze-ci-upgrade-r4" x="244" y="703.2" textLength="244" 
clip-path="url(#breeze-ci-up [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="727.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-29)">│</text><text 
class="breeze-ci-upgrade-r5" x="744.2" y="727.6" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-29)">k8s-schema-sync]</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="727.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-29)">│</text><text 
class="breeze-ci-upgrade-r1" x="1464" y="727.6" textLength="12.2" 
clip-path="url(#breeze-ci [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="752" textLength="1464" 
clip-path="url(#breeze-ci-upgrade-line-30)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-ci-upgrade-r1" x="1464" y="752" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-30)">
-</text><text class="breeze-ci-upgrade-r5" x="0" y="776.4" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-31)">╭─</text><text 
class="breeze-ci-upgrade-r5" x="24.4" y="776.4" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-31)">&#160;Common&#160;options&#160;</text><text
 class="breeze-ci-upgrade-r5" x="219.6" y="776.4" textLength="1220" 
clip-path="url(#breeze-ci-upgrade-line-31)">───────────────────────────────────────────────────────────────────────────────────────────
 [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="800.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-32)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="800.8" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-32)">--answer&#160;</text><text 
class="breeze-ci-upgrade-r7" x="158.6" y="800.8" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-32)">-a</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="800.8" textLength="329.4" 
clip-path="url(#breeze-ci- [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="825.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-33)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="825.2" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-33)">--verbose</text><text 
class="breeze-ci-upgrade-r7" x="158.6" y="825.2" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-33)">-v</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="825.2" textLength="585.6" 
clip-path="url(#breeze-ci-upgra [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="849.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-34)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="849.6" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-34)">--dry-run</text><text 
class="breeze-ci-upgrade-r7" x="158.6" y="849.6" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-34)">-D</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="849.6" textLength="719.8" 
clip-path="url(#breeze-ci-upgra [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="874" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-35)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="874" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-35)">--help&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r7" x="158.6" y="874" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-35)">-h</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="874" textLength="329.4" 
clip-path="url(#breeze-c [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="898.4" textLength="1464" 
clip-path="url(#breeze-ci-upgrade-line-36)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-ci-upgrade-r1" x="1464" y="898.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-36)">
+</text><text class="breeze-ci-upgrade-r5" x="0" y="264" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-10)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="264" textLength="85.4" 
clip-path="url(#breeze-ci-upgrade-line-10)">--draft</text><text 
class="breeze-ci-upgrade-r1" x="109.8" y="264" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-10)">/</text><text 
class="breeze-ci-upgrade-r4" x="122" y="264" textLength="122" 
clip-path="url(#breeze-ci-upgrade-line-10)">--n [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="288.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-11)">│</text><text 
class="breeze-ci-upgrade-r1" x="488" y="288.4" textLength="183" 
clip-path="url(#breeze-ci-upgrade-line-11)">to&#160;trigger&#160;CI)&#160;</text><text
 class="breeze-ci-upgrade-r5" x="671" y="288.4" textLength="231.8" 
clip-path="url(#breeze-ci-upgrade-line-11)">[default:&#160;no-draft]</text><text
 class="breeze-ci-upgrade-r5" x="1451.8" y="288.4" textLength [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="312.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-12)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="312.8" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-12)">--switch-to-base</text><text 
class="breeze-ci-upgrade-r1" x="219.6" y="312.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-12)">/</text><text 
class="breeze-ci-upgrade-r4" x="231.8" y="312.8" textLength="231.8" 
clip-path="url(#breeze-ci [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="337.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-13)">│</text><text 
class="breeze-ci-upgrade-r1" x="488" y="337.2" textLength="951.6" 
clip-path="url(#breeze-ci-upgrade-line-13)">specified,&#160;will&#160;ask)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#
 [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="361.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-14)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="361.6" textLength="439.2" 
clip-path="url(#breeze-ci-upgrade-line-14)">--airflow-site&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r1" x="488" y="361.6" textLength="695.4" 
clip-path="url(#breeze [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="386" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-15)">│</text><text 
class="breeze-ci-upgrade-r5" x="488" y="386" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-15)">../airflow-site]</text><text 
class="breeze-ci-upgrade-r6" x="695.4" y="386" textLength="134.2" 
clip-path="url(#breeze-ci-upgrade-line-15)">(DIRECTORY)</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="386" textLength="12.2" 
clip-path="url(#breeze- [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="410.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-16)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="410.4" textLength="439.2" 
clip-path="url(#breeze-ci-upgrade-line-16)">--force-k8s-schema-sync&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r1" x="488" y="410.4" textLength="951.6" 
clip-path="url(#breeze-ci-upgrade-line-16)">Force&#160;syncing&#160 [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="434.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-17)">│</text><text 
class="breeze-ci-upgrade-r1" x="488" y="434.8" textLength="951.6" 
clip-path="url(#breeze-ci-upgrade-line-17)">published&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="459.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-18)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="459.2" textLength="439.2" 
clip-path="url(#breeze-ci-upgrade-line-18)">--github-token&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r1" x="488" y="459.2" textLength="512.4" 
clip-path="url(#breeze [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="483.6" textLength="1464" 
clip-path="url(#breeze-ci-upgrade-line-19)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-ci-upgrade-r1" x="1464" y="483.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-19)">
+</text><text class="breeze-ci-upgrade-r5" x="0" y="508" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-20)">╭─</text><text 
class="breeze-ci-upgrade-r5" x="24.4" y="508" textLength="183" 
clip-path="url(#breeze-ci-upgrade-line-20)">&#160;Upgrade&#160;steps&#160;</text><text
 class="breeze-ci-upgrade-r5" x="207.4" y="508" textLength="1232.2" 
clip-path="url(#breeze-ci-upgrade-line-20)">──────────────────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="532.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-21)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="532.4" textLength="146.4" 
clip-path="url(#breeze-ci-upgrade-line-21)">--autoupdate</text><text 
class="breeze-ci-upgrade-r1" x="170.8" y="532.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-21)">/</text><text 
class="breeze-ci-upgrade-r4" x="183" y="532.4" textLength="183" 
clip-path="url(#breeze-ci-upgrade [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="556.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-22)">│</text><text 
class="breeze-ci-upgrade-r5" x="744.2" y="556.8" textLength="134.2" 
clip-path="url(#breeze-ci-upgrade-line-22)">autoupdate]</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="556.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-22)">│</text><text 
class="breeze-ci-upgrade-r1" x="1464" y="556.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgr [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="581.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-23)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="581.2" textLength="329.4" 
clip-path="url(#breeze-ci-upgrade-line-23)">--update-chart-dependencies</text><text
 class="breeze-ci-upgrade-r1" x="353.8" y="581.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-23)">/</text><text 
class="breeze-ci-upgrade-r4" x="366" y="581.2" textLength="353.8" 
clip-path="url(# [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="605.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-24)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="605.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-24)">s</text><text 
class="breeze-ci-upgrade-r1" x="744.2" y="605.6" textLength="158.6" 
clip-path="url(#breeze-ci-upgrade-line-24)">dependencies&#160;</text><text 
class="breeze-ci-upgrade-r5" x="902.8" y="605.6" textLength="439.2" 
clip-path="url(#breeze- [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="630" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-25)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="630" textLength="341.6" 
clip-path="url(#breeze-ci-upgrade-line-25)">--upgrade-important-versions</text><text
 class="breeze-ci-upgrade-r1" x="366" y="630" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-25)">/</text><text 
class="breeze-ci-upgrade-r4" x="378.2" y="630" textLength="341.6" 
clip-path="url(#breeze- [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="654.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-26)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="654.4" textLength="36.6" 
clip-path="url(#breeze-ci-upgrade-line-26)">ons</text><text 
class="breeze-ci-upgrade-r1" x="744.2" y="654.4" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-26)">versions&#160;</text><text 
class="breeze-ci-upgrade-r5" x="854" y="654.4" textLength="451.4" 
clip-path="url(#breeze-ci-u [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="678.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-27)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="678.8" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-27)">--update-uv-lock</text><text 
class="breeze-ci-upgrade-r1" x="219.6" y="678.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-27)">/</text><text 
class="breeze-ci-upgrade-r4" x="231.8" y="678.8" textLength="231.8" 
clip-path="url(#breeze-ci [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="703.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-28)">│</text><text 
class="breeze-ci-upgrade-r1" x="744.2" y="703.2" textLength="427" 
clip-path="url(#breeze-ci-upgrade-line-28)">resolutions&#160;inside&#160;Breeze&#160;CI&#160;image&#160;</text><text
 class="breeze-ci-upgrade-r5" x="1171.2" y="703.2" textLength="122" 
clip-path="url(#breeze-ci-upgrade-line-28)">[default:&#160;</text><text 
class="breeze-ci-upgrade-r5" x="1451 [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="727.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-29)">│</text><text 
class="breeze-ci-upgrade-r5" x="744.2" y="727.6" textLength="183" 
clip-path="url(#breeze-ci-upgrade-line-29)">update-uv-lock]</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="727.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-29)">│</text><text 
class="breeze-ci-upgrade-r1" x="1464" y="727.6" textLength="12.2" 
clip-path="url(#breeze-ci-up [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="752" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-30)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="752" textLength="207.4" 
clip-path="url(#breeze-ci-upgrade-line-30)">--k8s-schema-sync</text><text 
class="breeze-ci-upgrade-r1" x="231.8" y="752" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-30)">/</text><text 
class="breeze-ci-upgrade-r4" x="244" y="752" textLength="244" 
clip-path="url(#breeze-ci-upgrade-li [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="776.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-31)">│</text><text 
class="breeze-ci-upgrade-r5" x="744.2" y="776.4" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-31)">k8s-schema-sync]</text><text 
class="breeze-ci-upgrade-r5" x="1451.8" y="776.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-31)">│</text><text 
class="breeze-ci-upgrade-r1" x="1464" y="776.4" textLength="12.2" 
clip-path="url(#breeze-ci [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="800.8" textLength="1464" 
clip-path="url(#breeze-ci-upgrade-line-32)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-ci-upgrade-r1" x="1464" y="800.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-32)">
+</text><text class="breeze-ci-upgrade-r5" x="0" y="825.2" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-33)">╭─</text><text 
class="breeze-ci-upgrade-r5" x="24.4" y="825.2" textLength="195.2" 
clip-path="url(#breeze-ci-upgrade-line-33)">&#160;Common&#160;options&#160;</text><text
 class="breeze-ci-upgrade-r5" x="219.6" y="825.2" textLength="1220" 
clip-path="url(#breeze-ci-upgrade-line-33)">───────────────────────────────────────────────────────────────────────────────────────────
 [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="849.6" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-34)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="849.6" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-34)">--answer&#160;</text><text 
class="breeze-ci-upgrade-r7" x="158.6" y="849.6" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-34)">-a</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="849.6" textLength="329.4" 
clip-path="url(#breeze-ci- [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="874" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-35)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="874" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-35)">--verbose</text><text 
class="breeze-ci-upgrade-r7" x="158.6" y="874" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-35)">-v</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="874" textLength="585.6" 
clip-path="url(#breeze-ci-upgrade-line- [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="898.4" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-36)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="898.4" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-36)">--dry-run</text><text 
class="breeze-ci-upgrade-r7" x="158.6" y="898.4" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-36)">-D</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="898.4" textLength="719.8" 
clip-path="url(#breeze-ci-upgra [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="922.8" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-37)">│</text><text 
class="breeze-ci-upgrade-r4" x="24.4" y="922.8" textLength="109.8" 
clip-path="url(#breeze-ci-upgrade-line-37)">--help&#160;&#160;&#160;</text><text
 class="breeze-ci-upgrade-r7" x="158.6" y="922.8" textLength="24.4" 
clip-path="url(#breeze-ci-upgrade-line-37)">-h</text><text 
class="breeze-ci-upgrade-r1" x="207.4" y="922.8" textLength="329.4" 
clip-path="url(# [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="947.2" textLength="1464" 
clip-path="url(#breeze-ci-upgrade-line-38)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
 class="breeze-ci-upgrade-r1" x="1464" y="947.2" textLength="12.2" 
clip-path="url(#breeze-ci-upgrade-line-38)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_ci_upgrade.txt 
b/dev/breeze/doc/images/output_ci_upgrade.txt
index d4c9261560f..b4279b39938 100644
--- a/dev/breeze/doc/images/output_ci_upgrade.txt
+++ b/dev/breeze/doc/images/output_ci_upgrade.txt
@@ -1 +1 @@
-c31c21e727da6c84a6b2d7f1a7d18718
+98c7d919cdbf65fa4a8f774650c007e4
diff --git a/dev/breeze/src/airflow_breeze/commands/ci_commands.py 
b/dev/breeze/src/airflow_breeze/commands/ci_commands.py
index 68c184d2423..a011f7ba6d3 100644
--- a/dev/breeze/src/airflow_breeze/commands/ci_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/ci_commands.py
@@ -536,6 +536,13 @@ def _sync_k8s_schemas_to_airflow_site(airflow_site: Path, 
force: bool, command_e
     help="Automatically create a PR with the upgrade changes (if not 
specified, will ask)",
     is_flag=True,
 )
[email protected](
+    "--draft/--no-draft",
+    default=False,
+    show_default=True,
+    help="Create the PR as a draft (useful for scheduled CI runs where a human 
undrafts to trigger CI)",
+    is_flag=True,
+)
 @click.option(
     "--switch-to-base/--no-switch-to-base",
     default=None,
@@ -592,6 +599,7 @@ def _sync_k8s_schemas_to_airflow_site(airflow_site: Path, 
force: bool, command_e
 def upgrade(
     target_branch: str,
     create_pr: bool | None,
+    draft: bool,
     switch_to_base: bool | None,
     airflow_site: Path,
     force_k8s_schema_sync: bool,
@@ -828,12 +836,8 @@ def upgrade(
         should_create_pr = user_confirm("Do you want to create a PR with the 
upgrade changes?") == Answer.YES
 
     if should_create_pr:
-        # Get current HEAD commit hash for unique branch name
-        head_result = run_command(
-            ["git", "rev-parse", "--short", "HEAD"], capture_output=True, 
text=True, check=False
-        )
-        commit_hash = head_result.stdout.strip() if head_result.returncode == 
0 else "unknown"
-        branch_name = f"ci-upgrade-{commit_hash}"
+        # Use a stable branch name based on target branch so scheduled runs 
can reuse/update the same PR
+        branch_name = f"ci-upgrade-{target_branch}"
 
         # Check if branch already exists and delete it
         branch_check = run_command(
@@ -845,7 +849,7 @@ def upgrade(
 
         run_command(["git", "checkout", "-b", branch_name])
         run_command(["git", "add", "."])
-        run_command(["git", "commit", "-m", "CI: Upgrade important CI 
environment"])
+        run_command(["git", "commit", "-m", f"[{target_branch}] CI: Upgrade 
important CI environment"])
 
         # Push the branch to origin (use detected origin or fallback to 
'origin')
         push_remote = origin_remote_name if origin_remote_name else "origin"
@@ -875,33 +879,88 @@ def upgrade(
             head_ref = branch_name
             console_print("[warning]Could not determine fork repository. Using 
branch name only.[/]")
 
-        pr_result = run_command(
+        pr_title = f"[{target_branch}] Upgrade important CI environment"
+        pr_body = "This PR upgrades important dependencies of the CI 
environment."
+
+        # Check if there's already an open PR for this branch
+        existing_pr_result = run_command(
             [
                 "gh",
                 "pr",
-                "create",
-                "-w",
+                "list",
                 "--repo",
                 "apache/airflow",
                 "--head",
                 head_ref,
                 "--base",
                 target_branch,
-                "--title",
-                f"[{target_branch}] Upgrade important CI environment",
-                "--body",
-                "This PR upgrades important dependencies of the CI 
environment.",
+                "--state",
+                "open",
+                "--json",
+                "number,url",
+                "--jq",
+                ".[0]",
             ],
             capture_output=True,
             text=True,
             check=False,
             env=command_env,
         )
-        if pr_result.returncode != 0:
-            console_print(f"[error]Failed to create 
PR:\n{pr_result.stdout}\n{pr_result.stderr}[/]")
-            sys.exit(1)
-        pr_url = pr_result.stdout.strip() if pr_result.returncode == 0 else ""
-        console_print(f"[success]PR created successfully: {pr_url}.[/]")
+
+        existing_pr = existing_pr_result.stdout.strip() if 
existing_pr_result.returncode == 0 else ""
+
+        if existing_pr and existing_pr != "null" and existing_pr != "":
+            console_print(f"[success]Existing PR found and updated with force 
push: {existing_pr}[/]")
+            if draft:
+                # Convert back to draft so a human must undraft to trigger CI
+                run_command(
+                    [
+                        "gh",
+                        "pr",
+                        "ready",
+                        "--repo",
+                        "apache/airflow",
+                        "--undo",
+                        head_ref,
+                    ],
+                    capture_output=True,
+                    text=True,
+                    check=False,
+                    env=command_env,
+                )
+                console_print("[info]Existing PR converted back to draft.[/]")
+        else:
+            # Create a new PR
+            gh_create_cmd = [
+                "gh",
+                "pr",
+                "create",
+                "--repo",
+                "apache/airflow",
+                "--head",
+                head_ref,
+                "--base",
+                target_branch,
+                "--title",
+                pr_title,
+                "--body",
+                pr_body,
+            ]
+            if draft:
+                gh_create_cmd.append("--draft")
+
+            pr_result = run_command(
+                gh_create_cmd,
+                capture_output=True,
+                text=True,
+                check=False,
+                env=command_env,
+            )
+            if pr_result.returncode != 0:
+                console_print(f"[error]Failed to create 
PR:\n{pr_result.stdout}\n{pr_result.stderr}[/]")
+                sys.exit(1)
+            pr_url = pr_result.stdout.strip() if pr_result.returncode == 0 
else ""
+            console_print(f"[success]PR created successfully: {pr_url}.[/]")
 
         # Switch back to appropriate branch and delete the temporary branch
         console_print(f"[info]Cleaning up temporary branch 
{branch_name}...[/]")
diff --git a/dev/breeze/src/airflow_breeze/commands/ci_commands_config.py 
b/dev/breeze/src/airflow_breeze/commands/ci_commands_config.py
index 8c02d6c9c06..5e3593f18cf 100644
--- a/dev/breeze/src/airflow_breeze/commands/ci_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/ci_commands_config.py
@@ -74,6 +74,7 @@ CI_PARAMETERS: dict[str, list[dict[str, str | list[str]]]] = {
             "options": [
                 "--target-branch",
                 "--create-pr",
+                "--draft",
                 "--switch-to-base",
                 "--airflow-site",
                 "--force-k8s-schema-sync",

Reply via email to