Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 1 addition & 31 deletions .github/workflows/main-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,37 +30,7 @@ jobs:
pip install -r requirements.txt

- name: Build static site bundle
run: |
python - <<'PY'
import json
import shutil
import time
from pathlib import Path

start = time.perf_counter()
root = Path('.')
dist = Path('dist')
if dist.exists():
shutil.rmtree(dist)
dist.mkdir(parents=True, exist_ok=True)

for asset in ['index.html', 'style.css', 'app.js', 'ai-instruct.txt']:
shutil.copy2(root / asset, dist / asset)

duration = time.perf_counter() - start
report_dir = Path('ci_reports')
report_dir.mkdir(parents=True, exist_ok=True)
(report_dir / 'build_status.json').write_text(
json.dumps(
{
'status': 'succeeded',
'artifact': 'github-pages',
'duration': duration,
},
indent=2,
)
)
PY
run: python scripts/build_static.py

- name: Upload static artifact
uses: actions/upload-pages-artifact@v3
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ Two separate GitHub Actions workflows keep deployments fast and informative:

- **Main Branch Delivery** (`.github/workflows/main-branch.yml`)
- Triggers on pushes to `main` and manual dispatches.
- Builds the static bundle, uploads the GitHub Pages artifact, and records a
machine-readable build summary.
- Runs `scripts/build_static.py`, which inlines the CSS and JavaScript so the
GitHub Pages artifact is a self-contained `index.html` (eliminating missing
asset issues on the published site).
- Uploads the bundle artifact and records a machine-readable build summary.
- Executes the same test suite and reports results without blocking deploys.
- Deploys successful builds to GitHub Pages.

Expand Down
4 changes: 4 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Unity Voice Chat</title>
<!-- build:css -->
<link rel="stylesheet" href="./style.css">
<!-- endbuild css -->
<!-- build:js -->
<script defer src="./app.js"></script>
<!-- endbuild js -->
</head>
<body>
<div id="background" aria-hidden="true"></div>
Expand Down
88 changes: 88 additions & 0 deletions scripts/build_static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""Build the GitHub Pages bundle with inlined assets."""
from __future__ import annotations

import json
import shutil
import time
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
DIST = ROOT / "dist"
CI_REPORTS = ROOT / "ci_reports"

CSS_START = "<!-- build:css -->"
CSS_END = "<!-- endbuild css -->"
JS_START = "<!-- build:js -->"
JS_END = "<!-- endbuild js -->"


def replace_block(source: str, start_marker: str, end_marker: str, replacement: str) -> str:
"""Replace the block delimited by the provided markers.

Raises a ValueError when the markers are missing so the workflow fails fast
instead of silently producing a broken bundle.
"""

try:
start_index = source.index(start_marker) + len(start_marker)
end_index = source.index(end_marker)
except ValueError as exc: # pragma: no cover - defensive guard
raise ValueError(
"Build markers missing in index.html. Ensure the start and end "
f"markers {start_marker!r} and {end_marker!r} exist."
) from exc

before = source[:start_index]
after = source[end_index:]
return f"{before}\n{replacement}\n{after}"


def build() -> None:
start = time.perf_counter()

if DIST.exists():
shutil.rmtree(DIST)
DIST.mkdir(parents=True, exist_ok=True)

index_html = (ROOT / "index.html").read_text(encoding="utf-8")
css = (ROOT / "style.css").read_text(encoding="utf-8")
javascript = (ROOT / "app.js").read_text(encoding="utf-8")

inlined_index = replace_block(
index_html,
CSS_START,
CSS_END,
f"<style>\n{css}\n</style>",
)
inlined_index = replace_block(
inlined_index,
JS_START,
JS_END,
f"<script>\n{javascript}\n</script>",
)

(DIST / "index.html").write_text(inlined_index, encoding="utf-8")

# Keep the original assets alongside the inlined bundle for local debugging
# and to avoid breaking any bookmarked resources.
shutil.copy2(ROOT / "style.css", DIST / "style.css")
shutil.copy2(ROOT / "app.js", DIST / "app.js")
shutil.copy2(ROOT / "ai-instruct.txt", DIST / "ai-instruct.txt")

duration = time.perf_counter() - start
CI_REPORTS.mkdir(parents=True, exist_ok=True)
(CI_REPORTS / "build_status.json").write_text(
json.dumps(
{
"status": "succeeded",
"artifact": "github-pages",
"duration": duration,
},
indent=2,
),
encoding="utf-8",
)


if __name__ == "__main__":
build()