Skip to content

Commit 3be98b4

Browse files
fix: fall back to portable RID for bundled CLI lookup on Linux (#424)
On Linux distros that install .NET from distribution packages (Ubuntu, Fedora, RHEL, etc.), RuntimeInformation.RuntimeIdentifier returns distro-specific RIDs like ubuntu.24.04-x64 instead of the portable linux-x64. The bundled CLI is placed under runtimes/linux-x64/native/, so the lookup fails and throws. Fix both the runtime lookup and build-time RID resolution: - Client.cs: GetBundledCliPath now falls back to the portable RID (e.g., linux-x64) when the distro-specific RID path doesn't exist. - GitHub.Copilot.SDK.targets: Always use portable RIDs derived from OS/architecture detection instead of the project's RuntimeIdentifier, which may be distro-specific. Fixes #424 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e40d57c commit 3be98b4

2 files changed

Lines changed: 47 additions & 3 deletions

File tree

dotnet/src/Client.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,42 @@ private async Task VerifyProtocolVersionAsync(Connection connection, Cancellatio
999999
var binaryName = OperatingSystem.IsWindows() ? "copilot.exe" : "copilot";
10001000
var rid = Path.GetFileName(System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier);
10011001
searchedPath = Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native", binaryName);
1002-
return File.Exists(searchedPath) ? searchedPath : null;
1002+
if (File.Exists(searchedPath))
1003+
{
1004+
return searchedPath;
1005+
}
1006+
1007+
// Fall back to portable RID (e.g., linux-x64) when distro-specific RID
1008+
// (e.g., ubuntu.24.04-x64) doesn't match the bundled path.
1009+
var portableRid = GetPortableRid();
1010+
if (portableRid != null && portableRid != rid)
1011+
{
1012+
var portablePath = Path.Combine(AppContext.BaseDirectory, "runtimes", portableRid, "native", binaryName);
1013+
if (File.Exists(portablePath))
1014+
{
1015+
return portablePath;
1016+
}
1017+
}
1018+
1019+
return null;
1020+
}
1021+
1022+
private static string? GetPortableRid()
1023+
{
1024+
string os;
1025+
if (OperatingSystem.IsWindows()) os = "win";
1026+
else if (OperatingSystem.IsLinux()) os = "linux";
1027+
else if (OperatingSystem.IsMacOS()) os = "osx";
1028+
else return null;
1029+
1030+
var arch = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture switch
1031+
{
1032+
System.Runtime.InteropServices.Architecture.X64 => "x64",
1033+
System.Runtime.InteropServices.Architecture.Arm64 => "arm64",
1034+
_ => null,
1035+
};
1036+
1037+
return arch != null ? $"{os}-{arch}" : null;
10031038
}
10041039

10051040
private static (string FileName, IEnumerable<string> Args) ResolveCliCommand(string cliPath, IEnumerable<string> args)

dotnet/src/build/GitHub.Copilot.SDK.targets

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,18 @@
33
<!-- CopilotCliVersion is imported from GitHub.Copilot.SDK.props (generated at SDK build time, packaged alongside) -->
44
<Import Project="$(MSBuildThisFileDirectory)GitHub.Copilot.SDK.props" Condition="'$(CopilotCliVersion)' == '' And Exists('$(MSBuildThisFileDirectory)GitHub.Copilot.SDK.props')" />
55

6-
<!-- Resolve RID: use explicit RuntimeIdentifier, or infer from current machine -->
6+
<!-- Resolve RID: use explicit RuntimeIdentifier (normalized to portable form) or infer from current machine.
7+
Distro-specific RIDs like ubuntu.24.04-x64 are normalized to portable RIDs like linux-x64
8+
so the bundled CLI path is consistent. -->
79
<PropertyGroup>
8-
<_CopilotRid Condition="'$(RuntimeIdentifier)' != ''">$(RuntimeIdentifier)</_CopilotRid>
10+
<!-- Normalize explicit RuntimeIdentifier to portable RID if it's distro-specific -->
11+
<_CopilotRid Condition="'$(RuntimeIdentifier)' != '' And $(RuntimeIdentifier.Contains('win')) And $(RuntimeIdentifier.EndsWith('-x64'))">win-x64</_CopilotRid>
12+
<_CopilotRid Condition="'$(_CopilotRid)' == '' And '$(RuntimeIdentifier)' != '' And $(RuntimeIdentifier.Contains('win')) And $(RuntimeIdentifier.EndsWith('-arm64'))">win-arm64</_CopilotRid>
13+
<_CopilotRid Condition="'$(_CopilotRid)' == '' And '$(RuntimeIdentifier)' != '' And $(RuntimeIdentifier.Contains('linux')) And $(RuntimeIdentifier.EndsWith('-x64'))">linux-x64</_CopilotRid>
14+
<_CopilotRid Condition="'$(_CopilotRid)' == '' And '$(RuntimeIdentifier)' != '' And $(RuntimeIdentifier.Contains('linux')) And $(RuntimeIdentifier.EndsWith('-arm64'))">linux-arm64</_CopilotRid>
15+
<_CopilotRid Condition="'$(_CopilotRid)' == '' And '$(RuntimeIdentifier)' != '' And $(RuntimeIdentifier.Contains('osx')) And $(RuntimeIdentifier.EndsWith('-x64'))">osx-x64</_CopilotRid>
16+
<_CopilotRid Condition="'$(_CopilotRid)' == '' And '$(RuntimeIdentifier)' != '' And $(RuntimeIdentifier.Contains('osx')) And $(RuntimeIdentifier.EndsWith('-arm64'))">osx-arm64</_CopilotRid>
17+
<!-- Fall back to machine detection when no RuntimeIdentifier is set -->
918
<_CopilotRid Condition="'$(_CopilotRid)' == '' And $([MSBuild]::IsOSPlatform('Windows')) And '$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'X64'">win-x64</_CopilotRid>
1019
<_CopilotRid Condition="'$(_CopilotRid)' == '' And $([MSBuild]::IsOSPlatform('Windows')) And '$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'Arm64'">win-arm64</_CopilotRid>
1120
<_CopilotRid Condition="'$(_CopilotRid)' == '' And $([MSBuild]::IsOSPlatform('Linux')) And '$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'X64'">linux-x64</_CopilotRid>

0 commit comments

Comments
 (0)