Skip to content

Upload playground standalone emitters#10225

Draft
timotheeguerin wants to merge 24 commits intomicrosoft:mainfrom
timotheeguerin:standalone-emitter-upload-playground
Draft

Upload playground standalone emitters#10225
timotheeguerin wants to merge 24 commits intomicrosoft:mainfrom
timotheeguerin:standalone-emitter-upload-playground

Conversation

@timotheeguerin
Copy link
Copy Markdown
Member

No description provided.

@microsoft-github-policy-service microsoft-github-policy-service bot added meta:website TypeSpec.io updates emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp emitter:client:python Issue for the Python client emitter: @typespec/http-client-python eng labels Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

❌ There is undocummented changes. Run chronus add to add a changeset or click here.

The following packages have changes but are not documented.

  • @typespec/http-client-python
Show changes

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 31, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@10225
npm i https://pkg.pr.new/@typespec/http-client-python@10225

commit: 7909ea4

@azure-sdk
Copy link
Copy Markdown
Collaborator

azure-sdk commented Mar 31, 2026

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

timotheeguerin and others added 3 commits April 1, 2026 11:21
Pipeline PackagePath values start with '/' (e.g. '/packages/http-client-csharp')
which causes path.resolve() to treat it as an absolute path, ignoring repoRoot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

The upload step fails because the emitter dist/ doesn't exist when createTypeSpecBundle runs. The pipeline installs and builds bundle-uploader but not the emitter itself.

The fix: add emitter build steps before the bundle upload. For http-client-csharp, add these steps before the pnpm install for bundle-uploader:

    - script: npm ci
      displayName: Install emitter dependencies
      workingDirectory: $(Build.SourcesDirectory)/${{ parameters.PackagePath }}
    - script: npm run build:emitter
      displayName: Build emitter
      workingDirectory: $(Build.SourcesDirectory)/${{ parameters.PackagePath }}

The emitter packages (http-client-csharp, http-client-python) are outside the pnpm workspace, so pnpm build doesn't cover them — they need their own npm ci + build step.

The emitter packages (http-client-csharp, http-client-python) are
outside the pnpm workspace, so pnpm build doesn't cover them.
Add npm ci + npm run build:emitter steps before bundling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

I pushed the fix to JoshLove-msft/typespec branch fix/emitter-upload-build (based on your branch).

The change adds npm ci + npm run build:emitter steps before the bundle upload. The emitter packages are outside the pnpm workspace so they need their own build step.

Diff: JoshLove-msft@2814ed0fc

JoshLove-msft and others added 4 commits April 2, 2026 14:20
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Browser-compatible emitter (dynamic imports), playground-server-url
option, .NET playground server, and serialization optimization.

From PR microsoft#10189.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The publish stage doesn't have the .NET SDK installed. Only the
TypeScript emitter build is needed for the playground bundle.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Python uses 'build' (default), C# uses 'build:emitter' to skip
the .NET generator build which requires the .NET SDK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

The published emitter bundle (1.0.0) doesn't have the browser-compatible changes from PR #10189. It still has static import { fileURLToPath } from "url" which the bundler polyfills with a shim that references Deno.

PR #10189 makes these imports dynamic so the emitter module loads in the browser. That PR needs to merge before this upload pipeline produces a working bundle.

The error path: fileURLToPath is called because the emitter goes directly to runLocalGenerator (the Node.js code path) — the browser detection and generateViaPlaygroundServer code path doesn't exist in the published version.

JoshLove-msft and others added 8 commits April 3, 2026 09:54
The url module polyfill references Deno which crashes in browser.
Set fs, url, and child_process to empty shims since emitter code
that uses them is behind runtime guards and never executes in the
browser. Keep path polyfilled since it's commonly used in
browser-safe code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the package.json browser field to swap the Node.js emit-generate
module with a browser stub that calls the playground server via fetch.
This follows the same pattern as alloy-framework/alloy#376.

- emit-generate.ts: Node.js implementation (uses fs, child_process, url)
- emit-generate.browser.ts: browser stub (uses fetch to call server)
- emitter.ts: clean of all Node.js imports, delegates to generate()
- package.json: browser field maps the module swap

The bundler respects the browser field and swaps the import at build
time, so no Node.js polyfills are needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update  tests to verify generate() is called with correct
options instead of execCSharpGenerator (which moved to emit-generate.ts).
Re-export _validateDotNetSdk from emitter.ts for test compatibility.
Mock emit-generate.js with importOriginal to preserve _validateDotNetSdk.

All 195 emitter tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The code model was being serialized with plain JSON.stringify, losing
the reference tracking (/) and usage flag transformations that
the .NET generator requires. Use serializeCodeModel() from
code-model-writer which applies buildJson() and transformJSONProperties.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The browser bundle can't resolve this export since
emit-generate.browser.ts doesn't export it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move _validateDotNetSdk tests to validate-dotnet-sdk.test.ts to avoid
vitest module mock conflicts between  tests (which mock
emit-generate.js) and _validateDotNetSdk tests (which need the real
emit-generate.js).

All 195 emitter tests pass across 24 test files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

The published bundle is still the old version. The upload script reads the version from package.json (1.0.0) and the uploader skips if a manifest for that version already exists.

The npm publish step bumps the version with a prerelease suffix (e.g. 1.0.0-alpha.20260403.1), but the bundle upload runs before the version bump. Either:

  1. Move the bundle upload step after the version bump step, or
  2. Have the upload script apply the same prerelease suffix before uploading

This is why the playground still shows the Deno error — it's loading the stale 1.0.0 bundle from before the browser override changes.

JoshLove-msft and others added 5 commits April 3, 2026 16:11
Extract the version from the published tgz in build artifacts and
update package.json before building and uploading the playground
bundle. This ensures each publish produces a unique bundle version
so the uploader doesn't skip it as already-exists.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add pipeline parameters for Docker-based playground server deployment.
After uploading the emitter bundle, builds the Docker image via
az acr build and updates the Azure Container App.

The C# publish pipeline is configured with placeholder resource names
that need to be updated once the Azure resources are provisioned.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Hardcode registry and resource group ('typespec') in the pipeline step
since they're infrastructure constants. Only the app name is
per-emitter config.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Instead of defaulting to http://localhost:5174 (which triggers OS
permission prompts), throw a clear error if no server URL is
configured. The server URL must be set via
globalThis.__TYPESPEC_PLAYGROUND_SERVER_URL__.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Configure __TYPESPEC_PLAYGROUND_SERVER_URL__ in the website playground
component so the C# emitter's browser stub knows where to send
generation requests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp emitter:client:python Issue for the Python client emitter: @typespec/http-client-python eng meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants