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 2ec28175caa Add protoc pinning and include it in important versions 
upgrade (#58244)
2ec28175caa is described below

commit 2ec28175caa269165a8b3319e1eb5cbfbb57ec31
Author: Jarek Potiuk <[email protected]>
AuthorDate: Thu Nov 13 00:26:32 2025 +0100

    Add protoc pinning and include it in important versions upgrade (#58244)
---
 .github/workflows/basic-tests.yml             |  2 +
 .pre-commit-config.yaml                       |  1 +
 go-sdk/.pre-commit-config.yaml                |  2 +-
 scripts/ci/prek/upgrade_important_versions.py | 81 +++++++++++++++++++++++++++
 4 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/basic-tests.yml 
b/.github/workflows/basic-tests.yml
index 7b61ce37242..63d51fea1b7 100644
--- a/.github/workflows/basic-tests.yml
+++ b/.github/workflows/basic-tests.yml
@@ -324,6 +324,7 @@ jobs:
           UPGRADE_RICH: "false"
           UPGRADE_RUFF: "false"
           UPGRADE_MYPY: "false"
+          UPGRADE_PROTOC: "false"
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       - name: "Run automated upgrade for important versions minus uv (failing 
if needed)"
         run: |
@@ -348,6 +349,7 @@ jobs:
           UPGRADE_RICH: "true"
           UPGRADE_RUFF: "true"
           UPGRADE_MYPY: "true"
+          UPGRADE_PROTOC: "false"
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
   test-airflow-release-commands:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 67881631296..6947d80ac45 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -555,6 +555,7 @@ repos:
           ^.*RELEASE_NOTES\.rst$|
           ^scripts/ci/docker-compose/integration-keycloak\.yml$|
           ^scripts/ci/docker-compose/keycloak/keycloak-entrypoint\.sh$|
+          ^scripts/ci/prek/upgrade_important_versions.py$|
           ^scripts/ci/prek/vendor_k8s_json_schema\.py$
       - id: check-template-context-variable-in-sync
         name: Sync template context variable refs
diff --git a/go-sdk/.pre-commit-config.yaml b/go-sdk/.pre-commit-config.yaml
index 35267d13ab5..6452ceaf370 100644
--- a/go-sdk/.pre-commit-config.yaml
+++ b/go-sdk/.pre-commit-config.yaml
@@ -78,7 +78,7 @@ repos:
         language: docker_image
         types: [file, proto]
         entry: >-
-          rvolosatovs/protoc
+          rvolosatovs/protoc:v7.0.0
           --go_out=.
           --go_opt=paths=source_relative
           --go-grpc_out=.
diff --git a/scripts/ci/prek/upgrade_important_versions.py 
b/scripts/ci/prek/upgrade_important_versions.py
index 4e3b3088ce6..4886a6306f9 100755
--- a/scripts/ci/prek/upgrade_important_versions.py
+++ b/scripts/ci/prek/upgrade_important_versions.py
@@ -86,6 +86,7 @@ FILES_TO_UPDATE: list[tuple[Path, bool]] = [
     (AIRFLOW_CORE_ROOT_PATH / "docs" / "best-practices.rst", False),
     (AIRFLOW_ROOT_PATH / "dev" / "provider_db_inventory.py", False),
     (AIRFLOW_ROOT_PATH / "dev" / "pyproject.toml", False),
+    (AIRFLOW_ROOT_PATH / "go-sdk" / ".pre-commit-config.yaml", False),
 ]
 for file in DOCKER_IMAGES_EXAMPLE_DIR_PATH.rglob("*.sh"):
     FILES_TO_UPDATE.append((file, False))
@@ -185,6 +186,76 @@ def get_latest_lts_node_version() -> str:
     return latest_version
 
 
+def get_latest_image_version(image: str) -> str:
+    """
+    Fetch the latest tag released for a DockerHub image.
+
+    Args:
+        image: DockerHub image name in the format "namespace/repository" or 
just "repository" for official images
+
+    Returns:
+        The latest tag version as a string
+    """
+    if VERBOSE:
+        console.print(f"[bright_blue]Fetching latest tag for DockerHub image: 
{image}")
+
+    # Split image into namespace and repository
+    if "/" in image:
+        namespace, repository = image.split("/", 1)
+    else:
+        # Official images use 'library' as namespace
+        namespace = "library"
+        repository = image
+
+    # DockerHub API endpoint for tags
+    url = 
f"https://registry.hub.docker.com/v2/repositories/{namespace}/{repository}/tags";
+    params = {"page_size": 100, "ordering": "last_updated"}
+
+    headers = {"User-Agent": "Python requests"}
+    response = requests.get(url, headers=headers, params=params)
+    response.raise_for_status()
+
+    data = response.json()
+    tags = data.get("results", [])
+
+    if not tags:
+        console.print(f"[bright_red]No tags found for image {image}")
+        return ""
+
+    # Filter out non-version tags and sort by version
+    version_tags = []
+    for tag in tags:
+        tag_name = tag["name"]
+        # Skip tags like 'latest', 'stable', etc.
+        if tag_name in ["latest", "stable", "main", "master"]:
+            continue
+        try:
+            # Try to parse as version to filter out non-version tags
+            # Remove leading 'v' if present
+            version_str = tag_name.lstrip("v")
+            version_obj = Version(version_str)
+            version_tags.append((version_obj, tag_name))
+        except Exception:
+            # Skip tags that don't parse as versions
+            continue
+
+    if not version_tags:
+        # If no version tags found, return the first tag
+        latest_tag = tags[0]["name"]
+        if VERBOSE:
+            console.print(f"[bright_blue]Latest tag for {image}: {latest_tag} 
(no version tags found)")
+        return latest_tag
+
+    # Sort by version and get the latest
+    version_tags.sort(key=lambda x: x[0], reverse=True)
+    latest_tag = version_tags[0][1]
+
+    if VERBOSE:
+        console.print(f"[bright_blue]Latest tag for {image}: {latest_tag}")
+
+    return latest_tag
+
+
 class Quoting(Enum):
     UNQUOTED = 0
     SINGLE_QUOTED = 1
@@ -293,6 +364,7 @@ UPGRADE_RICH: bool = os.environ.get("UPGRADE_RICH", 
UPGRADE_ALL_BY_DEFAULT_STR).
 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"
 
 ALL_PYTHON_MAJOR_MINOR_VERSIONS = ["3.10", "3.11", "3.12", "3.13"]
 DEFAULT_PROD_IMAGE_PYTHON_VERSION = "3.12"
@@ -339,6 +411,7 @@ if __name__ == "__main__":
     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 ""
     latest_python_versions: dict[str, str] = {}
     latest_image_python_version = ""
     if UPGRADE_PYTHON:
@@ -489,6 +562,14 @@ if __name__ == "__main__":
                 new_content,
             )
 
+        if UPGRADE_PROTOC:
+            console.print(f"[bright_blue]Latest protoc image version: 
{protoc_version}")
+
+            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}")

Reply via email to