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

gopidesu 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 67596f9432e Add release date to provider docs (#50622)
67596f9432e is described below

commit 67596f9432ecebf19710b8a72b67e1e76e8cd8be
Author: GPK <[email protected]>
AuthorDate: Sat Jul 26 00:01:54 2025 +0100

    Add release date to provider docs (#50622)
    
    * Add release date to providers index
    
    * Add release date to providers index
    
    * Use release version to find release date
    
    * Update review suggestions
---
 .../templates/PROVIDER_INDEX_TEMPLATE.rst.jinja2   |  2 +
 .../templates/PROVIDER_README_TEMPLATE.rst.jinja2  |  1 +
 .../extra_provider_files_with_substitutions.py     | 50 +++++++++++++++++++++-
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git 
a/dev/breeze/src/airflow_breeze/templates/PROVIDER_INDEX_TEMPLATE.rst.jinja2 
b/dev/breeze/src/airflow_breeze/templates/PROVIDER_INDEX_TEMPLATE.rst.jinja2
index fb857bbe6ae..9670dfa98d5 100644
--- a/dev/breeze/src/airflow_breeze/templates/PROVIDER_INDEX_TEMPLATE.rst.jinja2
+++ b/dev/breeze/src/airflow_breeze/templates/PROVIDER_INDEX_TEMPLATE.rst.jinja2
@@ -36,6 +36,8 @@
 
 Release: {{ RELEASE }}{{ VERSION_SUFFIX }}
 
+Release Date: `|PypiReleaseDate|`
+
 Provider package
 ----------------
 
diff --git 
a/dev/breeze/src/airflow_breeze/templates/PROVIDER_README_TEMPLATE.rst.jinja2 
b/dev/breeze/src/airflow_breeze/templates/PROVIDER_README_TEMPLATE.rst.jinja2
index ab3210d866b..9392a0247ea 100644
--- 
a/dev/breeze/src/airflow_breeze/templates/PROVIDER_README_TEMPLATE.rst.jinja2
+++ 
b/dev/breeze/src/airflow_breeze/templates/PROVIDER_README_TEMPLATE.rst.jinja2
@@ -43,6 +43,7 @@ Package ``{{ PACKAGE_PIP_NAME }}``
 
 Release: ``{{ RELEASE }}{{ VERSION_SUFFIX }}``
 
+Release Date: `|PypiReleaseDate|`
 
 {{  PROVIDER_DESCRIPTION | safe }}
 
diff --git 
a/devel-common/src/sphinx_exts/extra_provider_files_with_substitutions.py 
b/devel-common/src/sphinx_exts/extra_provider_files_with_substitutions.py
index 065ba6a27bd..6526b1e3bef 100644
--- a/devel-common/src/sphinx_exts/extra_provider_files_with_substitutions.py
+++ b/devel-common/src/sphinx_exts/extra_provider_files_with_substitutions.py
@@ -16,8 +16,51 @@
 # under the License.
 from __future__ import annotations
 
+import os
+from datetime import datetime
 from pathlib import Path
 
+from packaging.version import Version
+
+
+def _get_rc_matching_version(releases: dict, version: str):
+    """
+    Get the latest release candidate version matching the given version.
+    """
+
+    matching_versions = (v for v in releases.keys() if Version(v).base_version 
== version)
+    latest_version = max(matching_versions, key=Version, default=None)
+
+    return releases.get(latest_version, []) if latest_version else []
+
+
+def get_release_date(package_name: str, version) -> str:
+    """Get the release date of the current version."""
+    if package_name == "":
+        return ""
+    import requests
+
+    resp = requests.get(f"https://pypi.org/pypi/{package_name}/json";)
+    resp_json = resp.json()
+    releases = resp_json.get("releases", {})
+    release_info = releases.get(version, [])
+
+    # If no exact version found, try to find the latest release candidate 
version
+    if not release_info and len(releases) > 0:
+        release_info = _get_rc_matching_version(releases, version)
+
+    if release_info:
+        release_date = 
datetime.fromisoformat(release_info[0].get("upload_time")).date()
+        return str(release_date)
+
+    return "Release date unknown"
+
+
+def _manual_substitution(line: str, replacements: dict[str, str]) -> str:
+    for value, repl in replacements.items():
+        line = line.replace(value, repl)
+    return line
+
 
 def fix_provider_references(app, exception):
     """Sphinx "build-finished" event handler."""
@@ -26,13 +69,18 @@ def fix_provider_references(app, exception):
     if exception or not isinstance(app.builder, 
builders.StandaloneHTMLBuilder):
         return
 
+    substitutions = {
+        "|version|": app.config.version,
+        "|PypiReleaseDate|": 
get_release_date(os.environ.get("AIRFLOW_PACKAGE_NAME", ""), 
app.config.version),
+    }
+
     # Replace `|version|` in the files that require manual substitution
     for path in Path(app.outdir).rglob("*.html"):
         if path.exists():
             lines = path.read_text().splitlines(True)
             with path.open("w") as output_file:
                 for line in lines:
-                    output_file.write(line.replace("|version|", 
app.config.version))
+                    output_file.write(_manual_substitution(line, 
substitutions))
 
 
 def setup(app):

Reply via email to