feat: enable C# emitter in playground with backend server#10346
feat: enable C# emitter in playground with backend server#10346JoshLove-msft wants to merge 20 commits intomicrosoft:mainfrom
Conversation
- Split emitter into emit-generate.ts (Node.js) and emit-generate.browser.ts (browser stub) - Browser stub POSTs code model to playground server for generation - Created .NET playground server (ASP.NET Core) that runs the generator - Added Dockerfile for containerized deployment - Pipeline: ACR build + App Service deployment with managed identity - Bundle upload to blob storage for browser-side emitter loading - Website: added C# to playground with server URL configuration - Fix: explicit ValueExpression conversion in spread expressions to prevent SIGSEGV when ParameterProvider is spread into ValueExpression collections Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ployment Only add new parameters (PlaygroundBundleBuildScript, PlaygroundServerDockerfile, PlaygroundServerAppName) and server deployment section. No changes to existing publish/ESRP pipeline logic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
commit: |
|
No changes needing a change description found. |
|
Will have a follow up PR for some UX enhancements to show a compiling spinner and change highlighting. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
You can try these changes here
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Simplify pipeline: remove Azure resource creation (ACR, plan, webapp, identity) since resources already exist manually; keep only ACR build and App Service container update - Move server URL default into browser stub so website doesn't need to set globalThis.__TYPESPEC_PLAYGROUND_SERVER_URL__ - Add --no-restore to Dockerfile publish step (restore already done) - Add **/artifacts/ to .dockerignore - Add azure.github.io to CORS allowed origins Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Test default and custom server URL - Test request body contains codeModel, configuration, generatorName - Test response files are written to host - Test error handling on non-OK response - Test empty files array Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
markcowl
left a comment
There was a problem hiding this comment.
I think we should be able to test changes using the typespec - PR Tools ci checks, so should update that workflow to ensure proper setup
Remove default server URL from browser stub to prevent it from leaking to third-party sites. The URL must be explicitly set via globalThis.__TYPESPEC_PLAYGROUND_SERVER_URL__ by the host site. Moved the URL configuration back to the website playground. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The server URL is hardcoded in the browser stub with no globalThis fallback. No configuration needed from the website. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Yes, that would capture the website changes, but the emitter changes would need to be published via the emitter pipeline. |
The publish stage didn't set a Node version, defaulting to Node 20 on the agent. The bundle-uploader depends on asset-emitter which requires Node >=22. Added NodeTool@0 step before the bundle upload. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The publish stage checks out fresh source with the original package.json version (e.g. 0.1.0). The bundle uploader reads this version for latest.json. Added a step to apply the build number (e.g. 0.1.0-beta.12345) before bundling, matching Build-Packages.ps1 behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ADO template parser was failing on the inline script. Use the auto-set BUILD_BUILDNUMBER environment variable instead of the macro syntax. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
C# emitter sets BuildPrereleaseVersion=true so gets -alpha tag, matching Build-Packages.ps1 behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
is there any emitter option that allow users to run a post emitting script that would allow a playground user to basically run code on the server?
There was a problem hiding this comment.
No, the closest thing is there an option to configure a plugin but the plugin would need to exist on the server.
Server-side (Program.cs):
- Request size limit: 10 MB max body via Kestrel
- Content-Type validation: must be application/json
- JSON parse error handling: returns 400 on invalid JSON
- Subprocess timeout: 5 minutes, kills process tree on timeout (504)
- Security headers: X-Content-Type-Options, X-Frame-Options,
Referrer-Policy
Client-side (emit-generate.browser.ts):
- Validate response content-type is application/json
- Validate response shape: { files: Array<{ path, content }> }
- Validate each file entry has string path and content
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
c36f99a to
5cb4659
Compare
Mock responses now include Headers with content-type to match the response validation added in the browser stub. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| } | ||
|
|
||
| const result: { files: Array<{ path: string; content: string }> } = await response.json(); | ||
| const contentType = response.headers.get("content-type"); |
There was a problem hiding this comment.
I'm wondering about a limit on response size? content-length is not a great way to police this, but not sure what size quotas are available to use
There was a problem hiding this comment.
Added a Content-Length check against a 10 MB limit before parsing the response JSON. As you noted, Content-Length isn't always reliable, but it provides a reasonable guard against obviously oversized responses without buffering the entire body.
-- Generated by Copilot
Checks Content-Length header against a 10 MB limit before parsing the response JSON to protect against unexpectedly large responses. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes #10228