From 7982d1082fa2c163a19eb1c4dec28f57b7deb035 Mon Sep 17 00:00:00 2001 From: jh-RLI Date: Tue, 13 Oct 2026 15:41:32 +0200 Subject: [PATCH 1/4] Add a "What's new" page fed by each release's changelog highlights Rebuilds PR #2401 on the new homepage. Each changelog gains a `## Highlights` section: three to five points written for users at release time. `base.helper.release_highlights()` reads it from every released changelog (`x_y_z.md`, not `current.md`), newest first by version number, and leaves out a release without one, so a patch release does not empty the page or the link. It replaces `read_version_changes`, whose result no template read any more. - `/whats-new/` (`base:whats-new`) lists the releases on the static-page layout, each with a link to its full changelog at the release tag. - The homepage hero links "What's new in version X" when a release has highlights, and the homepage footer links the page. Bryan's sections are untouched. - The template and `current.md` carry the section; `current.md` has a draft for the next release. RELEASE_PROCEDURE.md gains the step. Co-Authored-By: tomi-rli Co-Authored-By: Claude Opus 5.5 (1M context) --- RELEASE_PROCEDURE.md | 3 + base/helper.py | 76 +++++++++--------- base/static/css/index-style.css | 10 +++ base/templates/base/index.html | 1 + base/templates/base/whats_new.html | 26 ++++++ base/templates/homepage/hero.html | 7 ++ base/tests/test_page_lint.py | 1 + base/tests/test_views.py | 1 + base/tests/test_whats_new.py | 100 ++++++++++++++++++++++++ base/urls.py | 2 + base/views.py | 11 ++- versions/changelogs/current.md | 22 ++++++ versions/changelogs/current.template.md | 8 ++ 13 files changed, 229 insertions(+), 39 deletions(-) create mode 100644 base/templates/base/whats_new.html create mode 100644 base/tests/test_whats_new.py diff --git a/RELEASE_PROCEDURE.md b/RELEASE_PROCEDURE.md index e55fde78f..3ec2d9fb1 100644 --- a/RELEASE_PROCEDURE.md +++ b/RELEASE_PROCEDURE.md @@ -56,6 +56,9 @@ Before see How to 1. Update the oeplatform/versions/changelogs/ [`current.md`](https://github.com/OpenEnergyPlatform/oeplatform/blob/develop/versions/changelogs/current.md) (see the examples of previous releases) + - Write its `## Highlights`: three to five points for users. They are the + release's entry on the platform's "What's new" page, which the homepage + links to. A release without highlights (usually a patch) is not listed. - Change filename to release version (x_x_x.md) - Copy template to `current.md` - Update version with `bumpversion --allow-dirty [minor|patch]` diff --git a/base/helper.py b/base/helper.py index 17c9a51f9..50baaaa8c 100644 --- a/base/helper.py +++ b/base/helper.py @@ -20,51 +20,55 @@ import markdown2 +from oeplatform.settings import EXTERNAL_URLS + logger = logging.getLogger("oeplatform") SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) +CHANGELOG_DIR = os.path.join(SITE_ROOT, "..", "versions", "changelogs") +RELEASED_CHANGELOG = re.compile(r"(\d+)_(\d+)_(\d+)\.md") +HIGHLIGHTS = re.compile(r"^## Highlights[ \t]*\n(.*?)(?=^## |\Z)", re.M | re.S) +COMMENT = re.compile(r"", re.S) + + @lru_cache(maxsize=None) -def read_version_changes() -> dict: - """read version and changes from changelog markdown +def release_highlights(directory=CHANGELOG_DIR) -> list: + """The `## Highlights` of every released changelog, newest first. - We use cache so it can stay in process memory and we dont have to read files - in every request. this only changes on a new release anyway, in which case - the process is restarted. + A released changelog is named `__.md` (`current.md` is + the next release, not yet out). A release without highlights, as a patch + release usually is, is left out, so the newest entry is the newest release + that has something to tell users. Cached for the process: changelogs only + change with a release, which restarts it. Returns: - dict: {"version": (major, minor, patch), "changes": changes} + list of dicts with `version` ("1.11.0"), `html` and `changelog_url` """ - os.path.dirname(os.path.realpath(__file__)) - version_expr = r"^(?P\d+)\.(?P\d+)+\.(?P\d+)$" - markdowner = markdown2.Markdown() - - logger.info("READING VERSION file.") - try: - with open( - os.path.join(SITE_ROOT, "..", "VERSION"), encoding="utf-8" - ) as version_file: - text = version_file.read() - match = re.match(version_expr, text) - if not match: - raise ValueError(text) - major, minor, patch = match.groups() - with open( - os.path.join( - SITE_ROOT, - "..", - "versions/changelogs/%s_%s_%s.md" % (major, minor, patch), - ), - encoding="utf-8", - ) as change_file: - changes = markdowner.convert( - "\n".join(line for line in change_file.readlines()) - ) - except Exception: - logger.error("READING VERSION file.") - # probably because change_file is missing - major, minor, patch, changes = "", "", "", "" - return {"version": (major, minor, patch), "changes": changes} + releases = [] + for name in os.listdir(directory): + match = RELEASED_CHANGELOG.fullmatch(name) + if not match: + continue + with open(os.path.join(directory, name), encoding="utf-8") as file: + section = HIGHLIGHTS.search(file.read()) + text = COMMENT.sub("", section.group(1)).strip() if section else "" + if not text: + continue + version = ".".join(match.groups()) + releases.append( + { + "key": tuple(int(part) for part in match.groups()), + "version": version, + "html": markdown2.markdown(text), + "changelog_url": "{}/blob/v{}/versions/changelogs/{}".format( + EXTERNAL_URLS["github_openenergyplatform_oeplatform"], + version, + name, + ), + } + ) + return sorted(releases, key=lambda release: release["key"], reverse=True) def get_json_content(path, json_id=None): diff --git a/base/static/css/index-style.css b/base/static/css/index-style.css index 1368eb1a5..9acea6a9c 100644 --- a/base/static/css/index-style.css +++ b/base/static/css/index-style.css @@ -114,6 +114,16 @@ padding: 24px 0; } +.index-hero-news { + color: var(--oep-on-strong); +} + +.index-hero-news:hover, +.index-hero-news:focus-visible { + color: var(--oep-on-strong); + text-decoration: underline; +} + .index-hero-btn { display: inline-flex; align-items: center; diff --git a/base/templates/base/index.html b/base/templates/base/index.html index db10fb689..2e190d1dc 100644 --- a/base/templates/base/index.html +++ b/base/templates/base/index.html @@ -46,6 +46,7 @@