Repository navigation
PackAsTool: Copilot CLI binary not included in NuGet tool package (cross-platform) #2067
Description
Activity
github-actions commented
on Jul 23, 2026 on Jul 23, 2026 – with GitHub ActionsContributorMore actionsInvestigation
I investigated this issue by examining the .NET SDK build targets at
dotnet/src/build/GitHub.Copilot.SDK.targets.What the code does
The
_RegisterCopilotCliForCopytarget (line 146–163) registers the Copilot CLI binary as aContentWithTargetPathitem withCopyToOutputDirectory="PreserveNewest". This works correctly for regulardotnet buildanddotnet publishscenarios — the binary is copied tobin/runtimes/{rid}/native/at build time.The bug
However,
ContentWithTargetPathitems are not included in the.nupkgtool layout whenPackAsTool=true. The NuGet pack process for dotnet tools only packages the build output, notContentWithTargetPathitems that are dynamically injected via a.targetsfile in the consuming project. The CLI binary ends up in the build output directory but is never written into the.nupkg, so when the tool is installed on another machine (especially a different OS/RID) the binary is simply absent.A secondary issue noted by the reporter is also real: the build targets download only the CLI binary for the current build host RID — even if
RuntimeIdentifierslists multiple RIDs. Cross-platform tool packaging (e.g., building on Linux for a tool that should run on Windows) is therefore not supported by the current design.Root cause
The SDK was designed to download and copy the CLI binary at build time into the output directory. This approach works for applications but breaks for dotnet tool packages (
PackAsTool=true) and cross-platform publishing scenarios, because:ContentWithTargetPath/CopyToOutputDirectoryitems are not included in the NuGet tool package layout.- Only the host-platform binary is downloaded, so multi-RID cross-compilation is not supported.
Classification
This is a bug. The SDK does not document any limitation around
PackAsTool, and the current implementation silently produces a broken tool package. The fix would require either shipping the CLI binaries as properruntimes/{rid}/native/NuGet package assets (as the reporter suggests, similar tolibgit2sharp/SkiaSharp), or adding explicit support for thePackAsToolpath in the build targets.Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
awmgmcpg
To allow these domains, add them to the
network.allowedlist in your workflow frontmatter:network: allowed: - defaults - "awmgmcpg"
See Network Configuration for more information.
Generated by Bug Handler for #2067 · 19.8 AIC · ⌖ 5 AIC · ⊞ 4.5K · ◷
Root cause is narrower than the runtime-asset redesign suggested above: tool packages are built from the publish layout, but the SDK registered its CLI runtime assets only for build output, so packing without a rebuild dropped them. #2557 registers the same assets for publish as well. Verified end to end with a locally built SDK consumed by an external
PackAsToolproject outside the repo — unpatchedmainproduced a package with zeroruntimes/*/nativeentries and the installed tool crashed withCopilot runtime wrapper not found, while the patched build packaged 67 native entries and the installed tool started the real CLI and completed an RPC call.pack -r <rid>and multi-RID packing already worked before the change, so the gap is specific to packing without rebuilding.— kondv's Copilot 🤖
Description
When packaging a .NET application as a dotnet tool (
PackAsTool=true) that depends onGitHub.Copilot.SDK, the native Copilot CLI binary is not included in the.nupkgtool layout. At runtime, the tool fails with:Root Cause
The SDK's build targets use
ContentWithTargetPathwithCopyToOutputDirectoryto copy the CLI binary tobin/runtimes/{rid}/native/. However,PackAsTooldoes not includeContentWithTargetPathitems in the tool package layout. The binary ends up in the build output but not in the.nupkg.Additionally, when building on a Linux CI agent, the SDK downloads only the Linux binary. Even with
RuntimeIdentifiers=win-x64;linux-x64, the per-RID builds download the correct platform binary, but it still doesn't make it into the tool package.Steps to Reproduce
PackAsTool=trueandGitHub.Copilot.SDKreferencedotnet packon a Linux agentdotnet tool installordotnet dpxExpected Behavior
The Copilot CLI binaries for all target RIDs should be included in the NuGet tool package, similar to how packages like
libgit2sharpandSkiaSharpship native binaries underruntimes/{rid}/native/in the package itself.Suggested Fix
Ship the Copilot CLI binaries as proper
runtimes/{rid}/native/assets in theGitHub.Copilot.SDKNuGet package (all supported platforms), instead of downloading them at build time. This would makePackAsTool,PublishSingleFile, and cross-platform CI packaging all work correctly.Environment