Files
workinf_Blender_Wasm/tools/web/build-desktop-workflow-runtime.py
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

69 lines
3.4 KiB
Python

#!/usr/bin/env python3
"""Produce the changed WASM and web bundle without running acceptance commands."""
import argparse
import datetime
import hashlib
import json
import os
from pathlib import Path
import subprocess
ROOT = Path(__file__).resolve().parents[2]
def publish(destination, data):
destination.parent.mkdir(parents=True, exist_ok=True)
temporary = destination.with_name(destination.name + f'.tmp-{os.getpid()}')
temporary.write_bytes(data)
temporary.replace(destination)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--output', default='tests/golden/WBV2-P1424-001/desktop-workflow-build')
args = parser.parse_args()
output = ROOT / args.output / datetime.datetime.now(datetime.timezone.utc).strftime('%Y%m%dT%H%M%SZ')
output.mkdir(parents=True, exist_ok=False)
report = {'schemaVersion': 1, 'task': 'WBV2-P1424-001', 'status': 'BUILDING',
'validation': 'NOT_RUN', 'acceptance': 'NOT_CLAIMED', 'steps': []}
try:
commands = [
*(([('cpython', ['python3', 'tools/web/build-webengine-python.py'], ROOT)]) if not (ROOT / 'build_web_python313/build/libpython3.13.a').exists() else []),
('wasm', ['bash', '-c', 'source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine --parallel 4'], ROOT),
]
for name, command, directory in commands:
with (output / (name + '.log')).open('w') as log:
completed = subprocess.run(command, cwd=directory, stdout=log, stderr=subprocess.STDOUT)
report['steps'].append({'name': name, 'exitCode': completed.returncode})
if completed.returncode: raise RuntimeError(name + ' build failed; see ' + str(output))
build = ROOT / 'build_web_blender6/bin'
manifest_path = ROOT / 'web/app/public/wasm-module-manifest.json'
manifest = json.loads(manifest_path.read_text())
report['artifacts'] = {}
for name in ('web_engine.js', 'web_engine.wasm'):
data = (build / name).read_bytes()
digest = hashlib.sha256(data).hexdigest()
for directory in ('web/app/src/vendor/blender', 'web/app/public/vendor/blender'):
publish(ROOT / directory / name, data)
for module in manifest['modules']:
for resource in module.get('resources', {}).values():
if resource.get('url') == '/vendor/blender/' + name: resource['sha256'] = digest
report['artifacts'][name] = {'sha256': digest, 'bytes': len(data)}
publish(manifest_path, (json.dumps(manifest, indent=2) + '\n').encode())
with (output / 'web.log').open('w') as log:
completed = subprocess.run(['node', 'tools/web/incremental-web-build.mjs'], cwd=ROOT,
env=dict(os.environ, WBV2_SKIP_TYPECHECK='1'), stdout=log, stderr=subprocess.STDOUT)
report['steps'].append({'name': 'web', 'exitCode': completed.returncode})
if completed.returncode: raise RuntimeError('web build failed; see ' + str(output))
report['status'] = 'BUILT_UNVERIFIED'
except BaseException as error:
report.update(status='BUILD_INCOMPLETE', error=str(error))
raise
finally:
publish(output / 'build.json', (json.dumps(report, indent=2) + '\n').encode())
print(json.dumps({'directory': str(output), **report}), flush=True)
if __name__ == '__main__':
main()