You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by el...@apache.org on 2026/04/14 18:52:41 UTC
(airflow) branch main updated: Skip yanked versions in constraints-version-check when newer than current (#65236)
This is an automated email from the ASF dual-hosted git repository.
eladkal 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 d1d313ab5cf Skip yanked versions in constraints-version-check when newer than current (#65236)
d1d313ab5cf is described below
commit d1d313ab5cfef2d994e3f3e6b8d75bacbed22587
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Tue Apr 14 20:52:31 2026 +0200
Skip yanked versions in constraints-version-check when newer than current (#65236)
When a newer release has been yanked from PyPI it must not be proposed as
an upgrade candidate. The check now treats a release as "does not exist"
when all of its files are yanked, so yanked versions are ignored when
picking the latest version (with or without cooldown), counting versions
behind, and determining whether a package has any newer release since
the constraints file was generated.
---
.../airflow_breeze/utils/constraints_version_check.py | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/dev/breeze/src/airflow_breeze/utils/constraints_version_check.py b/dev/breeze/src/airflow_breeze/utils/constraints_version_check.py
index 25669c18863..a6284c9e8bc 100755
--- a/dev/breeze/src/airflow_breeze/utils/constraints_version_check.py
+++ b/dev/breeze/src/airflow_breeze/utils/constraints_version_check.py
@@ -62,6 +62,13 @@ def parse_constraints_generation_date(lines):
return None
+def is_yanked_release(release_files: list[dict] | None) -> bool:
+ """Return True if the release has files and all of them are yanked on PyPI."""
+ if not release_files:
+ return False
+ return all(f.get("yanked", False) for f in release_files)
+
+
def is_valid_version(version_str: str, latest_version: Version) -> bool:
"""Check if the version string is a valid one.
@@ -92,6 +99,7 @@ def count_versions_between(releases: dict[str, Any], current_version: str, lates
v
for v in releases.keys()
if releases[v]
+ and not is_yanked_release(releases[v])
and is_valid_version(version_str=v, latest_version=latest)
and current < version.parse(v) <= latest
]
@@ -163,6 +171,8 @@ def should_show_package(releases, latest_version, constraints_date, mode, is_lat
for version_info in releases.values():
if not version_info:
continue
+ if is_yanked_release(version_info):
+ continue
try:
release_date = datetime.fromisoformat(
version_info[0]["upload_time_iso_8601"].replace("Z", "+00:00")
@@ -187,6 +197,8 @@ def get_latest_version_with_cooldown(releases: dict[str, Any], cooldown_days: in
for v, release_files in releases.items():
if not release_files:
continue
+ if is_yanked_release(release_files):
+ continue
try:
parsed_v = version.parse(v)
except version.InvalidVersion:
@@ -213,12 +225,12 @@ def get_first_newer_release_date_str(releases, current_version):
try:
current = version.parse(current_version)
- # Filter and parse versions, excluding pre-releases and invalid versions
+ # Filter and parse versions, excluding pre-releases, yanked, and invalid versions
valid_versions = []
for v in releases:
try:
parsed_v = version.parse(v)
- if not parsed_v.is_prerelease and releases[v]: # Check if release data exists
+ if not parsed_v.is_prerelease and releases[v] and not is_yanked_release(releases[v]):
valid_versions.append(parsed_v)
except version.InvalidVersion:
continue