This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 9917a04c0ce Add mprocs upgrade check to upgrade_important_versions
(#58723)
9917a04c0ce is described below
commit 9917a04c0cede0cca02255ba39d22fd81e5c7152
Author: Jarek Potiuk <[email protected]>
AuthorDate: Fri Nov 28 18:17:44 2025 +0100
Add mprocs upgrade check to upgrade_important_versions (#58723)
Used the opportunity to refactor and restructure the script to
be much more readable and maintainable.
---
.github/workflows/basic-tests.yml | 2 +
scripts/ci/prek/upgrade_important_versions.py | 456 +++++++++++++++-----------
2 files changed, 263 insertions(+), 195 deletions(-)
diff --git a/.github/workflows/basic-tests.yml
b/.github/workflows/basic-tests.yml
index 244b5ffb780..b7749a52029 100644
--- a/.github/workflows/basic-tests.yml
+++ b/.github/workflows/basic-tests.yml
@@ -312,6 +312,7 @@ jobs:
UPGRADE_GITPYTHON: "false"
UPGRADE_RICH: "false"
UPGRADE_RUFF: "false"
+ UPGRADE_MPROCS: "true"
UPGRADE_MYPY: "false"
UPGRADE_PROTOC: "false"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -338,6 +339,7 @@ jobs:
UPGRADE_RICH: "true"
UPGRADE_RUFF: "true"
UPGRADE_MYPY: "true"
+ UPGRADE_MPROCS: "false"
UPGRADE_PROTOC: "false"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/scripts/ci/prek/upgrade_important_versions.py
b/scripts/ci/prek/upgrade_important_versions.py
index d723ad1853d..0c425a11c49 100755
--- a/scripts/ci/prek/upgrade_important_versions.py
+++ b/scripts/ci/prek/upgrade_important_versions.py
@@ -27,7 +27,7 @@
#
# DEBUGGING
# * You can set UPGRADE_ALL_BY_DEFAULT to "false" to only upgrade those
versions that
-# are set by UPGRADE_NNNNNNN (NNNNNN > thing to upgrade version)
+# are set by UPGRADE_NNNNNNN (NNNNNNN > thing to upgrade version)
# * You can set VERBOSE="true" to see requests being made
# * You can set UPGRADE_NNNNNNN_INCLUDE_PRE_RELEASES="true"
@@ -256,6 +256,40 @@ def get_latest_image_version(image: str) -> str:
return latest_tag
+def get_latest_github_release_version(repo: str) -> str:
+ """
+ Fetch the latest release version from a GitHub repository.
+
+ Args:
+ repo: GitHub repository in the format "owner/repo"
+
+ Returns:
+ The latest release version as a string (without leading 'v')
+ """
+ if VERBOSE:
+ console.print(f"[bright_blue]Fetching latest release for GitHub repo:
{repo}")
+
+ url = f"https://api.github.com/repos/{repo}/releases/latest"
+ headers = {"User-Agent": "Python requests"}
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+
+ data = response.json()
+ tag_name = data.get("tag_name", "")
+
+ if not tag_name:
+ console.print(f"[bright_red]No release tag found for {repo}")
+ return ""
+
+ # Remove leading 'v' if present
+ version = tag_name.lstrip("v")
+
+ if VERBOSE:
+ console.print(f"[bright_blue]Latest version for {repo}: {version}")
+
+ return version
+
+
class Quoting(Enum):
UNQUOTED = 0
SINGLE_QUOTED = 1
@@ -302,7 +336,7 @@ UV_PATTERNS: list[tuple[re.Pattern, Quoting]] = [
(re.compile(r"(\| *`AIRFLOW_UV_VERSION` *\| *)(`[0-9.abrd]+`)( *\|)"),
Quoting.REVERSE_SINGLE_QUOTED),
(
re.compile(
- r"(\")([0-9.abrc]+)(\" # Keep this comment to "
+ r"(\")([0-9.abrc]+)(\" {2}# Keep this comment to "
r"allow automatic replacement of uv version)"
),
Quoting.UNQUOTED,
@@ -321,7 +355,7 @@ PREK_PATTERNS: list[tuple[re.Pattern, Quoting]] = [
),
(
re.compile(
- r"(\")([0-9.abrc]+)(\" # Keep this comment to allow automatic "
+ r"(\")([0-9.abrc]+)(\" {2}# Keep this comment to allow automatic "
r"replacement of prek version)"
),
Quoting.UNQUOTED,
@@ -329,7 +363,7 @@ PREK_PATTERNS: list[tuple[re.Pattern, Quoting]] = [
]
NODE_LTS_PATTERNS: list[tuple[re.Pattern, Quoting]] = [
- (re.compile(r"(^ node: )([0-9.abrc]+)^"), Quoting.UNQUOTED),
+ (re.compile(r"(^ {2}node: )([0-9.abrc]+)^"), Quoting.UNQUOTED),
]
@@ -345,26 +379,35 @@ def get_replacement(value: str, quoting: Quoting) -> str:
return value
+def get_env_bool(name: str, default: bool = True) -> bool:
+ """Get boolean value from environment variable."""
+ default_str = str(default).lower()
+ upgrade_all_str = str(UPGRADE_ALL_BY_DEFAULT).lower()
+ fallback = upgrade_all_str if name.startswith("UPGRADE_") else default_str
+ return os.environ.get(name, fallback).lower() == "true"
+
+
VERBOSE: bool = os.environ.get("VERBOSE", "false") == "true"
UPGRADE_ALL_BY_DEFAULT: bool = os.environ.get("UPGRADE_ALL_BY_DEFAULT",
"true") == "true"
-UPGRADE_ALL_BY_DEFAULT_STR: str = str(UPGRADE_ALL_BY_DEFAULT).lower()
-if UPGRADE_ALL_BY_DEFAULT:
- if VERBOSE == "true":
- console.print("[bright_blue]Upgrading all important versions")
-
-UPGRADE_GITPYTHON: bool = os.environ.get("UPGRADE_GITPYTHON",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_GOLANG: bool = os.environ.get("UPGRADE_GOLANG",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_HATCH: bool = os.environ.get("UPGRADE_HATCH",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_NODE_LTS: bool = os.environ.get("UPGRADE_NODE_LTS",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_PIP: bool = os.environ.get("UPGRADE_PIP",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_PREK: bool = os.environ.get("UPGRADE_PREK",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_PYTHON: bool = os.environ.get("UPGRADE_PYTHON",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_PYYAML: bool = os.environ.get("UPGRADE_PYYAML",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_RICH: bool = os.environ.get("UPGRADE_RICH",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_RUFF: bool = os.environ.get("UPGRADE_RUFF",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_UV: bool = os.environ.get("UPGRADE_UV",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_MYPY: bool = os.environ.get("UPGRADE_MYPY",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
-UPGRADE_PROTOC: bool = os.environ.get("UPGRADE_PROTOC",
UPGRADE_ALL_BY_DEFAULT_STR).lower() == "true"
+
+if UPGRADE_ALL_BY_DEFAULT and VERBOSE:
+ console.print("[bright_blue]Upgrading all important versions")
+
+# Package upgrade flags
+UPGRADE_GITPYTHON: bool = get_env_bool("UPGRADE_GITPYTHON")
+UPGRADE_GOLANG: bool = get_env_bool("UPGRADE_GOLANG")
+UPGRADE_HATCH: bool = get_env_bool("UPGRADE_HATCH")
+UPGRADE_MPROCS: bool = get_env_bool("UPGRADE_MPROCS")
+UPGRADE_NODE_LTS: bool = get_env_bool("UPGRADE_NODE_LTS")
+UPGRADE_PIP: bool = get_env_bool("UPGRADE_PIP")
+UPGRADE_PREK: bool = get_env_bool("UPGRADE_PREK")
+UPGRADE_PYTHON: bool = get_env_bool("UPGRADE_PYTHON")
+UPGRADE_PYYAML: bool = get_env_bool("UPGRADE_PYYAML")
+UPGRADE_RICH: bool = get_env_bool("UPGRADE_RICH")
+UPGRADE_RUFF: bool = get_env_bool("UPGRADE_RUFF")
+UPGRADE_UV: bool = get_env_bool("UPGRADE_UV")
+UPGRADE_MYPY: bool = get_env_bool("UPGRADE_MYPY")
+UPGRADE_PROTOC: bool = get_env_bool("UPGRADE_PROTOC")
ALL_PYTHON_MAJOR_MINOR_VERSIONS = ["3.10", "3.11", "3.12", "3.13"]
DEFAULT_PROD_IMAGE_PYTHON_VERSION = "3.12"
@@ -397,193 +440,216 @@ def replace_version(pattern: re.Pattern[str], version:
str, text: str, keep_tota
return re.sub(pattern, replacer, text)
-if __name__ == "__main__":
- gh_token =
retrieve_gh_token(description="airflow-upgrade-important-versions",
scopes="public_repo")
- changed = False
- golang_version = get_latest_golang_version()
- pip_version = get_latest_pypi_version("pip", UPGRADE_PIP)
- uv_version = get_latest_pypi_version("uv", UPGRADE_UV)
- prek_version = get_latest_pypi_version("prek", UPGRADE_PREK)
- hatch_version = get_latest_pypi_version("hatch", UPGRADE_HATCH)
- pyyaml_version = get_latest_pypi_version("PyYAML", UPGRADE_PYYAML)
- gitpython_version = get_latest_pypi_version("GitPython", UPGRADE_GITPYTHON)
- ruff_version = get_latest_pypi_version("ruff", UPGRADE_RUFF)
- rich_version = get_latest_pypi_version("rich", UPGRADE_RICH)
- mypy_version = get_latest_pypi_version("mypy", UPGRADE_MYPY)
- node_lts_version = get_latest_lts_node_version()
- protoc_version = get_latest_image_version("rvolosatovs/protoc") if
UPGRADE_PROTOC else ""
+def apply_simple_regex_replacements(
+ text: str,
+ version: str,
+ patterns: list[tuple[str, str]],
+) -> str:
+ """Apply a list of simple regex replacements where the version is
substituted."""
+ result = text
+ for pattern, replacement_template in patterns:
+ result = re.sub(pattern, replacement_template.format(version=version),
result)
+ return result
+
+
+def apply_pattern_replacements(
+ text: str,
+ version: str,
+ patterns: list[tuple[re.Pattern, Quoting]],
+ keep_length: bool,
+) -> str:
+ """Apply pattern-based replacements with quoting."""
+ result = text
+ for line_pattern, quoting in patterns:
+ result = replace_version(line_pattern, get_replacement(version,
quoting), result, keep_length)
+ return result
+
+
+# Configuration for packages that follow simple version constant patterns
+SIMPLE_VERSION_PATTERNS = {
+ "hatch": [
+ (r"(HATCH_VERSION = )(\"[0-9.abrc]+\")", 'HATCH_VERSION =
"{version}"'),
+ (r"(HATCH_VERSION=)(\"[0-9.abrc]+\")", 'HATCH_VERSION="{version}"'),
+ (r"(hatch==)([0-9.abrc]+)", "hatch=={version}"),
+ (r"(hatch>=)([0-9.abrc]+)", "hatch>={version}"),
+ ],
+ "pyyaml": [
+ (r"(PYYAML_VERSION = )(\"[0-9.abrc]+\")", 'PYYAML_VERSION =
"{version}"'),
+ (r"(PYYAML_VERSION=)(\"[0-9.abrc]+\")", 'PYYAML_VERSION="{version}"'),
+ (r"(pyyaml>=)(\"[0-9.abrc]+\")", 'pyyaml>="{version}"'),
+ (r"(pyyaml>=)([0-9.abrc]+)", "pyyaml>={version}"),
+ ],
+ "gitpython": [
+ (r"(GITPYTHON_VERSION = )(\"[0-9.abrc]+\")", 'GITPYTHON_VERSION =
"{version}"'),
+ (r"(GITPYTHON_VERSION=)(\"[0-9.abrc]+\")",
'GITPYTHON_VERSION="{version}"'),
+ ],
+ "rich": [
+ (r"(RICH_VERSION = )(\"[0-9.abrc]+\")", 'RICH_VERSION = "{version}"'),
+ (r"(RICH_VERSION=)(\"[0-9.abrc]+\")", 'RICH_VERSION="{version}"'),
+ ],
+ "ruff": [
+ (r"(ruff==)([0-9.abrc]+)", "ruff=={version}"),
+ (r"(ruff>=)([0-9.abrc]+)", "ruff>={version}"),
+ ],
+ "mypy": [
+ (r"(mypy==)([0-9.]+)", "mypy=={version}"),
+ ],
+ "protoc": [
+ (r"(rvolosatovs/protoc:)(v[0-9.]+)", "rvolosatovs/protoc:{version}"),
+ ],
+ "mprocs": [
+ (r"(ARG MPROCS_VERSION=)(\"[0-9.]+\")", 'ARG
MPROCS_VERSION="{version}"'),
+ ],
+}
+
+
+# Configuration mapping pattern variables to their patterns and upgrade flags
+PATTERN_REGISTRY = {
+ "pip": (PIP_PATTERNS, UPGRADE_PIP),
+ "golang": (GOLANG_PATTERNS, UPGRADE_GOLANG),
+ "uv": (UV_PATTERNS, UPGRADE_UV),
+ "prek": (PREK_PATTERNS, UPGRADE_PREK),
+ "node_lts": (NODE_LTS_PATTERNS, UPGRADE_NODE_LTS),
+}
+
+
+def fetch_all_package_versions() -> dict[str, str]:
+ """Fetch latest versions for all packages that need to be upgraded."""
+ return {
+ "golang": get_latest_golang_version() if UPGRADE_GOLANG else "",
+ "pip": get_latest_pypi_version("pip", UPGRADE_PIP),
+ "uv": get_latest_pypi_version("uv", UPGRADE_UV),
+ "prek": get_latest_pypi_version("prek", UPGRADE_PREK),
+ "hatch": get_latest_pypi_version("hatch", UPGRADE_HATCH),
+ "pyyaml": get_latest_pypi_version("PyYAML", UPGRADE_PYYAML),
+ "gitpython": get_latest_pypi_version("GitPython", UPGRADE_GITPYTHON),
+ "ruff": get_latest_pypi_version("ruff", UPGRADE_RUFF),
+ "rich": get_latest_pypi_version("rich", UPGRADE_RICH),
+ "mypy": get_latest_pypi_version("mypy", UPGRADE_MYPY),
+ "node_lts": get_latest_lts_node_version() if UPGRADE_NODE_LTS else "",
+ "protoc": get_latest_image_version("rvolosatovs/protoc") if
UPGRADE_PROTOC else "",
+ "mprocs": get_latest_github_release_version("pvolok/mprocs") if
UPGRADE_MPROCS else "",
+ }
+
+
+def log_special_versions(versions: dict[str, str]) -> None:
+ """Log versions that need special attention."""
+ if UPGRADE_MYPY and versions["mypy"]:
+ console.print(f"[bright_blue]Latest mypy version: {versions['mypy']}")
+ if UPGRADE_PROTOC and versions["protoc"]:
+ console.print(f"[bright_blue]Latest protoc image version:
{versions['protoc']}")
+
+
+def fetch_python_versions() -> dict[str, str]:
+ """Fetch latest Python versions for all supported major.minor versions."""
latest_python_versions: dict[str, str] = {}
- latest_image_python_version = ""
+ if not UPGRADE_PYTHON:
+ return latest_python_versions
+
+ all_python_versions = get_all_python_versions()
+ for python_major_minor_version in ALL_PYTHON_MAJOR_MINOR_VERSIONS:
+ latest_python_versions[python_major_minor_version] =
get_latest_python_version(
+ python_major_minor_version, all_python_versions
+ )
+ if python_major_minor_version == DEFAULT_PROD_IMAGE_PYTHON_VERSION:
+ console.print(
+ f"[bright_blue]Latest image python
{python_major_minor_version} "
+ f"version:
{latest_python_versions[python_major_minor_version]}"
+ )
+ return latest_python_versions
+
+
+def update_file_with_versions(
+ file_content: str,
+ keep_length: bool,
+ versions: dict[str, str],
+ latest_python_versions: dict[str, str],
+) -> str:
+ """Update file content with all version replacements."""
+ new_content = file_content
+
+ # Apply pattern-based replacements using registry
+ for package_name, (patterns, should_upgrade) in PATTERN_REGISTRY.items():
+ version = versions.get(package_name, "")
+ if should_upgrade and version:
+ new_content = apply_pattern_replacements(new_content, version,
patterns, keep_length)
+
+ # Handle Python version updates (special case due to multiple versions)
if UPGRADE_PYTHON:
- all_python_versions = get_all_python_versions() if UPGRADE_PYTHON else
None
for python_major_minor_version in ALL_PYTHON_MAJOR_MINOR_VERSIONS:
- latest_python_versions[python_major_minor_version] =
get_latest_python_version(
- python_major_minor_version, all_python_versions
- )
- if python_major_minor_version == DEFAULT_PROD_IMAGE_PYTHON_VERSION:
- latest_image_python_version =
latest_python_versions[python_major_minor_version]
- console.print(
- f"[bright_blue]Latest image python
{python_major_minor_version} version: {latest_image_python_version}"
- )
- for file, keep_length in FILES_TO_UPDATE:
- console.print(f"[bright_blue]Updating {file}")
- file_content = file.read_text()
- new_content = file_content
- if UPGRADE_PIP:
- for line_pattern, quoting in PIP_PATTERNS:
- new_content = replace_version(
- line_pattern, get_replacement(pip_version, quoting),
new_content, keep_length
- )
- if UPGRADE_PYTHON:
- for python_major_minor_version in ALL_PYTHON_MAJOR_MINOR_VERSIONS:
- latest_python_version =
latest_python_versions[python_major_minor_version]
- for line_format, quoting in PYTHON_PATTERNS:
- line_pattern = re.compile(
-
line_format.format(python_major_minor=python_major_minor_version)
- )
- new_content = replace_version(
- line_pattern,
- get_replacement(latest_python_version, quoting),
- new_content,
- keep_length,
- )
- if python_major_minor_version ==
DEFAULT_PROD_IMAGE_PYTHON_VERSION:
- for line_pattern, quoting in AIRFLOW_IMAGE_PYTHON_PATTERNS:
- new_content = replace_version(
- line_pattern,
- get_replacement(latest_python_version, quoting),
- new_content,
- keep_length,
- )
- if UPGRADE_GOLANG:
- for line_pattern, quoting in GOLANG_PATTERNS:
- new_content = replace_version(
- line_pattern, get_replacement(golang_version, quoting),
new_content, keep_length
- )
- if UPGRADE_UV:
- for line_pattern, quoting in UV_PATTERNS:
- new_content = replace_version(
- line_pattern, get_replacement(uv_version, quoting),
new_content, keep_length
- )
- if UPGRADE_PREK:
- for line_pattern, quoting in PREK_PATTERNS:
- new_content = replace_version(
- line_pattern, get_replacement(prek_version, quoting),
new_content, keep_length
- )
- if UPGRADE_NODE_LTS:
- for line_pattern, quoting in NODE_LTS_PATTERNS:
+ latest_python_version =
latest_python_versions[python_major_minor_version]
+ for line_format, quoting in PYTHON_PATTERNS:
+ line_pattern =
re.compile(line_format.format(python_major_minor=python_major_minor_version))
new_content = replace_version(
line_pattern,
- get_replacement(node_lts_version, quoting),
+ get_replacement(latest_python_version, quoting),
new_content,
keep_length,
)
- if UPGRADE_HATCH:
- new_content = re.sub(
- r"(HATCH_VERSION = )(\"[0-9.abrc]+\")",
- f'HATCH_VERSION = "{hatch_version}"',
- new_content,
- )
- new_content = re.sub(
- r"(HATCH_VERSION=)(\"[0-9.abrc]+\")",
- f'HATCH_VERSION="{hatch_version}"',
- new_content,
- )
- new_content = re.sub(
- r"(hatch==)([0-9.abrc]+)",
- f"hatch=={hatch_version}",
- new_content,
- )
- new_content = re.sub(
- r"(hatch>=)([0-9.abrc]+)",
- f"hatch>={hatch_version}",
- new_content,
- )
- if UPGRADE_PYYAML:
- new_content = re.sub(
- r"(PYYAML_VERSION = )(\"[0-9.abrc]+\")",
- f'PYYAML_VERSION = "{pyyaml_version}"',
- new_content,
- )
- new_content = re.sub(
- r"(PYYAML_VERSION=)(\"[0-9.abrc]+\")",
- f'PYYAML_VERSION="{pyyaml_version}"',
- new_content,
- )
- new_content = re.sub(
- r"(pyyaml>=)(\"[0-9.abrc]+\")",
- f'pyyaml>="{pyyaml_version}"',
- new_content,
- )
- new_content = re.sub(
- r"(pyyaml>=)([0-9.abrc]+)",
- f"pyyaml>={pyyaml_version}",
- new_content,
- )
- if UPGRADE_GITPYTHON:
- new_content = re.sub(
- r"(GITPYTHON_VERSION = )(\"[0-9.abrc]+\")",
- f'GITPYTHON_VERSION = "{gitpython_version}"',
- new_content,
- )
- new_content = re.sub(
- r"(GITPYTHON_VERSION=)(\"[0-9.abrc]+\")",
- f'GITPYTHON_VERSION="{gitpython_version}"',
- new_content,
- )
- if UPGRADE_RICH:
- new_content = re.sub(
- r"(RICH_VERSION = )(\"[0-9.abrc]+\")",
- f'RICH_VERSION = "{rich_version}"',
- new_content,
- )
- new_content = re.sub(
- r"(RICH_VERSION=)(\"[0-9.abrc]+\")",
- f'RICH_VERSION="{rich_version}"',
- new_content,
- )
- if UPGRADE_RUFF:
- new_content = re.sub(
- r"(ruff==)([0-9.abrc]+)",
- f"ruff=={ruff_version}",
- new_content,
- )
- new_content = re.sub(
- r"(ruff>=)([0-9.abrc]+)",
- f"ruff>={ruff_version}",
- new_content,
- )
- if UPGRADE_MYPY:
- console.print(f"[bright_blue]Latest mypy version: {mypy_version}")
+ if python_major_minor_version == DEFAULT_PROD_IMAGE_PYTHON_VERSION:
+ new_content = apply_pattern_replacements(
+ new_content, latest_python_version,
AIRFLOW_IMAGE_PYTHON_PATTERNS, keep_length
+ )
- new_content = re.sub(
- r"(mypy==)([0-9.]+)",
- f"mypy=={mypy_version}",
- new_content,
- )
+ # Apply simple regex replacements
+ for package_name, patterns in SIMPLE_VERSION_PATTERNS.items():
+ should_upgrade = globals().get(f"UPGRADE_{package_name.upper()}",
False)
+ version = versions.get(package_name, "")
+ if should_upgrade and version:
+ new_content = apply_simple_regex_replacements(new_content,
version, patterns)
- if UPGRADE_PROTOC:
- console.print(f"[bright_blue]Latest protoc image version:
{protoc_version}")
+ return new_content
+
+
+def process_all_files(versions: dict[str, str], latest_python_versions:
dict[str, str]) -> bool:
+ """
+ Process all files and apply version updates.
+
+ Returns:
+ True if any files were changed, False otherwise.
+ """
+ changed = False
+ for file_to_update, keep_length in FILES_TO_UPDATE:
+ console.print(f"[bright_blue]Updating {file_to_update}")
+ file_content = file_to_update.read_text()
+ new_content = update_file_with_versions(file_content, keep_length,
versions, latest_python_versions)
- new_content = re.sub(
- r"(rvolosatovs/protoc:)(v[0-9.]+)",
- f"rvolosatovs/protoc:{protoc_version}",
- new_content,
- )
if new_content != file_content:
- file.write_text(new_content)
- console.print(f"[bright_blue]Updated {file}")
+ file_to_update.write_text(new_content)
+ console.print(f"[bright_blue]Updated {file_to_update}")
changed = True
+ return changed
+
+
+def sync_breeze_lock_file() -> None:
+ """Run uv sync to update breeze's lock file."""
+ console.print("[bright_blue]Running breeze's uv sync to update the lock
file")
+ copy_env = os.environ.copy()
+ del copy_env["VIRTUAL_ENV"]
+ subprocess.run(
+ ["uv", "sync", "--resolution", "highest", "--upgrade"],
+ check=True,
+ cwd=AIRFLOW_ROOT_PATH / "dev" / "breeze",
+ env=copy_env,
+ )
+
+
+def main() -> None:
+ """Main entry point for the version upgrade script."""
+ retrieve_gh_token(description="airflow-upgrade-important-versions",
scopes="public_repo")
+
+ versions = fetch_all_package_versions()
+ log_special_versions(versions)
+ latest_python_versions = fetch_python_versions()
+
+ changed = process_all_files(versions, latest_python_versions)
+
if changed:
- console.print("[bright_blue]Running breeze's uv sync to update the
lock file")
- copy_env = os.environ.copy()
- del copy_env["VIRTUAL_ENV"]
- subprocess.run(
- ["uv", "sync", "--resolution", "highest", "--upgrade"],
- check=True,
- cwd=AIRFLOW_ROOT_PATH / "dev" / "breeze",
- env=copy_env,
- )
+ sync_breeze_lock_file()
if not os.environ.get("CI"):
console.print("[bright_blue]Please commit the changes")
sys.exit(1)
+
+
+if __name__ == "__main__":
+ main()