diff options
| author | Agando <roduccomm@gmail.com> | 2026-10-27 17:18:30 +0100 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-10-27 17:18:30 +0100 |
| commit | 7165c9eeccce44d4cd83194de5a200973e80c45a (patch) | |
| tree | 8cd17a397999c18c2008407e5eeff2acd1b2b9e3 /scripts/newos4-maintain.py | |
| parent | 4251edccc2e4fa587b26e908b301283cc94ae651 (diff) | |
feat(docs): generate the changelog from git and keep it current in maintenance
The page at spaces/agando/downloads/changelog.html was hand-built from VFS notes by the
in-page agent: 11 entries, huge honest holes ("v4.6.59 - v4.6.100 unknown"), and it had
stopped at v4.6.101 while the app was running v4.6.119. A docs page that lags the release
reads as current, which is worse than no page.
- scripts/build-changelog.py derives every entry from git: it walks commits touching
spaces/newos4, stamps each with the LATEST_VER that was live at that commit, and groups
them into builds. Kinds map onto the page's own vocabulary (feat->release, fix->fix,
test->review, docs->docs, chore/style/refactor->project), and a build's chip is its
dominant kind. Commits whose prefix carries `backticks` render as <code>, escaped first.
- The page is its own template: everything visible comes from the #changelog-data JSON
island, so regeneration swaps the island and refreshes the two prose blocks that
described the VFS-only source. No second copy of the CSS or the 296-line renderer.
- Every unshowable thing is stated, not smoothed: commits before the first version stamp
become one "before v4.6.10" bucket, build numbers that were bumped twice before a commit
are called out as absent, and the page says entries summarise subjects, not diffs.
- CHANGELOG.md is generated from the same data between markers (app-scoped; the root
CHANGELOG.md documents the platform's 0.2.x line and is left alone).
- newos4-maintain.py gains check_changelog(): FAIL when the page's build differs from
LATEST_VER, regenerate under --fix, PASS when current. So the daily 07:15 job keeps the
docs in step with the build instead of relying on someone remembering.
Verification:
- build: 68 entries, 158 commits, v4.6.10 - v4.6.119, page 63 327 bytes, CHANGELOG.md 15 840.
- live page renders 68 entries with kind chips, search, per-build anchors ("Copy a direct
link to v4.6.119"), "68 of 68".
- stale detection proved by bumping LATEST_VER to v4.6.120 without rebuilding:
"FAIL: changelog changelog stale: page says v4.6.119, build is v4.6.120"; --fix then
"PASS: changelog regenerated: ... v4.6.10 - v4.6.120"; version reverted, page back to 119.
- maintain: PASS node tests 20/20, PASS changelog current: v4.6.119 (68 entries), result OK.
- mobile: verify-mobile.py at 360/390 px, light+dark -> ALL VIEWPORTS OK, 0 overflow.
Diffstat (limited to 'scripts/newos4-maintain.py')
| -rw-r--r-- | scripts/newos4-maintain.py | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/scripts/newos4-maintain.py b/scripts/newos4-maintain.py index c28fb8b..8cc7c5a 100644 --- a/scripts/newos4-maintain.py +++ b/scripts/newos4-maintain.py @@ -119,6 +119,33 @@ def check_course(): r = run([sys.executable, 'scripts/course-validate.py'], cwd=ROOT) add('PASS' if r.returncode == 0 else 'FAIL', 'course ' + ('valid' if r.returncode == 0 else 'INVALID: ' + r.stdout[-160:])) +def check_changelog(): + """The changelog page must describe the build that is actually running. + + docs/changelog.html was hand-built from VFS notes and had stopped at v4.6.101 while + the app was on v4.6.119 -- a docs page that lags the release is worse than no page, + because it reads as current. build-changelog.py derives every entry from git, so the + only thing left to check is whether it has been run since the last version bump. + """ + script = os.path.join(ROOT, 'scripts/build-changelog.py') + if not os.path.exists(script): + add('FAIL', 'changelog: scripts/build-changelog.py missing') + return + r = run([sys.executable, script, '--check'], cwd=ROOT) + if r.returncode == 0: + add('PASS', 'changelog: ' + (r.stdout.strip() or 'current')) + return + stale = (r.stdout or r.stderr).strip().splitlines() + stale = stale[-1][:150] if stale else 'stale' + if FIX: + r2 = run([sys.executable, script], cwd=ROOT) + if r2.returncode == 0: + add('PASS', 'changelog regenerated: ' + (r2.stdout.strip()[:130] or 'ok')) + return + add('FAIL', 'changelog regen failed: ' + (r2.stderr.strip()[:150] or '?')) + return + add('FAIL', 'changelog ' + stale) + def check_help_coverage(): """Every command the code registers must appear in help.html (2026-10-22). @@ -188,7 +215,7 @@ def check_links(): def main(): os.chdir(ROOT) bad = syntax_failures() # computed once, gates the bundle rebuild - check_versions(); check_syntax(bad); check_regression_tests(); check_bundles(bad); check_perms(); check_index(); check_data(); check_live(); check_atlas(); check_course(); check_help_coverage(); check_links() + check_versions(); check_syntax(bad); check_regression_tests(); check_bundles(bad); check_perms(); check_index(); check_data(); check_live(); check_atlas(); check_course(); check_help_coverage(); check_links(); check_changelog() fails = [m for l, m in issues if l == 'FAIL'] print('newOS4 maintenance — ' + datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%MZ') + (' [fix]' if FIX else '') + (' [deep]' if DEEP else '')) for l, m in issues: print(f'{l}: {m}') |