This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-1-test by this push:
new 9392cc12866 Fix unauthenticated GitHub API calls in `breeze ci upgrade`
9392cc12866 is described below
commit 9392cc128669b1d68da872b8ca20f4ea7bbc2138
Author: Jarek Potiuk <[email protected]>
AuthorDate: Fri Mar 20 09:21:21 2026 +0100
Fix unauthenticated GitHub API calls in `breeze ci upgrade`
Two GitHub API calls in upgrade_important_versions.py (for fetching
latest releases of mprocs and openapi-generator) were not using the
GitHub token, hitting the 60 req/hr unauthenticated rate limit.
Also adds --github-token option to `breeze ci upgrade` so the token
can be passed explicitly instead of relying on `gh auth token`.
(cherry picked from commit f8b049982b17554e5f4182c19f2782cf651d2836)
---
dev/breeze/doc/images/output_ci_upgrade.svg | 24 +++++++++--------
dev/breeze/doc/images/output_ci_upgrade.txt | 2 +-
.../src/airflow_breeze/commands/ci_commands.py | 30 +++++++++++++---------
.../airflow_breeze/commands/ci_commands_config.py | 1 +
scripts/ci/prek/upgrade_important_versions.py | 12 ++++++++-
5 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/dev/breeze/doc/images/output_ci_upgrade.svg
b/dev/breeze/doc/images/output_ci_upgrade.svg
index 58a7b5bc225..59236bc0f97 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 513.5999999999999"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 538.0"
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="462.59999999999997" />
+ <rect x="0" y="0" width="1463.0" height="487.0" />
</clipPath>
<clipPath id="breeze-ci-upgrade-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -99,9 +99,12 @@
<clipPath id="breeze-ci-upgrade-line-17">
<rect x="0" y="416.3" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-ci-upgrade-line-18">
+ <rect x="0" y="440.7" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="511.6" rx="8"/><text
class="breeze-ci-upgrade-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: ci upgrade</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="536" rx="8"/><text
class="breeze-ci-upgrade-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: ci 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"/>
@@ -123,13 +126,14 @@
</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="512.4" y="239.6" textLength="927.2"
clip-path="url(#breeze-ci-upgrade-line-9)">ask)                                        
[...]
</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="512.4" y="288.4" textLength="927.2"
clip-path="url(#breeze-ci-upgrade-line-11)">specified, will ask)                                    
[...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="312.8" textLength="1464"
clip-path="url(#breeze-ci-upgrade-line-12)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-ci-upgrade-r1" x="1464" y="312.8" textLength="12.2"
clip-path="url(#breeze-ci-upgrade-line-12)">
-</text><text class="breeze-ci-upgrade-r5" x="0" y="337.2" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-13)">╭─</text><text
class="breeze-ci-upgrade-r5" x="24.4" y="337.2" textLength="195.2"
clip-path="url(#breeze-ci-upgrade-line-13)"> Common options </text><text
class="breeze-ci-upgrade-r5" x="219.6" y="337.2" textLength="1220"
clip-path="url(#breeze-ci-upgrade-line-13)">───────────────────────────────────────────────────────────────────────────────────────────
[...]
-</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="97.6"
clip-path="url(#breeze-ci-upgrade-line-14)">--answer</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="361.6" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-14)">-a</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="361.6" textLength="317.2"
clip-path="url(#breeze-ci-upgrade [...]
-</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-r4" x="24.4" y="386" textLength="109.8"
clip-path="url(#breeze-ci-upgrade-line-15)">--verbose</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="386" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-15)">-v</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="386" textLength="585.6"
clip-path="url(#breeze-ci-upgrade-line- [...]
-</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="109.8"
clip-path="url(#breeze-ci-upgrade-line-16)">--dry-run</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="410.4" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-16)">-D</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="410.4" textLength="719.8"
clip-path="url(#breeze-ci-upgra [...]
-</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-r4" x="24.4" y="434.8" textLength="73.2"
clip-path="url(#breeze-ci-upgrade-line-17)">--help</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="434.8" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-17)">-h</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="434.8" textLength="329.4"
clip-path="url(#breeze-ci-upgrade-l [...]
-</text><text class="breeze-ci-upgrade-r5" x="0" y="459.2" textLength="1464"
clip-path="url(#breeze-ci-upgrade-line-18)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-ci-upgrade-r1" x="1464" y="459.2" textLength="12.2"
clip-path="url(#breeze-ci-upgrade-line-18)">
+</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="170.8"
clip-path="url(#breeze-ci-upgrade-line-12)">--github-token</text><text
class="breeze-ci-upgrade-r1" x="512.4" y="312.8" textLength="500.2"
clip-path="url(#breeze-ci-upgrade-line-12)">The token used to authenticate to GitHub.</text><text
class="breeze-ci-upgrade [...]
+</text><text class="breeze-ci-upgrade-r5" x="0" y="337.2" textLength="1464"
clip-path="url(#breeze-ci-upgrade-line-13)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-ci-upgrade-r1" x="1464" y="337.2" textLength="12.2"
clip-path="url(#breeze-ci-upgrade-line-13)">
+</text><text class="breeze-ci-upgrade-r5" x="0" y="361.6" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-14)">╭─</text><text
class="breeze-ci-upgrade-r5" x="24.4" y="361.6" textLength="195.2"
clip-path="url(#breeze-ci-upgrade-line-14)"> Common options </text><text
class="breeze-ci-upgrade-r5" x="219.6" y="361.6" textLength="1220"
clip-path="url(#breeze-ci-upgrade-line-14)">───────────────────────────────────────────────────────────────────────────────────────────
[...]
+</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-r4" x="24.4" y="386" textLength="97.6"
clip-path="url(#breeze-ci-upgrade-line-15)">--answer</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="386" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-15)">-a</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="386" textLength="317.2"
clip-path="url(#breeze-ci-upgrade-line-15 [...]
+</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="109.8"
clip-path="url(#breeze-ci-upgrade-line-16)">--verbose</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="410.4" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-16)">-v</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="410.4" textLength="585.6"
clip-path="url(#breeze-ci-upgra [...]
+</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-r4" x="24.4" y="434.8" textLength="109.8"
clip-path="url(#breeze-ci-upgrade-line-17)">--dry-run</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="434.8" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-17)">-D</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="434.8" textLength="719.8"
clip-path="url(#breeze-ci-upgra [...]
+</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="73.2"
clip-path="url(#breeze-ci-upgrade-line-18)">--help</text><text
class="breeze-ci-upgrade-r7" x="158.6" y="459.2" textLength="24.4"
clip-path="url(#breeze-ci-upgrade-line-18)">-h</text><text
class="breeze-ci-upgrade-r1" x="207.4" y="459.2" textLength="329.4"
clip-path="url(#breeze-ci-upgrade-l [...]
+</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>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_ci_upgrade.txt
b/dev/breeze/doc/images/output_ci_upgrade.txt
index 2fb1cda8a68..5f05a990319 100644
--- a/dev/breeze/doc/images/output_ci_upgrade.txt
+++ b/dev/breeze/doc/images/output_ci_upgrade.txt
@@ -1 +1 @@
-098262cac189629f9ba74c4517b0b853
+e81724124d51a5dfddc0f2732e65a609
diff --git a/dev/breeze/src/airflow_breeze/commands/ci_commands.py
b/dev/breeze/src/airflow_breeze/commands/ci_commands.py
index f9f65965c59..75d48cba1f4 100644
--- a/dev/breeze/src/airflow_breeze/commands/ci_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/ci_commands.py
@@ -37,6 +37,7 @@ from airflow_breeze.commands.common_options import (
option_answer,
option_dry_run,
option_github_repository,
+ option_github_token,
option_verbose,
)
from airflow_breeze.global_constants import (
@@ -450,7 +451,10 @@ def get_workflow_info(github_context: str,
github_context_input: StringIO):
@option_answer
@option_verbose
@option_dry_run
-def upgrade(target_branch: str, create_pr: bool | None, switch_to_base: bool |
None):
+@option_github_token
+def upgrade(
+ target_branch: str, create_pr: bool | None, switch_to_base: bool | None,
github_token: str | None
+):
# Validate target_branch pattern
target_branch_pattern = re.compile(r"^(main|v\d+-\d+-test)$")
if not target_branch_pattern.match(target_branch):
@@ -606,24 +610,26 @@ def upgrade(target_branch: str, create_pr: bool | None,
switch_to_base: bool | N
get_console().print("[info]Running upgrade of important CI
environment.[/]")
- # Get GitHub token from gh CLI and set it in environment copy
- gh_token_result = run_command(
- ["gh", "auth", "token"],
- capture_output=True,
- text=True,
- check=False,
- )
+ # Resolve GitHub token: prefer --github-token / GITHUB_TOKEN env var, fall
back to gh CLI
+ if not github_token:
+ gh_token_result = run_command(
+ ["gh", "auth", "token"],
+ capture_output=True,
+ text=True,
+ check=False,
+ )
+ if gh_token_result.returncode == 0 and gh_token_result.stdout.strip():
+ github_token = gh_token_result.stdout.strip()
# Create a copy of the environment to pass to commands
command_env = os.environ.copy()
- if gh_token_result.returncode == 0 and gh_token_result.stdout.strip():
- github_token = gh_token_result.stdout.strip()
+ if github_token:
command_env["GITHUB_TOKEN"] = github_token
- get_console().print("[success]GitHub token retrieved from gh CLI and
set in environment.[/]")
+ get_console().print("[success]GitHub token set in environment.[/]")
else:
get_console().print(
- "[warning]Could not retrieve GitHub token from gh CLI. "
+ "[warning]Could not retrieve GitHub token from --github-token or
gh CLI. "
"Commands may fail if they require authentication.[/]"
)
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 9f822c4365d..35cc09a465a 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]]]] = {
"--target-branch",
"--create-pr",
"--switch-to-base",
+ "--github-token",
],
}
],
diff --git a/scripts/ci/prek/upgrade_important_versions.py
b/scripts/ci/prek/upgrade_important_versions.py
index 5b5d23b40b8..e435e29a049 100755
--- a/scripts/ci/prek/upgrade_important_versions.py
+++ b/scripts/ci/prek/upgrade_important_versions.py
@@ -48,6 +48,9 @@ from common_prek_utils import AIRFLOW_CORE_ROOT_PATH,
AIRFLOW_ROOT_PATH, console
DOCKER_IMAGES_EXAMPLE_DIR_PATH = AIRFLOW_ROOT_PATH / "docker-stack-docs" /
"docker-examples"
+# Module-level GitHub token, set during main() via retrieve_gh_token()
+_github_token: str | None = None
+
# List of files to update and whether to keep total length of the original
value when replacing.
FILES_TO_UPDATE: list[tuple[Path, bool]] = [
@@ -270,6 +273,9 @@ def get_latest_github_release_version(repo: str) -> str:
url = f"https://api.github.com/repos/{repo}/releases/latest"
headers = {"User-Agent": "Python requests"}
+ if _github_token:
+ headers["Authorization"] = f"Bearer {_github_token}"
+ headers["X-GitHub-Api-Version"] = "2022-11-28"
response = requests.get(url, headers=headers)
response.raise_for_status()
@@ -296,6 +302,9 @@ def get_latest_openapi_generator_version() -> str:
console.print("[bright_blue]Fetching latest OpenAPI generator version
from GitHub")
url =
"https://api.github.com/repos/OpenAPITools/openapi-generator/releases/latest"
headers = {"User-Agent": "Python requests"}
+ if _github_token:
+ headers["Authorization"] = f"Bearer {_github_token}"
+ headers["X-GitHub-Api-Version"] = "2022-11-28"
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
@@ -833,7 +842,8 @@ def update_pyproject_build_requires(
def main() -> None:
"""Main entry point for the version upgrade script."""
- retrieve_gh_token(description="airflow-upgrade-important-versions",
scopes="public_repo")
+ global _github_token
+ _github_token =
retrieve_gh_token(description="airflow-upgrade-important-versions",
scopes="public_repo")
versions = fetch_all_package_versions()
log_special_versions(versions)