This repository was archived by the owner on Apr 24, 2026. It is now read-only.
chore: clean up temp files and deduplicate .gitignore #130
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy GitHub Pages Demo | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: gh-pages | |
| cancel-in-progress: true | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Download KTX-Software binary | |
| run: | | |
| mkdir -p bin | |
| KTX_URL="https://github.com/KhronosGroup/KTX-Software/releases/download/v4.3.2/KTX-Software-4.3.2-Linux-x86_64.tar.zst" | |
| curl -sL "$KTX_URL" -o ktx.tar.zst | |
| if command -v zstd >/dev/null 2>&1; then | |
| tar --use-compress-program=unzstd -xf ktx.tar.zst --wildcards '*/bin/ktx' --strip-components=2 -C bin/ 2>/dev/null || true | |
| fi | |
| if [ ! -f bin/ktx ]; then | |
| sudo apt-get install -y zstd 2>/dev/null || true | |
| tar --use-compress-program=unzstd -xf ktx.tar.zst --wildcards '*/bin/ktx' --strip-components=2 -C bin/ 2>/dev/null || true | |
| fi | |
| rm -f ktx.tar.zst | |
| chmod +x bin/ktx 2>/dev/null || true | |
| [ -f bin/ktx ] && echo "ktx binary ready: $(bin/ktx --version 2>&1 || echo unknown)" || echo "ktx binary not found, will fallback to PNG downscale" | |
| - name: Build dist | |
| run: | | |
| mkdir -p dist/src dist/apps/maps dist/apps/tps-game dist/node_modules | |
| cp -r client/* dist/ | |
| cp -r src/client dist/src/client | |
| cp -r src/protocol dist/src/protocol | |
| cp -r src/shared dist/src/shared | |
| cp -r src/sdk dist/src/sdk | |
| cp -r src/connection dist/src/connection | |
| cp -r src/debug dist/src/debug | |
| cp -r src/netcode dist/src/netcode | |
| cp -r src/physics dist/src/physics | |
| cp -r src/apps dist/src/apps | |
| cp -r src/stage dist/src/stage | |
| cp -r src/storage dist/src/storage | |
| cp -r src/transport dist/src/transport | |
| cp -r src/spatial dist/src/spatial | |
| cp src/math.js dist/src/math.js | |
| cp src/index.client.js dist/src/index.client.js | |
| cp apps/maps/aim_sillos.glb dist/apps/maps/aim_sillos.glb | |
| cp apps/tps-game/cleetus.vrm dist/apps/tps-game/cleetus.vrm | |
| # Copy all app JS sources so BrowserServer.connect() can fetch them | |
| # Also copy _lib/ since src/apps/AppContext.js imports apps/_lib/lifecycle.js | |
| find apps -name "*.js" | while read f; do | |
| mkdir -p "dist/$(dirname $f)" | |
| cp "$f" "dist/$f" | |
| done | |
| for pkg in three @pixiv/three-vrm webjsx msgpackr meshoptimizer monaco-editor jolt-physics xstate d3-octree; do | |
| if [ -d "node_modules/$pkg" ]; then | |
| mkdir -p "dist/node_modules/$pkg" | |
| cp -r "node_modules/$pkg" "dist/node_modules/$(dirname $pkg)/" | |
| fi | |
| done | |
| cp -r client/vendor dist/vendor 2>/dev/null || true | |
| cp client/draco -r dist/draco 2>/dev/null || true | |
| cp client/basis -r dist/basis 2>/dev/null || true | |
| - name: Optimize models for GPU memory | |
| run: node scripts/optimize-models.js dist/apps dist/anim-lib.glb || true | |
| - name: Patch paths for gh-pages | |
| run: | | |
| BASE="/spoint" | |
| find dist -name "*.html" -o -name "*.js" | xargs sed -i "s|href=\"/|href=\"${BASE}/|g; s|src=\"/|src=\"${BASE}/|g" 2>/dev/null || true | |
| find dist -name "*.js" -exec sed -i "s|'/src/|'${BASE}/src/|g; s|\"/src/|\"${BASE}/src/|g" {} \; 2>/dev/null || true | |
| find dist -name "*.js" -exec sed -i "s|'/node_modules/|'${BASE}/node_modules/|g; s|\"/node_modules/|\"${BASE}/node_modules/|g" {} \; 2>/dev/null || true | |
| find dist -name "*.js" -exec sed -i "s|'/draco/'|'${BASE}/draco/'|g; s|'/basis/'|'${BASE}/basis/'|g; s|'/singleplayer-world.json'|'${BASE}/singleplayer-world.json'|g; s|'/anim-lib.glb'|'${BASE}/anim-lib.glb'|g" {} \; 2>/dev/null || true | |
| sed -i 's|"/node_modules/|"/spoint/node_modules/|g; s|"/vendor/|"/spoint/vendor/|g' dist/index.html | |
| sed -i 's|href="/style.css"|href="/spoint/style.css"|g; s|src="/app.js"|src="/spoint/app.js"|g' dist/index.html | |
| - name: Add singleplayer auto-enable script to index.html | |
| run: | | |
| sed -i 's|<meta charset="UTF-8">|<meta charset="UTF-8"><script>if(!location.search.includes("singleplayer"))location.replace(location.pathname+"?singleplayer")</script>|' dist/index.html | |
| - name: Copy singleplayer world config | |
| run: | | |
| cp client/singleplayer-world.json dist/singleplayer-world.json | |
| sed -i 's|"\./apps/|"/spoint/apps/|g' dist/singleplayer-world.json | |
| - name: Patch server-side modules for browser Worker | |
| run: | | |
| # AppLoader: remove node: imports (loadFromString doesn't need them) | |
| sed -i "/^import.*from 'node:fs\/promises'/d" dist/src/apps/AppLoader.js | |
| sed -i "/^import.*from 'node:fs'/d" dist/src/apps/AppLoader.js | |
| sed -i "/^import.*from 'node:path'/d" dist/src/apps/AppLoader.js | |
| sed -i "/^import.*from 'node:url'/d" dist/src/apps/AppLoader.js | |
| # SessionStore: replace node:crypto randomBytes with Web Crypto | |
| sed -i "s|import { randomBytes } from 'node:crypto'||" dist/src/connection/SessionStore.js | |
| sed -i "s|randomBytes(16).toString('hex')|Array.from(crypto.getRandomValues(new Uint8Array(16))).map(b=>b.toString(16).padStart(2,'0')).join('')|g" dist/src/connection/SessionStore.js | |
| # AppRuntime: node: import guard already applied in source (process.versions?.node check) | |
| # GLBLoader: node:fs guard already applied in source (process.versions?.node check) | |
| # ReloadManager, StaticHandler, UploadHandler, ServerAPI, server.js are NOT imported by WorkerEntry - no patch needed | |
| # WebTransportServer: not imported by WorkerEntry | |
| # FSAdapter: not implemented by WorkerEntry (Worker uses IDBAdapter) | |
| # lifecycle.js: replace bare 'xstate' specifier with absolute path so module Workers can resolve it without importmap | |
| sed -i "s|from 'xstate'|from '/spoint/node_modules/xstate/dist/xstate.esm.js'|g" dist/apps/_lib/lifecycle.js | |
| # Octree.js: replace bare 'd3-octree' specifier with absolute path for Worker importmap bypass | |
| sed -i "s|from 'd3-octree'|from '/spoint/node_modules/d3-octree/src/index.js'|g" dist/src/spatial/Octree.js | |
| # msgpack.js: replace bare 'msgpackr' specifier with absolute path for Worker importmap bypass | |
| sed -i "s|from 'msgpackr'|from '/spoint/node_modules/msgpackr/index.js'|g" dist/src/protocol/msgpack.js | |
| # World.js: replace bare 'jolt-physics/wasm-compat' specifier with absolute path for Worker importmap bypass | |
| sed -i "s|from 'jolt-physics/wasm-compat'|from '/spoint/node_modules/jolt-physics/dist/jolt-physics.wasm-compat.js'|g" dist/src/physics/World.js | |
| - name: Deploy to gh-pages | |
| uses: peaceiris/actions-gh-pages@v4 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| publish_dir: ./dist | |
| force_orphan: true |