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}")