You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -43,6 +43,46 @@ published as prereleases with the Windows `.exe` attached. Both build workflows
share one publication concurrency group, and retrying a build or publication
repairs the release for that commit rather than allocating another version.
+After the EXE upload and release publication succeed, the same job announces the
+release in Discussions → **Change Log** (category slug `change-log`). Each post
+includes direct EXE download links, a brief plain-text overview from the merged
+PR title, and changed file names with addition/deletion counts and expandable
+diff previews. File links open a comparison of the PR's recorded base commit and
+release merge commit; the post also links the full file list and downloadable
+patch. Announcements contain no PR links. Binary files or diffs omitted by GitHub have
+links instead of previews. Large posts limit previews and direct readers to the
+complete file list to stay within GitHub's size limit. GitHub's PR-files API
+returns at most 3,000 files; the full diff and patch links remain available.
+
+To associate the correct documentation update, add a line to the engine PR
+description pointing to the affected **published page**,
@@ -1,14 +1,35 @@
"""Publish an already-built installer; never execute downloaded artifacts."""
+import hashlib
+import html
import json
import os
from pathlib import Path
import re
import subprocess
import tempfile
+from urllib.parse import quote
VERSION = re.compile(r"v(\d+)\.(\d)-pre-alpha", re.IGNORECASE)
+DOCS_ROOT = "https://rustic-game-engine.pages.dev/docs/"
+
+
+def documentation_links(pr):
+ """Require an explicit mapping to published pages, never infer a docs PR."""
+ entries = re.findall(r"^Documentation:[ \t]*(.+)$", pr.get("body") or "", re.MULTILINE)
+ if not entries:
+ raise ValueError("Add Documentation: <published docs URL> to the merged PR description "
+ "(or Documentation: none for changes without a documentation update).")
+ if len(entries) == 1 and entries[0].strip().lower() == "none":
+ return []
+ urls = []
+ for entry in entries:
+ found = re.findall(re.escape(DOCS_ROOT) + r"[A-Za-z0-9_./%~-]+(?:#[A-Za-z0-9_.%~-]+)?", entry)
+ if not found:
+ raise ValueError("Documentation must link to a published page under " + DOCS_ROOT)
+ urls.extend(found)
+ return
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Announce installer releases in Change Log discussions
Download RusticGameEngine-Setup-0.1.0-x64-20261028-235258.exe
Release · All changed files and full diff · Download patch
Files changed
.github/CI.md— modified, +40 / -0Diff preview
See the file link for the complete diff.
.github/scripts/installer_release.py— modified, +133 / -0Diff preview
@@ -1,14 +1,35 @@ """Publish an already-built installer; never execute downloaded artifacts.""" +import hashlib +import html import json import os from pathlib import Path import re import subprocess import tempfile +from urllib.parse import quote VERSION = re.compile(r"v(\d+)\.(\d)-pre-alpha", re.IGNORECASE) +DOCS_ROOT = "https://rustic-game-engine.pages.dev/docs/" + + +def documentation_links(pr): + """Require an explicit mapping to published pages, never infer a docs PR.""" + entries = re.findall(r"^Documentation:[ \t]*(.+)$", pr.get("body") or "", re.MULTILINE) + if not entries: + raise ValueError("Add Documentation: <published docs URL> to the merged PR description " + "(or Documentation: none for changes without a documentation update).") + if len(entries) == 1 and entries[0].strip().lower() == "none": + return [] + urls = [] + for entry in entries: + found = re.findall(re.escape(DOCS_ROOT) + r"[A-Za-z0-9_./%~-]+(?:#[A-Za-z0-9_.%~-]+)?", entry) + if not found: + raise ValueError("Documentation must link to a published page under " + DOCS_ROOT) + urls.extend(found) + returnSee the file link for the complete diff.
.github/tests/test_installer_release.py— modified, +169 / -2Diff preview
@@ -57,8 +57,12 @@ def gh(*args): with patch.object(release, "api_list", side_effect=[ [self.pr] if pulls is None else pulls, list(releases) - ]), patch.object(release, "gh", side_effect=gh): + ]), patch.object(release, "gh", side_effect=gh), \ + patch.object(release, "announce") as announce: release.publish(REPOSITORY, self.run, self.temp.name) + announce.assert_called_once_with( + REPOSITORY, calls[0][2], self.pr, [self.installer] + ) return calls def test_new_release_uses_exact_pr_body_commit_and_installer(self): @@ -89,11 +93,13 @@ def test_retry_reuses_release_and_repairs_assets(self): def test_upload_failure_leaves_draft_unpublished(self): with patch.object(release, "api_list", side_effect=[[self.pr], []]), \ - patch.object(release, "gh", side_effect=["", RuntimeError("upload failed")]) as gh: + patch.object(release, "gh", side_effect=["", RuntimeError("upload failed")]) as gh, \ + patch.object(release, "announce") as announce: with self.assertRaisesRegex(RuntimeError, "upload failed"):See the file link for the complete diff.
.github/workflows/installer-release.yml— modified, +1 / -0Diff preview
See the file link for the complete diff.
All reactions