Skip to content

fix(ci): assert McpServer packageType + embedded .mcp/server.json in packed nupkg#996

Merged
darylmcd merged 3 commits into
mainfrom
fix/publish-nuget-verify-package-types
Jun 20, 2026
Merged

fix(ci): assert McpServer packageType + embedded .mcp/server.json in packed nupkg#996
darylmcd merged 3 commits into
mainfrom
fix/publish-nuget-verify-package-types

Conversation

@darylmcd

Copy link
Copy Markdown
Owner

Closes backlog row publish-nuget-verify-package-types (Medium, top-n-remediation).

Problem

publish-nuget.yml's "Verify package contents" step only size-checked the .nupkg. A csproj regression dropping <PackageType>McpServer</PackageType> or the .mcp/server.json <None Include> embed would ship a tool-only package on green CI — silently delisting from the NuGet MCP gallery. eng/verify-version-drift.ps1 guards the manifest version but not its presence/type in the package.

Fix

Extend the verify step (additive) to open the .nupkg as a ZIP and assert:

  1. the nuspec contains <packageType name="McpServer" />, and
  2. an entry .mcp/server.json exists.

throw (fail the run) on either miss. ZipArchive disposed in try/finally; the nuspec StreamReader reads inside its own try/finally.

Validation

publish-nuget.yml only runs on release/dispatch, so the PR's CI does not exercise it — proven locally instead:

  • Pass path: built + packed the host project (Darylmcd.RoslynMcp.2.3.5.nupkg); assertions found <packageType name="McpServer" /> (verbatim packed shape) + the .mcp/server.json entry → exit 0.
  • Fail paths (acceptance Production readiness: thread safety, lifecycle, new tools #2): temporarily dropped each csproj line → re-packed → each assertion threw red (missing <packageType name=McpServer> / missing .mcp/server.json embed); csproj reverted afterward (unmodified in this diff).

Scope: 1 workflow file (size S). Spec-compliance PASS; code-quality PASS (low disposal nit fixed in-PR).

darylmcd and others added 3 commits June 19, 2026 22:17
…packed nupkg

The "Verify package contents" step only size-checked the .nupkg, so a csproj
regression dropping <PackageType>McpServer</PackageType> or the .mcp/server.json
embed would still pass on green CI and ship a tool-only package — silently
delisting the package from the NuGet MCP gallery.

Unzip the packed .nupkg (it is a ZIP), read the embedded .nuspec, and fail
closed unless it contains <packageType name="McpServer" /> AND the archive
holds a .mcp/server.json entry. The archive handle is disposed in a finally.
Additive to the existing size-check; the workflow is otherwise unchanged.

Verified locally (publish-nuget.yml does not run on PRs): a clean build+pack
passes both assertions; deleting either csproj line and re-packing makes the
step throw (red), then reverted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Code-quality review nit: the StreamReader on the nuspec entry used a bare
Dispose() outside try/finally — a throw from ReadToEnd() would leak it (bounded
by CI process exit, but tighten it). Wrap the read in try/finally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…fragment

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@darylmcd darylmcd merged commit 87c16ef into main Jun 20, 2026
5 checks passed
@darylmcd darylmcd deleted the fix/publish-nuget-verify-package-types branch June 20, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant