Skip to content

feat: add UseTypeSpecNext support for C# emitter pipeline#10370

Open
JoshLove-msft wants to merge 10 commits intomicrosoft:mainfrom
JoshLove-msft:feat/typespec-next-pipeline
Open

feat: add UseTypeSpecNext support for C# emitter pipeline#10370
JoshLove-msft wants to merge 10 commits intomicrosoft:mainfrom
JoshLove-msft:feat/typespec-next-pipeline

Conversation

@JoshLove-msft
Copy link
Copy Markdown
Contributor

@JoshLove-msft JoshLove-msft commented Apr 14, 2026

Summary

Adds the ability to run the C# emitter pipeline against TypeSpec @next versions, enabling validation of upcoming TypeSpec changes before they are released.

Changes

Common pipeline template (�ng/emitters/pipelines/templates/steps/build-step.yml)

  • Added a conditional script step that runs
    px @azure-tools/typespec-bump-deps@latest --use-peer-ranges package.json when UseTypeSpecNext is rue
  • This step is shared by all emitters, so any emitter can opt in to TypeSpec-next testing by setting the flag

C# publish pipeline (packages/http-client-csharp/eng/pipeline/publish.yml)

  • Added UseTypeSpecNext pipeline parameter (boolean, default alse) so operators can toggle it when manually queuing the pipeline
  • Wired the parameter through to �mitter-stages.yml (previously hardcoded to alse)

C# Initialize-Repository.ps1

  • Implemented the UseTypeSpecNext branch (was a TODO stub) to use
    pm install instead of
    pm ci, since the lockfile will be stale after dependency bumping

How it works

  1. When UseTypeSpecNext is rue, the common �uild-step.yml template runs @azure-tools/typespec-bump-deps to update all TypeSpec dependencies in package.json to their latest @next versions
  2. The --use-peer-ranges flag ensures peerDependencies use compatible semver ranges (not exact pinned versions), so the published emitter can be consumed by downstream repos like azure-sdk-for-net
  3. The emitter's Initialize-Repository.ps1 then runs
    pm install (instead of
    pm ci) since the lockfile no longer matches the bumped package.json
  4. The rest of the build/test/publish pipeline proceeds as normal

Usage

In the Azure DevOps publish pipeline, toggle "Use TypeSpec Next" when manually queuing a build. The published emitter package will use TypeSpec @next dependencies and can be used to regenerate azure-sdk-for-net.

Other emitters (Java, Python) can adopt the same pattern by implementing the UseTypeSpecNext branch in their Initialize-Repository.ps1 scripts — the common pipeline step already handles the dep bumping.

Add a common reusable script (eng/emitters/scripts/Update-TypeSpecNext.ps1)
that uses @azure-tools/typespec-bump-deps to update TypeSpec dependencies
to their @next versions. The script only mutates package manifests and can
be adopted by any emitter.

Implement the UseTypeSpecNext branch in the C# Initialize-Repository.ps1
and expose the flag as a pipeline parameter in the C# publish pipeline so
operators can toggle it on manual runs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
JoshLove-msft and others added 4 commits April 14, 2026 10:06
Move the npx @azure-tools/typespec-bump-deps invocation from the
PowerShell wrapper script into build-step.yml as a conditional pipeline
step. This gives better visibility in the Azure DevOps UI, makes the
step truly common across all emitters, and matches the Python approach.

- Add conditional step in build-step.yml to run typespec-bump-deps
- Remove eng/emitters/scripts/Update-TypeSpecNext.ps1
- Simplify C# Initialize-Repository.ps1 to only handle npm install

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When typespec-bump-deps updates dependencies to @next versions, transitive
peer dependency constraints may not yet be satisfied (e.g. azure-core@next
still declares peerDep on compiler@^1.11.0 while compiler@1.12.0-dev is
installed). Use --legacy-peer-deps to skip strict peer dep resolution,
matching the behavior of pnpm --no-frozen-lockfile used by Python.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With @next versions, transitive peer dependency mismatches are expected
(e.g. azure-core@next may still declare peer on compiler@^1.11.0 while
compiler@1.12.0-dev is installed). Use -IgnoreExitCode on npm ls to
prevent the pipeline from failing on these expected warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Invoke-LoggedCommand -IgnoreExitCode suppresses the error message but
does not reset $LASTEXITCODE. PowerShell then exits with code 1,
causing the ADO task to fail. Explicitly reset to 0 after the call.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 14, 2026

Open in StackBlitz

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

commit: ab00cab

@github-actions
Copy link
Copy Markdown
Contributor

No changes needing a change description found.

JoshLove-msft and others added 5 commits April 14, 2026 11:27
The tsp-client generate-config-files command runs npm install internally,
which fails on peer dep conflicts with @next versions. Set npm config
legacy-peer-deps=true before the CreateAzureSdkForNetPR stage when
UseTypeSpecNext is enabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Submit-AzureSdkForNetPr.ps1 script sets NPM_CONFIG_USERCONFIG to a
custom .npmrc for registry auth, which overrides the user-level .npmrc
where 'npm config set' writes. Use the npm_config_legacy_peer_deps
environment variable instead, which takes precedence over all .npmrc
files and is inherited by child processes (tsp-client's internal npm
install).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
--legacy-peer-deps skips installing conflicting peer deps entirely,
causing packages like @typespec/streams and @typespec/events to be
missing at runtime. --force installs all packages including peer deps
but ignores version conflicts.

Also set TSPCLIENT_FORCE_INSTALL=true for tsp-client's internal npm
install (tsp-client already supports this env var natively).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The test stage calls Initialize-Repository.ps1 with -BuildArtifactsPath
which uses npm ci (strict peer dep enforcement). When UseTypeSpecNext is
true, npm ci needs --force to handle peer dep conflicts in @next packages.

Thread UseTypeSpecNext through emitter-stages.yml -> test-job.yml ->
test-step.yml -> Initialize-Repository.ps1 so the test leg uses
npm ci --force when needed.

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 eng

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants