diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bbc2422d803e95553ed5bf8849dfd778cc14dffe..50a438e0dbe16d9cbfe1ef64bfd49feacda57737 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -192,6 +192,7 @@ build-docs-check: image: "${YAOOK_K8S_CI_IMAGE_NAME}:${YAOOK_K8S_CI_IMAGE_TAG}" script: - towncrier build --version x.x.x --keep + - python docs/generate_supported_releases.py - sphinx-build -W docs _build/html - mv _build/html public artifacts: @@ -261,6 +262,7 @@ release-note-file-check: if [ "${exit_code}" != 0 ]; then exit "${exit_code}" fi + - python docs/generate_supported_releases.py - | if [ "${FORK}" = "False" ]; then git fetch origin "${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}" diff --git a/docs/_releasenotes/1875.docs.supported-versions b/docs/_releasenotes/1875.docs.supported-versions new file mode 100644 index 0000000000000000000000000000000000000000..4990cfb9f7e44a49d00efe05fd1cef59ded7e25c --- /dev/null +++ b/docs/_releasenotes/1875.docs.supported-versions @@ -0,0 +1 @@ +Explicitly add supported versions to the documentation. diff --git a/docs/generate_supported_releases.py b/docs/generate_supported_releases.py new file mode 100755 index 0000000000000000000000000000000000000000..6726457dbd0e66717ee8d4fa8030f5e6c3cb6627 --- /dev/null +++ b/docs/generate_supported_releases.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +import argparse +import os +import re +from datetime import datetime, timedelta +from packaging.version import parse as parse_version +from jinja2 import Environment, FileSystemLoader +from itertools import groupby + + +def parse_changelog(changelog_content): + """Parse changelog content and extract version information.""" + version_pattern = r'v(\d+\.\d+\.\d+)\s+\((\d{4}-\d{2}-\d{2})\)' + matches = re.finditer(version_pattern, changelog_content) + versions = [] + + for match in matches: + version, date_str = match.groups() + versions.append({ + 'version': version, + 'date': datetime.strptime(date_str, '%Y-%m-%d') + }) + + return sorted(versions, key=lambda x: parse_version(x['version']), reverse=True) + + +def get_latest_patch_versions(versions): + """Group versions by major.minor and keep only the latest patch version.""" + def get_major_minor(version): + return '.'.join(version['version'].split('.')[:2]) + + # Sort versions by major.minor and then by patch level + versions.sort(key=lambda x: (get_major_minor(x), parse_version(x['version'])), + reverse=True) + + # Group by major.minor and take only the first (latest) patch version + latest_versions = [] + for _, group in groupby(versions, key=get_major_minor): + latest_versions.append(next(group)) + + return latest_versions + + +def get_supported_releases(versions, current_date): + """ + Determine supported versions based on the rules: + - A release becomes EOL when there are three newer (major/minor) versions + - But earliest four weeks after it has been released + """ + supported = [] + major_minor_versions = [] + + # Get only latest patch versions + latest_versions = get_latest_patch_versions(versions) + + for ver in latest_versions: + major_minor = '.'.join(ver['version'].split('.')[:2]) + if major_minor not in major_minor_versions: + major_minor_versions.append(major_minor) + + for ver in latest_versions: + release_date = ver['date'] + four_weeks_passed = (current_date - release_date) > timedelta(weeks=4) + major_minor = '.'.join(ver['version'].split('.')[:2]) + newer_major_minor_versions = len([ + v for v in major_minor_versions + if parse_version(v) > parse_version(major_minor) + ]) + + if newer_major_minor_versions < 3 or not four_weeks_passed: + supported.append({ + 'number': f"v{ver['version']}", + 'date': ver['date'].strftime('%Y-%m-%d'), + 'eol': (release_date + timedelta(weeks=4)).strftime('%Y-%m-%d') + if newer_major_minor_versions >= 3 else None + }) + + return supported + + +def generate_doc_from_template(versions, template_path, output_path): + """Generate documentation using Jinja2 template.""" + env = Environment( + loader=FileSystemLoader(os.path.dirname(template_path)), + trim_blocks=True, + lstrip_blocks=True + ) + + template_name = os.path.basename(template_path) + template = env.get_template(template_name) + + content = template.render(versions=versions) + + os.makedirs(os.path.dirname(output_path), exist_ok=True) + + with open(output_path, 'w') as f: + f.write(content) + + +def main(): + parser = argparse.ArgumentParser( + description="Generate supported versions documentation" + ) + parser.add_argument( + "--changelog", default="CHANGELOG.rst", + help="Path to changelog file" + ) + parser.add_argument( + "--template", default="docs/supported_releases_template.jinja", + help="Path to Jinja template file" + ) + parser.add_argument( + "--output", default="docs/supported_releases.rst", + help="Output file path" + ) + + args = parser.parse_args() + + with open(args.changelog, 'r') as f: + changelog_content = f.read() + + versions = parse_changelog(changelog_content) + + current_date = datetime.now() + supported_releases = get_supported_releases(versions, current_date) + + generate_doc_from_template(supported_releases, args.template, args.output) + + print(f"Generated supported versions documentation at {args.output}") + + +if __name__ == "__main__": + main() diff --git a/docs/index.md b/docs/index.md index 3f1a9cc7f7bf1713b2f03b45595190dc02c1291a..a8e1cf82bfcf136830c31288b673f9c8066d96c9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,9 +12,11 @@ hide-doc: true .. toctree:: :hidden: + :caption: Version Information Releases releasenotes + supported_releases .. toctree:: :hidden: diff --git a/docs/supported_releases.rst b/docs/supported_releases.rst new file mode 100644 index 0000000000000000000000000000000000000000..08e7322e435363d51e1a1ad07b94ef1c940662dc --- /dev/null +++ b/docs/supported_releases.rst @@ -0,0 +1,29 @@ + +Supported Releases +================== + +This document lists all currently supported releases of YAOOK/k8s. + +.. Warning:: + + Please make sure to open the newest version of this document to see the latest supported releases. + +Support Policy +-------------- + +See :doc:`/user/explanation/deprecation-policy` for our policy on supporting and deprecating releases. + +Currently Supported Releases +---------------------------- + +* v9.1.7 (2025-05-07) +* v9.0.3 (2025-03-07) +* v8.1.9 (2025-02-04) + + +Upgrade Recommendations +----------------------- + +* We recommend staying on the latest supported version +* Plan upgrades before a version reaches its EOL date +* For upgrade instructions, see :doc:`/user/tutorial/upgrade-release` diff --git a/docs/supported_releases_template.jinja b/docs/supported_releases_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..23f940f1df14571abc98179131fb15e1aae6d9d1 --- /dev/null +++ b/docs/supported_releases_template.jinja @@ -0,0 +1,33 @@ +{# supported_releases.rst.template #} + +Supported Releases +================== + +This document lists all currently supported releases of YAOOK/k8s. + +.. Warning:: + + Please make sure to open the newest version of this document to see the latest supported releases. + +Support Policy +-------------- + +See :doc:`/user/explanation/deprecation-policy` for our policy on supporting and deprecating releases. + +Currently Supported Releases +---------------------------- + +{% for version in versions %} +* {{ version.number }} ({{ version.date }}) +{% if version.eol %} + * **EOL date:** {{ version.eol }} +{% endif %} +{% endfor %} + + +Upgrade Recommendations +----------------------- + +* We recommend staying on the latest supported version +* Plan upgrades before a version reaches its EOL date +* For upgrade instructions, see :doc:`/user/tutorial/upgrade-release`