Skip to content

Release doc page dates - #7849

Open
bmwiedemann wants to merge 2 commits into
OSGeo:mainfrom
bmwiedemann:release-doc-page-dates
Open

Release doc page dates#7849
bmwiedemann wants to merge 2 commits into
OSGeo:mainfrom
bmwiedemann:release-doc-page-dates

Conversation

@bmwiedemann

Copy link
Copy Markdown
Contributor

While working on reproducible builds for openSUSE, I found that
our grass-8.5.0 package still had variations of Accessed date in html and md docs.
I had ClaudeAI debug it and it found that the replacements of #3417 were not enough:

A) mapping of doc entries to JSON was faulty and incomplete
B) ordering influenced results
C) the fallback of using directory mtimes causes variations, because extracting a tarball updates these dir-mtimes.

Some testing was done and looked good.

generate_last_commit_file.py keyed core_modules_with_last_commit.json by
the basename of each directory containing a .html file, while
get_git_commit_from_file() looks entries up by page name. Pages whose
name differs from their directory therefore never matched: r.watershed
(html in front/), r3.mapcalc (in the r.mapcalc directory), the wxGUI.*
pages (all in gui/wxpython/docs/), the intro and driver pages
(databaseintro in db/, helptext in lib/init/, ...) and the Markdown-only
development pages in doc/, which have no .html file at all. In a build
from a release tarball these pages fell back to the source directory
mtime, which is the build time, so they said "Accessed: <build time>"
instead of "Latest change: <date> in commit: <hash>" and differed
between two builds of the same source.

Key the JSON by page name instead, one entry per .html or .md file,
keeping the last commit of the directory the page lives in as the
recorded commit so that existing entries and the output of builds with
Git history are unchanged. Sort the walk so that the few duplicate page
names (r.drain in raster/ and scripts/, the example pages under doc/)
resolve to the same entry in every run. This grows the file from 586 to
651 entries.

mkhtml.py had a second bug hiding some of the same pages: the
"<!-- meta page name: -->" and "<!-- meta page description: -->"
comments overwrote pgm with the page title (e.g. "LRS" for the lrs
page), which is not a JSON key, so even pages with a matching entry
missed the lookup. Keep the title in a separate pgm_title used for the
generated header and source code section, whose rendered output is
unchanged, and leave pgm as the page name for the commit and addon path
lookups.

Together with the release workflow, which already runs
generate_last_commit_file.py and ships the JSON in the release tarball,
this makes all the previously date-stamped pages (71 html, 71 man,
74 markdown in GRASS 8.5.0) show the real last-change date and build
reproducibly.

This was found and fixed while working on reproducible builds for
openSUSE, with the analysis and patch drafted by an AI assistant
(Claude) and reviewed by the author.
Images in manual_gallery.html were sorted by the manual page they
belong to alone, so multiple images of the same page (e.g. the three
wxGUI.tplot screenshots) kept their os.listdir() order, which is the
filesystem order and differs between builds. Sort by image name within
one manual page to make the gallery reproducible.

This patch was done while working on reproducible builds for openSUSE.
@github-actions github-actions Bot added Python Related code is in Python docs labels Aug 25, 2026

@echoix echoix left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The end of the tests are doing something different, I still think it's a valid change. Can someone else review?

all core modules with their last commit. Used by GitHub "Additional Checks"
action workflow.
Script for testing that the core_modules_with_last_commit.json file
contains every documentation page with its last commit. Used by GitHub

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To reread, it's different, but I like the new text better

@echoix

echoix commented Aug 25, 2026

Copy link
Copy Markdown
Member

There seems to be an outage of some sort

@wenzeslaus wenzeslaus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty good overall. I have a question about the test.

core_module = os.path.basename(core_module_path)
assert core_module in read_json_file
@pytest.mark.parametrize(("page", "page_path"), PAGES)
def test_pages_in_json_file(read_json_file, page, page_path):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm just confused about fixtures here, but page_path is unused.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used in test_compare_json_file_data and this way, we can use the same list of PAGES for both.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is way to not have the unused param, without duplicating the list:

  @pytest.mark.depends(on=["test_json_file_is_not_empty"])
  @pytest.mark.parametrize("page", [page for page, _ in PAGES])
  def test_pages_in_json_file(read_json_file, page):
      assert page in read_json_file

but not sure, if it is worth the change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Python Related code is in Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants