From f1b3467c0f9dfeaf0dba154ff88a2f23a87a9656 Mon Sep 17 00:00:00 2001 From: Max Natthawut Adulyanukosol <13469652+na399@users.noreply.github.com> Date: Sun, 30 Aug 2026 09:14:07 +0700 Subject: [PATCH 1/2] Add GitHub Pages public web distribution Build and validate the Leptos/WASM application at the repository project path, deploy tested main-branch artifacts through GitHub Pages, and document the public-release, persistence, and certification boundaries. --- .github/workflows/pages.yml | 85 ++++++++++++ CHANGELOG.md | 7 + Cargo.toml | 2 +- MANIFEST.sha256 | 15 ++- Makefile | 12 +- README.md | 53 +++++--- crates/web-ui/index.html | 11 +- crates/web-ui/public.css | 40 ++++++ docs/adr/0011-github-pages-public-web.md | 37 ++++++ docs/runbooks/GITHUB_PAGES.md | 69 ++++++++++ scripts/validate_pages_dist.py | 157 +++++++++++++++++++++++ 11 files changed, 459 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/pages.yml create mode 100644 crates/web-ui/public.css create mode 100644 docs/adr/0011-github-pages-public-web.md create mode 100644 docs/runbooks/GITHUB_PAGES.md create mode 100644 scripts/validate_pages_dist.py diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..2548d08 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,85 @@ +name: GitHub Pages + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + name: Build static web distribution + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install content-validation dependencies + run: python -m pip install --disable-pip-version-check PyYAML jsonschema + + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown + components: rustfmt, clippy + + - name: Cache Rust build state + uses: Swatinem/rust-cache@v2 + + - name: Install pinned Trunk + run: cargo install trunk --version 0.21.14 --locked + + - name: Validate source and simulation boundary + run: | + make check + python3 scripts/static_rust_sanity.py + python3 scripts/verify_manifest.py + + - name: Set GitHub project-site base path + run: echo "PAGES_BASE_PATH=/${GITHUB_REPOSITORY#*/}/" >> "$GITHUB_ENV" + + - name: Build static Pages artifact + run: | + cargo metadata --locked --format-version 1 >/dev/null + cd crates/web-ui + trunk build --release --public-url "$PAGES_BASE_PATH" + + - name: Validate static Pages artifact + run: python3 scripts/validate_pages_dist.py crates/web-ui/dist "$PAGES_BASE_PATH" + + - name: Upload Pages artifact + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + uses: actions/upload-pages-artifact@v5 + with: + path: crates/web-ui/dist + + deploy: + name: Deploy public web distribution + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + needs: build + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 diff --git a/CHANGELOG.md b/CHANGELOG.md index e5a0ee2..2d16c58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Unreleased + +- Added GitHub Pages as the public static web distribution. +- Added a repository-path-aware Trunk build, generated-artifact validation, and deployment workflow. +- Added public independence, local-execution, and browser-storage notices. +- Documented repository setup, trust boundaries, custom-domain migration, and rollback. + ## 0.1.0-dev-pack — 2026-08-05 - Added DGX Lab PRD v1.0 and requirements traceability. diff --git a/Cargo.toml b/Cargo.toml index 28613c8..2d7484f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ version = "0.1.0" edition = "2024" license = "Apache-2.0" authors = ["DGX Lab contributors"] -repository = "https://example.invalid/dgx-lab" +repository = "https://github.com/sidataplus/DGX_Lab" rust-version = "1.88" [workspace.dependencies] diff --git a/MANIFEST.sha256 b/MANIFEST.sha256 index 6440dd6..aea946e 100644 --- a/MANIFEST.sha256 +++ b/MANIFEST.sha256 @@ -2,19 +2,20 @@ aeac9b3ef812a24f379f8516078ed9fec8e9aea30d3052bc82571f4ef14d7a00 .github/dependabot.yml 949193274bb5b66db38744ae0475a272e784682bda5dcceefbe6974f67225c5c .github/pull_request_template.md c2343e3bcbca8163fc5094fa749106ac62ab7060a6cc608e2ffd59f54b81d5ac .github/workflows/ci.yml +6262dd904a8dda5b5af20dab5382326fae71d74e25157e0f055c4d4387286a43 .github/workflows/pages.yml 02d523396c0582dc194050eeec1bdd75c39dc85f8bea0f2b69cf873ce1431394 .github/workflows/release-blueprint.yml 7c0d8206830526e398531bb684dc1878a3f5c693ce1d666bd5ca6c743c847be0 .github/workflows/security-boundary.yml c6c44e5d4675a1644e3324dc17c5795d09d5055c6a5d99577d4f28e7ed055db6 .gitignore -32b6e864cb51587c020d103b93f5c104b8a0fbc7ad9c60658c757ec9f496c272 CHANGELOG.md +f88e2b610dfad2b93d81394afa44ecd8add5d633271dfa74574b07d559b4892f CHANGELOG.md 334744126cf33bc893e29a5dec5bf491e81be97978878119b53c17e531e24cd3 CONTENT-LICENSE.md 33b25f921344c2db05aa21018320342c2a2e76d100b92400b0cef1cc9f8c3a66 CONTRIBUTING.md 8b50db4f2f2594d574fda3413fa179ac5bf493989e01cc16875e963f99e12335 Cargo.lock 583559e02128faf10af9464268132289d4e189d2b76facda9fd5d49b48ae9a2d Cargo.lock.NOT_GENERATED.md -f8c44a7fa9c8b3004b5e93a31c63db994626119c25ce40f099743c12e2a476da Cargo.toml +70b4ee55c0bc6f6c560d70c0656dbfbfdd2d74315ed01aa3a545b5329dbd2d22 Cargo.toml a033dd6ee3b1aef3ba39126b6fc2c3002c266d60698f5a9db4fc8145ca2555af LICENSE -81252f4048abbf280f8b9977c67a56942d3d3970f58573970883dc10c4e7f6a3 Makefile +8716891999fd40ac315bc565012a84e372245812ad5c319f7aa397b2f346c134 Makefile bfd07db590fab27034c1f2640fe45718781e3c7a8bf6ede74b0df5cb1dab9f03 NOTICE -5b958cd6222dadaa62d816164b9eee540b4e12a8e82d4a00c62912c9761227cc README.md +8f656fec7315c089c97566a1417631b19645b7b51c97d36805b9f08ab570aaeb README.md 3dbbdf4a5a3ba3b6de3da1f673368274ee00982b7beae5912297e5e0b06aae6c SECURITY.md eadf2458f40e72f62a6080f0e846aada57efea8fa7558b03eb3cba0fa1046947 TRADEMARKS.md 5c9c112fc83af1a2f8c196a676c8f81d1a28aab1ffe9bacd0e8265a150e2e20e VERSION @@ -98,7 +99,8 @@ ef7dda1ff1f3af1332f63bfb33f2b01389c2d74b93ce9d5c93aa34f9399ef613 crates/web-ui/ 1d9506a4155489dc2d52df2e8bc0cecd39371b9f51f0db09cc3ec110596ad95d crates/web-ui/dist/style-86b3632c245ac7f3.css 3f1840337eea92ef4e86697fb59589ce28d88df04b1c435887c5249b8ee2ad1a crates/web-ui/dist/web-ui-f961d7fae81dd101.js f8986ca86a1f7aec7a1e6c6649cae9e63264bbba4d9cf742de42687a1a3edb46 crates/web-ui/dist/web-ui-f961d7fae81dd101_bg.wasm -0161ac66f9db29b1afde173fce2490fa8da279e727584b7533bd7832b40fc27f crates/web-ui/index.html +e986746ec40461a295774409ea8bb54fd6d766708834aaaf190da9e000c4e778 crates/web-ui/index.html +24bd1baa53f6c906097dfb2c924e0204f5ed13bc9dc08dc5fd1ede87a92900ae crates/web-ui/public.css 8d074f16804980915bb73756da6de904bd3bc63916685a4e0cb597cd5b3ba7c0 crates/web-ui/src/app.rs 9277c64111bff9e1924f4444d8e8a61519b38db5b27d500b7ed8020d1306ff4b crates/web-ui/src/bridge.rs 5af2a554eeddf75943aa6c2c3208f3be3c719fb84a8c70826bea65c395042d4a crates/web-ui/src/learning.rs @@ -131,6 +133,7 @@ d0324894185571d86acc5f3ebff0b8a7a0f9cd12c6c4866816359856ef6b6efc docs/adr/0007- 6e96d816955eefc39968aaa9e0b01e98dcdcd7f8c3592adede1b1a49c3b9a638 docs/adr/0008-local-certification-trust.md 77c2a84ade2af1fa3155bc0d6077555f2238a01f460b6c078562b9d200754848 docs/adr/0009-generic-dgx-profile.md b4262ba40d4414b15f2d32350236c203b6d8ba2f65ef08cb6b056dd2b2a1c7c8 docs/adr/0010-leptos-csr-and-worker-boundary.md +e168776cc57b98954e5d5ec79db423ac3c274ee58d11593f89bf3d66bea8a81b docs/adr/0011-github-pages-public-web.md 78941fa25d4db13efe0a795f5b338a409d9f8b720569af1daca575e643dd0027 docs/adr/README.md 45c18bff9bb4f434a4f8a6bd1f98ca14aa7c101f8985b5c31d1c225e4a8e7413 docs/content/COURSE_MAP.md 3efaa66539e495e8e53a58c4a1f355403aa4b73ed81935c1fdc134bdabe6b496 docs/design/MOCKUP_INDEX.md @@ -148,6 +151,7 @@ dcc83ee211acee6853acd6b46af6bba96a7f1195872da41836a6108aed44da01 docs/reference b0beb26021d265c7d5302007e8d6223f9e2b6f5ea980077bcd10135f7714e902 docs/reference/SLURM_COMMAND_MATRIX.md 48e0334673a3788f41db112988e7aad421e1b474c2f0c7b25eafc0f2fb864790 docs/runbooks/BUILD_RELEASE.md 8bba389584e3f36f4805f7fdff27d2aa6fa737dd119504fef39bae31941abe18 docs/runbooks/CONTENT_AUTHORING.md +0b63a97dabdb2db218ea66684324d74a46002d234a2bdff885a84525c8570574 docs/runbooks/GITHUB_PAGES.md a990ecfc1d38f9f1242e9f10334aa71da1b5994ae2f79f467e3347448a566ad5 docs/runbooks/LOCAL_DEVELOPMENT.md 603ddd2430b5d6d62b47eae86672ca1a01ae2c9d739850363c6f69c4e81bbf57 docs/runbooks/SECURITY_REVIEW.md 3dc23d49b57c3ba4707aa41603f62e6f719d059bd25184098d4aeb86170d2c1c prototype/README.md @@ -178,6 +182,7 @@ a9dafa68b579d2b57bc7328a9c9c9d4ab42cd0d0b67e2b25f89766c3356f6497 scripts/genera ae68d98a2ff824e173a691e87817894c5c3fb91b20caa52c1fbeabc143a6deed scripts/run_static_checks.sh 34a6b2bcd10fc232c3f45378cbeec898ebbb4f3cc0a5d67b18ffb7e9a2e73f14 scripts/static_rust_sanity.py 4f5ca1e0af1685ea961f841d003139822d326fd73f6a0889bac1b2f213fc82e6 scripts/validate_all.py +327a088d5e952418db42517d2510649a1c99a03e2ac92097af9eea043474768e scripts/validate_pages_dist.py ab7f73ff37df0ef8c6233b87bf3bea041c266bae8bd7e3ddd9dbb97f298674ef scripts/verify_manifest.py b3d82a8e468e482bc507c6fdb90c136dcecefb5e7a81267059faa20eb1532a4d src-tauri/Cargo.toml 30e44cbd5a7e4c0378934d1f6f173b416fdcbf5ff74e54d228e2ae2dfa918913 src-tauri/README.md diff --git a/Makefile b/Makefile index 37a60f7..bcc7b3d 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,10 @@ -.PHONY: validate check test web tauri prototype clean +.PHONY: validate check test web web-release web-pages tauri prototype clean # Prefer real toolchain binaries if ~/.cargo/bin rustup proxies are broken: # export PATH="$HOME/.rustup/toolchains/stable-aarch64-apple-darwin/bin:$HOME/.cargo/bin:$PATH" PYTHON ?= python3 +PAGES_BASE ?= /DGX_Lab/ validate: $(PYTHON) scripts/validate_all.py @@ -21,6 +22,15 @@ test: web: cd crates/web-ui && trunk serve --port 1420 --address 127.0.0.1 +web-release: + cargo metadata --locked --format-version 1 >/dev/null + cd crates/web-ui && trunk build --release + +web-pages: + cargo metadata --locked --format-version 1 >/dev/null + cd crates/web-ui && trunk build --release --public-url "$(PAGES_BASE)" + $(PYTHON) scripts/validate_pages_dist.py crates/web-ui/dist "$(PAGES_BASE)" + # Desktop app: Tauri shell + Leptos CSR UI (Trunk on port 1420). tauri: cargo tauri dev diff --git a/README.md b/README.md index 72dda8a..fc8b0f7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Interactive SLURM Training Simulator** -DGX Lab is a standalone, deterministic desktop simulation environment for learning SLURM and shared GPU-computing workflows. It presents a generic DGX-scale cluster, simulated concurrent users, synthetic AI workloads, failure scenarios, guided labs, and local certification. It is deliberately incapable of connecting to a real scheduler. +DGX Lab is a standalone, deterministic simulation environment for learning SLURM and shared GPU-computing workflows. It presents a generic DGX-scale cluster, simulated concurrent users, synthetic AI workloads, failure scenarios, guided labs, and local certification. It is deliberately incapable of connecting to a real scheduler. ## Learning experience @@ -22,7 +22,7 @@ Every module follows a consistent **Learn → Practice → Assess** rhythm. Lear This repository accompanies **DGX Lab PRD v1.0** and provides: -- a Tauri 2 + Leptos/Rust/WASM application workspace; +- a Tauri 2 desktop shell and static GitHub Pages web distribution over one Leptos/Rust/WASM application; - a responsive Learn, Practice, and Assess interface; - a deterministic simulation core with constrained virtual scheduler, shell, and filesystem; - state-backed practical grading and an offline knowledge assessment; @@ -45,17 +45,30 @@ This repository accompanies **DGX Lab PRD v1.0** and provides: | Practical grading and knowledge scoring | State-backed and tested | | Scenario compiler and report renderer | Implemented | | Leptos CSR UI | Responsive release build produced | +| GitHub Pages distribution | Path-aware build and deployment workflow implemented | | WASM worker API | Native/WASM boundary verified | | Tauri 2 shell | Minimal, no real-system commands | | Native/WASM compilation evidence | Verified in the current workspace | | Cargo lockfile | Resolved and committed | | Signed installers | Deferred to a signing/notarization release lane | -The current release has native Rust test evidence, a verified WebAssembly build, strict linting, browser QA at desktop and phone widths, validated course content, 241 requirement links, and a checksum-verified course pack. The browser build remains offline and never executes learner commands on the host. +The current release has native Rust test evidence, a verified WebAssembly build, strict linting, browser QA at desktop and phone widths, validated course content, 241 requirement links, and a checksum-verified course pack. The browser build runs entirely client-side and never executes learner commands on the host. + +## Public web distribution + +The canonical web edition is built from `crates/web-ui` and deployed from `main` by `.github/workflows/pages.yml`. GitHub Pages receives a generated static artifact rather than the checked-in `dist/` reference snapshot. The workflow derives the repository project path, rebuilds the Leptos/WASM application, and rejects broken or root-hosted asset references before deployment. + +Reproduce the project-site build locally with: + +```bash +make web-pages PAGES_BASE=/DGX_Lab/ +``` + +A repository administrator must select **GitHub Actions** as the Pages source before the first production deployment. See `docs/runbooks/GITHUB_PAGES.md` for setup, trust boundaries, custom-domain migration, and rollback. ## Fastest way to inspect the product -Serve the checked-in release build locally: +Serve the checked-in reference release build locally: ```bash cd crates/web-ui/dist @@ -88,22 +101,22 @@ See `docs/runbooks/LOCAL_DEVELOPMENT.md` for OS prerequisites and the build orde ## Architectural boundary ```text -Tauri 2 desktop shell - │ - ▼ -Leptos CSR interface (WASM) - │ - ▼ -Rust simulation worker (WASM) - │ - ├── virtual scheduler - ├── virtual users - ├── virtual shell/filesystem - ├── synthetic workloads - ├── grading and assessment - └── deterministic event replay - -NO SSH · NO SHELL · NO REAL SLURM · NO EXTERNAL NETWORK +GitHub Pages static host or Tauri 2 desktop shell + │ + ▼ + Leptos CSR interface (WASM) + │ + ▼ + Rust simulation worker (WASM) + │ + ├── virtual scheduler + ├── virtual users + ├── virtual shell/filesystem + ├── synthetic workloads + ├── grading and assessment + └── deterministic event replay + +NO SSH · NO SHELL · NO REAL SLURM · NO RUNTIME EXTERNAL NETWORK ``` The default cluster profile generalizes an eight-H200, 224-logical-CPU, cgroup-isolated Slurm environment into non-institutional names and paths. Production hostnames, IP addresses, credentials, and operational paths are intentionally absent. diff --git a/crates/web-ui/index.html b/crates/web-ui/index.html index 93a97eb..9851245 100644 --- a/crates/web-ui/index.html +++ b/crates/web-ui/index.html @@ -3,10 +3,17 @@
- + + +