From 2b367cc37e609b3183b3fd1aeb0234ddb6b5c178 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Thu, 8 Oct 2026 15:47:23 +0200 Subject: [PATCH] Fix/automate documentation (#1611) * also update developer * mofified for testing * fixed error message * temporarily disable all workflows * reference branch with /ref/head * force cherry-pick * allow empty commit * set write permissions * dont push update when updating version * Revert "temporarily disable all workflows" This reverts commit d8c67354d68e202b5ce893340a89931536dbcdb3. * use indices from relese list * removed versions.yaml * always sort the releases --- .github/workflows/build_documentation.yml | 27 ++-- docs/main_index/index.html.j2 | 11 +- docs/main_index/render_main_index.py | 145 +++++++++++----------- docs/main_index/versions.yaml | 77 ------------ etc/update_version.py | 13 +- 5 files changed, 103 insertions(+), 170 deletions(-) delete mode 100644 docs/main_index/versions.yaml diff --git a/.github/workflows/build_documentation.yml b/.github/workflows/build_documentation.yml index 458084c0a..f3bc49084 100644 --- a/.github/workflows/build_documentation.yml +++ b/.github/workflows/build_documentation.yml @@ -26,9 +26,9 @@ jobs: build-and-deploy: strategy: matrix: - patform: [ubuntu-latest] + platform: [ubuntu-latest] python-version: ["3.12"] - runs-on: ${{ matrix.patform }} + runs-on: ${{ matrix.platform }} defaults: run: @@ -74,24 +74,29 @@ jobs: cmake -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DSLS_BUILD_DOCS=ON -DSLS_USE_HDF5=ON -DSLS_USE_PYTHON=ON .. make -j4 make docs - - # Update main index if this is a release - - name: Update version index + + + - name: Render Documentation index if: github.event_name == 'release' run: | - python docs/main_index/render_main_index.py \ - --version "${{ steps.version.outputs.version }}" \ - --date "$(date +'%d.%m.%Y')" - + gh release list --json tagName,publishedAt > releases.json + python docs/main_index/render_main_index.py --json_releases releases.json --new_version ${{ steps.version.outputs.version }} + - name: Checkout gh-pages uses: actions/checkout@v6 with: ref: gh-pages path: gh-pages + + - name: Copy documentation to versioned folder for developer branch + if: github.event_name == 'push' && github.ref == 'refs/heads/developer' + run: | + VERSION="${{ steps.version.outputs.version }}" + mkdir -p "gh-pages/${VERSION}" + cp -r build/docs/html/. "gh-pages/${VERSION}/" - - name: Copy documentation and Release notes to versioned folder - if: github.event_name == 'release' || (github.event_name == 'push') + if: github.event_name == 'release' run: | VERSION="${{ steps.version.outputs.version }}" mkdir -p "gh-pages/${VERSION}" diff --git a/docs/main_index/index.html.j2 b/docs/main_index/index.html.j2 index baf5c8dfd..5727064ea 100644 --- a/docs/main_index/index.html.j2 +++ b/docs/main_index/index.html.j2 @@ -99,7 +99,6 @@ {% for v in versions %} -{# Check if version >= 10.0.0 for .md vs .txt #} {% set version_parts = v["version"].split('.') | map('int') | list %} {% set is_new_format = (version_parts[0] > 10) or (version_parts[0] == 10 and version_parts[1] > 0 and version_parts[2] > 0) %} {% set release_ext = '.md' if is_new_format else '.txt' %} @@ -151,10 +150,8 @@ -ery(function () { -hinxRtdTheme.Navigation.enable(true); - - \ No newline at end of file + + + diff --git a/docs/main_index/render_main_index.py b/docs/main_index/render_main_index.py index d2bbb2780..ce0c1ffff 100644 --- a/docs/main_index/render_main_index.py +++ b/docs/main_index/render_main_index.py @@ -1,98 +1,101 @@ """ -Render the index HTML from a Jinja2 template with version data. -Can also add new versions to the YAML data file. +Render the index HTML from a Jinja2 template with release data. + +The release data is a JSON list as produced by + gh release list --json tagName,publishedAt Usage: - # Just render from existing data - python render_main_index.py --template main_index.html.j2 --output main_index.html --data versions.yaml - - # Add a new version and render - python render_main_index.py --data versions.yaml --add-version 10.1.0 --type Minor --date "15.10.2025" --template main_index.html.j2 --output main_index.html + python render_main_index.py --data releases.json --template index.html.j2 --output index.html """ import argparse +import json from pathlib import Path from jinja2 import Template -import yaml import os +from datetime import date SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) -def load_versions(data_path: Path): - """Load version data from YAML file.""" - with open(data_path, 'r') as f: - data = yaml.safe_load(f) - return data['versions'] +MIN_VERSION = (5, 0, 0) # releases older than this are not listed +MIN_DOCS_VERSION = (9, 0, 0) # releases older than this have no docs -def save_versions(data_path: Path, versions): - """Save version data to YAML file.""" - data = { - 'versions': versions - } - with open(data_path, 'w') as f: - yaml.dump(data, f, default_flow_style=False, sort_keys=False) - print(f"✓ Saved version data to {data_path}") +def parse_version(tag: str): + """Return (major, minor, patch) for a tag like '10.0.1', or None for e.g. '7.0.0.rc1'.""" + parts = tag.split('.') + if len(parts) != 3 or not all(p.isdigit() for p in parts): + return None + return tuple(int(p) for p in parts) -def extract_release_type(version: str) -> str: - """Extract release type from version string.""" - parts = version.split('.') - if len(parts) != 3: - return "Unknown" - major, minor, patch = map(int, parts) - if minor == 0 and patch == 0: - return "Major" - elif patch == 0: - return "Minor" - else: + +def release_type(version): + """Derive the release type from the version number.""" + _, minor, patch = version + if patch != 0: return "Bug Fix" + if minor != 0: + return "Minor" + return "Major" -def add_version(data_path: Path, version: str, release_type: str, date: str, has_docs: bool = True): - """Add a new version to the YAML data file.""" - versions = load_versions(data_path) - - # Add to table (check if not already present) - new_entry = { - 'version': version, - 'type': release_type, - 'date': date, - 'has_docs': has_docs - } - versions.insert(0, new_entry) - - print(f"✓ Added version {new_entry} to version data") - - save_versions(data_path, versions) +def read_release_json(data_path: Path): + """Load release data from JSON file, newest version first.""" + with open(data_path, 'r') as f: + releases = json.load(f) + versions = [] + for release in releases: + version = parse_version(release['tagName']) + if version is None or version < MIN_VERSION: + continue + versions.append({ + 'version': release['tagName'], + 'type': release_type(version), + 'date': release['publishedAt'].split('T')[0], + 'has_docs': version >= MIN_DOCS_VERSION, + '_key': version, + }) -def render_template(template_path: Path, output_path: Path, data_path: Path): + versions.sort(key=lambda v: v['_key'], reverse=True) + return versions + +def render_template(template_path: Path, output_path: Path, versions : list): """Render the Jinja2 template with version data.""" - versions = load_versions(data_path) - + with open(template_path, 'r') as f: template = Template(f.read()) - + html = template.render( versions=versions ) - + with open(output_path, 'w') as f: f.write(html) - + print(f"✓ Rendered {output_path}") +def add_version(version: str, versions : list): + """Add a version to the versions dict if it is not already present.""" + tuple_version = parse_version(version) + if version not in versions: + versions.insert(0,{ + 'version': version, + 'type': release_type(tuple_version), + 'date': date.today().strftime("%Y-%m-%d"), + 'has_docs': tuple_version >= MIN_DOCS_VERSION, + '_key': tuple_version, + }) + + versions.sort(key=lambda v: v['_key'], reverse=True) def main(): - parser = argparse.ArgumentParser(description='Manage versions and render main index HTML') - parser.add_argument('--data', type=Path, default=Path(SCRIPT_DIR + "/versions.yaml"), - help='Path to versions YAML data file') - - # Options for adding a new version - parser.add_argument('--version', type=str, - help='new version (e.g., 10.1.0)') - parser.add_argument('--date', type=str, - help='Release date (e.g., 15.10.2025)') + parser = argparse.ArgumentParser(description='Render main index HTML from release data') + parser.add_argument('--json_releases', type=Path, + help='Path to releases JSON data file') + parser.add_argument('--new_version', type=str, + help='New version to add to the releases data') + # Options for rendering parser.add_argument('--template', type=Path, default=Path(SCRIPT_DIR + "/index.html.j2"), help='Path to Jinja2 template file') @@ -100,17 +103,15 @@ def main(): help='Path to output HTML file') args = parser.parse_args() - - # Add new version if requested - if args.version: - if not args.date: - parser.error("--version requires --date") - release_type = extract_release_type(args.version) - add_version(args.data, args.version, release_type, args.date, has_docs=True) - + + versions = read_release_json(args.json_releases) + + if args.new_version: + add_version(args.new_version, versions) + # Render template if requested if args.template and args.output: - render_template(args.template, args.output, args.data) + render_template(args.template, args.output, versions) elif args.template or args.output: parser.error("--template and --output must be used together") diff --git a/docs/main_index/versions.yaml b/docs/main_index/versions.yaml deleted file mode 100644 index 7f46d545e..000000000 --- a/docs/main_index/versions.yaml +++ /dev/null @@ -1,77 +0,0 @@ -versions: -- version: 10.0.0 - type: Major - date: 10.09.2025 - has_docs: true -- version: 9.2.0 - type: Minor - date: 02.06.2025 - has_docs: true -- version: 9.1.1 - type: Bug Fix - date: 22.05.2025 - has_docs: true -- version: 9.1.0 - type: Minor - date: 28.03.2025 - has_docs: true -- version: 9.0.0 - type: Major - date: 26.11.2024 - has_docs: true -- version: 8.0.2 - type: Bug Fix - date: 18.09.2024 - has_docs: false -- version: 8.0.1 - type: Bug Fix - date: 16.01.2024 - has_docs: false -- version: 8.0.0 - type: Major - date: 13.11.2023 - has_docs: false -- version: 7.0.3 - type: Bug Fix - date: 14.11.2023 - has_docs: false -- version: 7.0.2 - type: Bug Fix - date: 12.07.2023 - has_docs: false -- version: 7.0.1 - type: Bug Fix - date: 24.03.2023 - has_docs: false -- version: 7.0.0 - type: Major - date: 24.02.2023 - has_docs: false -- version: 6.1.2 - type: Bug Fix - date: 25.11.2022 - has_docs: false -- version: 6.1.1 - type: Bug Fix - date: 04.01.2022 - has_docs: false -- version: 6.1.0 - type: Minor - date: 25.11.2021 - has_docs: false -- version: 6.0.0 - type: Major - date: 20.10.2021 - has_docs: false -- version: 5.1.0 - type: Minor - date: 22.03.2021 - has_docs: false -- version: 5.0.1 - type: Bug Fix - date: 25.11.2020 - has_docs: false -- version: 5.0.0 - type: Major - date: 18.11.2020 - has_docs: false \ No newline at end of file diff --git a/etc/update_version.py b/etc/update_version.py index b3878b18e..f312c276c 100644 --- a/etc/update_version.py +++ b/etc/update_version.py @@ -2,6 +2,7 @@ # Copyright (C) 2021 Contributors to the SLS Detector Package """ Script to update VERSION file with semantic versioning if provided as an argument, or with 0.0.0 if no argument is provided. +Script also updates VERSION in RELEASE.md and adds the new version to version.yaml """ import sys @@ -32,7 +33,7 @@ def write_version_to_file(version): version_file_path = Path(SCRIPT_DIR / "VERSION") with open(version_file_path, "w") as version_file: version_file.write(version) - print(f"Version {version} written to VERSION file.") + print(f"✓ Version {version} written to VERSION file.") def extract_release_type(version: str) -> str: @@ -59,9 +60,11 @@ def get_previous_version(data_path: Path, version : str) -> str: return prev_version + def main(): parser = argparse.ArgumentParser(description='Update version release notes') parser.add_argument('--version', required=True, type=str, help='version to write to VERSION file') + parser.add_argument('--prev_version', required=False, type=str, help='previous version to write to RELEASE.md file') parser.add_argument('--update_version_only', action="store_true", help='Only update version in VERSION file, do not generate release notes') args = parser.parse_args() @@ -69,8 +72,12 @@ def main(): write_version_to_file(version) if not args.update_version_only: + + if args.prev_version is None: + raise ValueError("Previous version must be provided when generating release notes. Use --prev_version to specify the previous version.") + release_type = extract_release_type(version) - prev_version = get_previous_version(ROOT_DIR / "docs/main_index/versions.yaml", version) + prev_version = args.prev_version # Read template template = Path(ROOT_DIR / "RELEASE.md").read_text() @@ -83,7 +90,7 @@ def main(): # Write output Path(ROOT_DIR / "RELEASE.md").write_text(output) - print(f"Generated RELEASE.md for version {version}") + print(f"✓ Generated RELEASE.md for version {version}") # Main script if __name__ == "__main__":