studio: version text in the status bar, favicon
Deploy web Studio / deploy (push) Successful in 3m15s

The status bar ends with "isokit <engine version>"; the web build adds
the commit (linked on Gitea), its date as a tooltip and a "+" when built
from a tree with uncommitted changes (build_web.py writes a
<meta name="isokit-build"> from GITHUB_SHA or git). /api/meta now carries
"engine". studio/favicon.svg (isometric cube in the accent green) is
served by `isokit studio` (also on /view) and copied into the web build.
check_web.py and check_studio.py check both.
This commit is contained in:
grabowski committed 2026-10-23 17:08:48 +07:00
1 parent c1d01331ac
commit c647f39059
11 files changed
+66 -4

No files matched your search

+24 -3
View File
@@ -81,6 +81,24 @@ def demo_files():
return out
def build_info():
"""'<commit> <commit date> [dirty]' for the version text in the Studio's
status bar; GITHUB_SHA (CI) wins over git. Empty when git is missing."""
def git(*args):
r = subprocess.run(["git", *args], capture_output=True, text=True, cwd=ROOT)
return r.stdout.strip() if r.returncode == 0 else ""
try:
sha = os.environ.get("GITHUB_SHA") or git("rev-parse", "HEAD")
if not sha:
return ""
parts = [sha, git("log", "-1", "--format=%cs", sha) or "-"]
if git("status", "--porcelain", "--untracked-files=no"):
parts.append("dirty")
return " ".join(parts)
except OSError:
return ""
def replace_once(s, old, new):
n = s.count(old)
assert n == 1, f"studio/index.html: expected {old!r} once, found {n}"
@@ -116,7 +134,7 @@ def main():
print(" (wasm-opt not found: the .wasm stays unoptimised by binaryen, about 15% larger)")
for src, dst in [("viewer/isokit-view.js", "viewer"), ("viewer/isokit-view.css", "viewer"),
("studio/studio.js", "studio"), ("studio/studio.css", "studio"),
("studio/studio.js", "studio"), ("studio/studio.css", "studio"), ("studio/favicon.svg", "studio"),
("web/web.js", "web"), ("web/web.css", "web")]:
(out / "assets" / dst).mkdir(parents=True, exist_ok=True)
shutil.copy2(ROOT / src, out / "assets" / dst / Path(src).name)
@@ -129,8 +147,11 @@ def main():
v = "v=" + h.hexdigest()[:10]
html = (ROOT / "studio" / "index.html").read_text(encoding="utf-8")
build = build_info()
html = replace_once(html, '<title>isokit Studio</title>',
'<title>isokit Studio</title>\n<meta name="description" content="isokit Studio: edit isometric site plans in the browser.">')
'<title>isokit Studio</title>\n<meta name="description" content="isokit Studio: edit isometric site plans in the browser.">'
+ (f'\n<meta name="isokit-build" content="{build}">' if build else ""))
html = replace_once(html, 'href="/assets/studio/favicon.svg"', f'href="assets/studio/favicon.svg?{v}"')
html = replace_once(html, 'href="/assets/viewer/isokit-view.css"', f'href="assets/viewer/isokit-view.css?{v}"')
html = replace_once(html, '<link rel="stylesheet" href="/assets/theme.css">', '<style id="iso-theme"></style>')
html = replace_once(html, '<link rel="stylesheet" href="/assets/studio/studio.css">',
@@ -148,7 +169,7 @@ def main():
if p.is_file():
total += p.stat().st_size
print(f" {p.relative_to(out).as_posix():40} {p.stat().st_size / 1024:8.1f} kB")
print(f"{out} ({total / 1024 / 1024:.1f} MB, {v})")
print(f"{out} ({total / 1024 / 1024:.1f} MB, {v}, build {build or 'unknown'})")
if __name__ == "__main__":