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

jscheffl 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 43e8bbbf75a [v3-1-test] Improve pyproject.toml synchronization hook 
with fallback logic (#61597) (#61599)
43e8bbbf75a is described below

commit 43e8bbbf75a2ab00e8280e80d61c39a2b67327ad
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Feb 7 17:46:22 2026 +0100

    [v3-1-test] Improve pyproject.toml synchronization hook with fallback logic 
(#61597) (#61599)
    
    Add fallback mechanism for provider minimum version detection when
    metadata is unavailable. The hook now attempts to read local provider
    pyproject.toml files as a fallback before giving up.
    
    Changes:
    - Add get_local_provider_version() to read from local pyproject.toml
    - Extract fallback logic into _fallback_provider_version() helper
    - Add extra_information parameter to insert_documentation() for clearer
      update messages showing what was synchronized
    
    This ensures the hook works correctly even for providers without
    published metadata, improving reliability during development.
    (cherry picked from commit e7ecdbda7cf5b4faced200568e23be3bf13cffd5)
    
    Co-authored-by: Jarek Potiuk <[email protected]>
---
 scripts/ci/prek/common_prek_utils.py             |  9 ++-
 scripts/ci/prek/update_airflow_pyproject_toml.py | 77 +++++++++++++++++++++---
 2 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/scripts/ci/prek/common_prek_utils.py 
b/scripts/ci/prek/common_prek_utils.py
index 26730129814..2f0af7f9306 100644
--- a/scripts/ci/prek/common_prek_utils.py
+++ b/scripts/ci/prek/common_prek_utils.py
@@ -129,7 +129,12 @@ def pre_process_files(files: list[str]) -> list[str]:
 
 
 def insert_documentation(
-    file_path: Path, content: list[str], header: str, footer: str, 
add_comment: bool = False
+    file_path: Path,
+    content: list[str],
+    header: str,
+    footer: str,
+    add_comment: bool = False,
+    extra_information: str | None = None,
 ) -> bool:
     found = False
     old_content = file_path.read_text()
@@ -155,7 +160,7 @@ def insert_documentation(
         sys.exit(1)
     if new_content != old_content:
         file_path.write_text(new_content)
-        console.print(f"Updated {file_path}")
+        console.print(f"Updated {file_path} with {extra_information or 
'generated documentation'}")
         return True
     return False
 
diff --git a/scripts/ci/prek/update_airflow_pyproject_toml.py 
b/scripts/ci/prek/update_airflow_pyproject_toml.py
index 6c31a6e5ff4..b55642baa58 100755
--- a/scripts/ci/prek/update_airflow_pyproject_toml.py
+++ b/scripts/ci/prek/update_airflow_pyproject_toml.py
@@ -105,7 +105,49 @@ all_providers_metadata = 
json.loads(PROVIDER_METADATA_FILE_PATH.read_text())
 all_providers_dependencies = 
json.loads(PROVIDER_DEPENDENCIES_FILE_PATH.read_text())
 
 
+def _read_toml(path: Path) -> dict[str, Any]:
+    try:
+        import tomllib
+    except ImportError:
+        import tomli as tomllib
+    return tomllib.loads(path.read_text())
+
+
+def get_local_provider_version(provider_id: str) -> Version | None:
+    provider_pyproject = PROVIDERS_DIR / provider_path(provider_id) / 
"pyproject.toml"
+    if not provider_pyproject.exists():
+        return None
+    try:
+        provider_toml = _read_toml(provider_pyproject)
+    except Exception:
+        return None
+    version_str = provider_toml.get("project", {}).get("version")
+    if not version_str:
+        return None
+    return parse_version(version_str)
+
+
+def _fallback_provider_version(
+    provider_id: str, min_version_override: Version | None
+) -> tuple[Version | None, str]:
+    if min_version_override:
+        console.print(
+            f"[yellow]Provider id {provider_id} min version fallback:[/] "
+            f"MIN_VERSION_OVERRIDE -> {min_version_override}"
+        )
+        return min_version_override, f" # Set from MIN_VERSION_OVERRIDE in 
{Path(__file__).name}"
+    local_version = get_local_provider_version(provider_id)
+    if local_version:
+        console.print(
+            f"[yellow]Provider id {provider_id} min version fallback:[/] "
+            f"local provider pyproject.toml -> {local_version}"
+        )
+        return local_version, " # Set from local provider pyproject.toml"
+    return None, ""
+
+
 def find_min_provider_version(provider_id: str) -> tuple[Version | None, str]:
+    console.print(f"[bright_blue]Finding min version for provider id:[/] 
{provider_id}")
     metadata = all_providers_metadata.get(provider_id)
     # We should periodically update the starting date to avoid pip install 
resolution issues
     # TODO: when min Python version is 3.11 change back the code to 
fromisoformat
@@ -116,10 +158,11 @@ def find_min_provider_version(provider_id: str) -> 
tuple[Version | None, str]:
     last_version_newer_than_cutoff: Version | None = None
     date_released: datetime | None = None
     min_version_override = MIN_VERSION_OVERRIDE.get(provider_id)
+    override_comment = ""
     if not metadata:
-        if not min_version_override:
-            return None, ""
-        last_version_newer_than_cutoff = min_version_override
+        last_version_newer_than_cutoff, override_comment = 
_fallback_provider_version(
+            provider_id, min_version_override
+        )
     else:
         versions: list[Version] = sorted([parse_version(version) for version 
in metadata], reverse=True)
         for version in versions:
@@ -130,11 +173,19 @@ def find_min_provider_version(provider_id: str) -> 
tuple[Version | None, str]:
             if date_released < cut_off_date:
                 break
             last_version_newer_than_cutoff = version
-    console.print(
-        f"[bright_blue]Provider id {provider_id} min version found:[/] "
-        f"{last_version_newer_than_cutoff} (date {date_released}"
-    )
-    override_comment = ""
+        if not last_version_newer_than_cutoff:
+            last_version_newer_than_cutoff, override_comment = 
_fallback_provider_version(
+                provider_id, min_version_override
+            )
+    if date_released:
+        console.print(
+            f"[bright_blue]Provider id {provider_id} min version found:[/] "
+            f"{last_version_newer_than_cutoff} (date {date_released})"
+        )
+    else:
+        console.print(
+            f"[yellow]Provider id {provider_id} has no released versions newer 
than cutoff date {cut_off_date}![/]"
+        )
     if last_version_newer_than_cutoff:
         if min_version_override and min_version_override > 
last_version_newer_than_cutoff:
             console.print(
@@ -211,13 +262,17 @@ if __name__ == "__main__":
         all_optional_dependencies,
         START_OPTIONAL_DEPENDENCIES,
         END_OPTIONAL_DEPENDENCIES,
+        False,
+        "optional dependencies",
     )
     all_mypy_paths = []
     for provider_id in all_providers:
         provider_mypy_path = 
f"$MYPY_CONFIG_FILE_DIR/providers/{provider_path(provider_id)}"
         all_mypy_paths.append(f'    "{provider_mypy_path}/src",\n')
         all_mypy_paths.append(f'    "{provider_mypy_path}/tests",\n')
-    insert_documentation(AIRFLOW_PYPROJECT_TOML_FILE, all_mypy_paths, 
START_MYPY_PATHS, END_MYPY_PATHS)
+    insert_documentation(
+        AIRFLOW_PYPROJECT_TOML_FILE, all_mypy_paths, START_MYPY_PATHS, 
END_MYPY_PATHS, False, "mypy paths"
+    )
     all_workspace_items = []
     for provider_id in all_providers:
         all_workspace_items.append(f"{provider_distribution_name(provider_id)} 
= {{ workspace = true }}\n")
@@ -226,6 +281,8 @@ if __name__ == "__main__":
         all_workspace_items,
         START_WORKSPACE_ITEMS,
         END_WORKSPACE_ITEMS,
+        False,
+        "workspace items",
     )
     all_workspace_members = []
     for provider_id in all_providers:
@@ -235,4 +292,6 @@ if __name__ == "__main__":
         all_workspace_members,
         START_PROVIDER_WORKSPACE_MEMBERS,
         END_PROVIDER_WORKSPACE_MEMBERS,
+        False,
+        "provider workspace members",
     )

Reply via email to