Skip to content

Commit 42ad3b2

Browse files
authored
Merge branch 'main' into dev/qmuntal/sdkpriv
2 parents 7959629 + 96c8e8d commit 42ad3b2

27 files changed

+713
-236
lines changed

.github/workflows/dotnet-sdk-tests.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
name: ".NET SDK Tests"
22

33
on:
4+
push:
5+
branches:
6+
- main
47
pull_request:
58
paths:
69
- 'dotnet/**'
710
- 'test/**'
811
- 'nodejs/package.json'
912
- '.github/workflows/dotnet-sdk-tests.yml'
10-
- '.github/actions/setup-copilot/**'
1113
- '!**/*.md'
1214
- '!**/LICENSE*'
1315
- '!**/.gitignore'
@@ -39,17 +41,16 @@ jobs:
3941
working-directory: ./dotnet
4042
steps:
4143
- uses: actions/checkout@v6.0.2
42-
- uses: ./.github/actions/setup-copilot
43-
id: setup-copilot
4444
- uses: actions/setup-dotnet@v5
4545
with:
4646
dotnet-version: "8.0.x"
4747
- uses: actions/setup-node@v6
4848
with:
49+
node-version: "24"
4950
cache: "npm"
5051
cache-dependency-path: "./nodejs/package-lock.json"
5152

52-
- name: Install Node.js dependencies (for CLI)
53+
- name: Install Node.js dependencies (for CLI version extraction)
5354
working-directory: ./nodejs
5455
run: npm ci --ignore-scripts
5556

@@ -80,5 +81,4 @@ jobs:
8081
- name: Run .NET SDK tests
8182
env:
8283
COPILOT_HMAC_KEY: ${{ secrets.COPILOT_DEVELOPER_CLI_INTEGRATION_HMAC_KEY }}
83-
COPILOT_CLI_PATH: ${{ steps.setup-copilot.outputs.cli-path }}
8484
run: dotnet test --no-build -v n

.github/workflows/go-sdk-tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: "Go SDK Tests"
22

33
on:
4+
push:
5+
branches:
6+
- main
47
pull_request:
58
paths:
69
- 'go/**'

.github/workflows/nodejs-sdk-tests.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ env:
44
HUSKY: 0
55

66
on:
7+
push:
8+
branches:
9+
- main
710
pull_request:
811
paths:
912
- 'nodejs/**'
1013
- 'test/**'
1114
- '.github/workflows/nodejs-sdk-tests.yml'
12-
- '.github/actions/setup-copilot/**'
1315
- '!**/*.md'
1416
- '!**/LICENSE*'
1517
- '!**/.gitignore'
@@ -45,9 +47,7 @@ jobs:
4547
with:
4648
cache: "npm"
4749
cache-dependency-path: "./nodejs/package-lock.json"
48-
node-version: 22
49-
- uses: ./.github/actions/setup-copilot
50-
id: setup-copilot
50+
node-version: 24
5151
- name: Install dependencies
5252
run: npm ci --ignore-scripts
5353

@@ -72,5 +72,4 @@ jobs:
7272
- name: Run Node.js SDK tests
7373
env:
7474
COPILOT_HMAC_KEY: ${{ secrets.COPILOT_DEVELOPER_CLI_INTEGRATION_HMAC_KEY }}
75-
COPILOT_CLI_PATH: ${{ steps.setup-copilot.outputs.cli-path }}
7675
run: npm test

.github/workflows/publish.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ jobs:
106106
name: nodejs-package
107107
path: nodejs/*.tgz
108108
- name: Publish to npm
109+
if: github.ref == 'refs/heads/main'
109110
run: npm publish --tag ${{ github.event.inputs.dist-tag }} --access public --registry https://registry.npmjs.org
110111

111112
publish-dotnet:
@@ -130,6 +131,7 @@ jobs:
130131
name: dotnet-package
131132
path: dotnet/artifacts/*.nupkg
132133
- name: NuGet login (OIDC)
134+
if: github.ref == 'refs/heads/main'
133135
uses: NuGet/login@v1
134136
id: nuget-login
135137
with:
@@ -139,6 +141,7 @@ jobs:
139141
# are associated with individual maintainers' accounts too.
140142
user: stevesanderson
141143
- name: Publish to NuGet
144+
if: github.ref == 'refs/heads/main'
142145
run: dotnet nuget push ./artifacts/*.nupkg --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
143146

144147
publish-python:
@@ -153,18 +156,25 @@ jobs:
153156
- uses: actions/setup-python@v6
154157
with:
155158
python-version: "3.12"
159+
- uses: actions/setup-node@v6
160+
with:
161+
node-version: "22.x"
156162
- name: Set up uv
157163
uses: astral-sh/setup-uv@v7
164+
- name: Install Node.js dependencies (for CLI version)
165+
working-directory: ./nodejs
166+
run: npm ci --ignore-scripts
158167
- name: Set version
159168
run: sed -i "s/^version = .*/version = \"${{ needs.version.outputs.version }}\"/" pyproject.toml
160-
- name: Build package
161-
run: uv build
169+
- name: Build platform wheels
170+
run: node scripts/build-wheels.mjs --output-dir dist
162171
- name: Upload artifact
163172
uses: actions/upload-artifact@v6
164173
with:
165174
name: python-package
166175
path: python/dist/*
167176
- name: Publish to PyPI
177+
if: github.ref == 'refs/heads/main'
168178
uses: pypa/gh-action-pypi-publish@release/v1
169179
with:
170180
packages-dir: python/dist/

.github/workflows/python-sdk-tests.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ env:
44
PYTHONUTF8: 1
55

66
on:
7+
push:
8+
branches:
9+
- main
710
pull_request:
811
paths:
912
- 'python/**'
1013
- 'test/**'
1114
- 'nodejs/package.json'
1215
- '.github/workflows/python-sdk-tests.yml'
13-
- '.github/actions/setup-copilot/**'
1416
- '!**/*.md'
1517
- '!**/LICENSE*'
1618
- '!**/.gitignore'
@@ -42,11 +44,14 @@ jobs:
4244
working-directory: ./python
4345
steps:
4446
- uses: actions/checkout@v6.0.2
45-
- uses: ./.github/actions/setup-copilot
46-
id: setup-copilot
4747
- uses: actions/setup-python@v6
4848
with:
4949
python-version: "3.12"
50+
- uses: actions/setup-node@v6
51+
with:
52+
node-version: "24"
53+
cache: "npm"
54+
cache-dependency-path: "./nodejs/package-lock.json"
5055

5156
- name: Set up uv
5257
uses: astral-sh/setup-uv@v7
@@ -56,6 +61,10 @@ jobs:
5661
- name: Install Python dev dependencies
5762
run: uv sync --locked --all-extras --dev
5863

64+
- name: Install Node.js dependencies (for CLI in tests)
65+
working-directory: ./nodejs
66+
run: npm ci --ignore-scripts
67+
5968
- name: Run ruff format check
6069
run: uv run ruff format --check .
6170

@@ -76,5 +85,4 @@ jobs:
7685
- name: Run Python SDK tests
7786
env:
7887
COPILOT_HMAC_KEY: ${{ secrets.COPILOT_DEVELOPER_CLI_INTEGRATION_HMAC_KEY }}
79-
COPILOT_CLI_PATH: ${{ steps.setup-copilot.outputs.cli-path }}
8088
run: uv run pytest -v -s

dotnet/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
bin/
33
obj/
44

5+
# Generated build props (contains CLI version)
6+
src/build/GitHub.Copilot.SDK.props
7+
58
# NuGet packages
69
*.nupkg
710
*.snupkg

dotnet/src/Client.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -873,15 +873,17 @@ private async Task VerifyProtocolVersionAsync(Connection connection, Cancellatio
873873

874874
private static async Task<(Process Process, int? DetectedLocalhostTcpPort)> StartCliServerAsync(CopilotClientOptions options, ILogger logger, CancellationToken cancellationToken)
875875
{
876-
var cliPath = options.CliPath ?? "copilot";
876+
// Use explicit path or bundled CLI - no PATH fallback
877+
var cliPath = options.CliPath ?? GetBundledCliPath(out var searchedPath)
878+
?? throw new InvalidOperationException($"Copilot CLI not found at '{searchedPath}'. Ensure the SDK NuGet package was restored correctly or provide an explicit CliPath.");
877879
var args = new List<string>();
878880

879881
if (options.CliArgs != null)
880882
{
881883
args.AddRange(options.CliArgs);
882884
}
883885

884-
args.AddRange(["--headless", "--log-level", options.LogLevel]);
886+
args.AddRange(["--headless", "--no-auto-update", "--log-level", options.LogLevel]);
885887

886888
if (options.UseStdio)
887889
{
@@ -976,6 +978,14 @@ private async Task VerifyProtocolVersionAsync(Connection connection, Cancellatio
976978
return (cliProcess, detectedLocalhostTcpPort);
977979
}
978980

981+
private static string? GetBundledCliPath(out string searchedPath)
982+
{
983+
var binaryName = OperatingSystem.IsWindows() ? "copilot.exe" : "copilot";
984+
var rid = Path.GetFileName(System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier);
985+
searchedPath = Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native", binaryName);
986+
return File.Exists(searchedPath) ? searchedPath : null;
987+
}
988+
979989
private static (string FileName, IEnumerable<string> Args) ResolveCliCommand(string cliPath, IEnumerable<string> args)
980990
{
981991
var isJsFile = cliPath.EndsWith(".js", StringComparison.OrdinalIgnoreCase);
@@ -985,13 +995,6 @@ private static (string FileName, IEnumerable<string> Args) ResolveCliCommand(str
985995
return ("node", new[] { cliPath }.Concat(args));
986996
}
987997

988-
// On Windows with UseShellExecute=false, Process.Start doesn't search PATHEXT,
989-
// so use cmd /c to let the shell resolve the executable
990-
if (OperatingSystem.IsWindows() && !Path.IsPathRooted(cliPath))
991-
{
992-
return ("cmd", new[] { "/c", cliPath }.Concat(args));
993-
}
994-
995998
return (cliPath, args);
996999
}
9971000

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,60 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
8+
<Version>0.1.0</Version>
9+
<Description>SDK for programmatic control of GitHub Copilot CLI</Description>
10+
<Authors>GitHub</Authors>
11+
<Company>GitHub</Company>
12+
<Copyright>Copyright (c) Microsoft Corporation. All rights reserved.</Copyright>
13+
<PackageLicenseExpression>MIT</PackageLicenseExpression>
14+
<PackageReadmeFile>README.md</PackageReadmeFile>
15+
<RepositoryUrl>https://github.com/github/copilot-sdk</RepositoryUrl>
16+
<PackageTags>github;copilot;sdk;jsonrpc;agent</PackageTags>
17+
<IsAotCompatible>true</IsAotCompatible>
18+
</PropertyGroup>
19+
20+
<ItemGroup>
21+
<None Include="../README.md" Pack="true" PackagePath="/" />
22+
</ItemGroup>
23+
24+
<ItemGroup>
25+
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="10.2.0" />
26+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.2" />
27+
<PackageReference Include="StreamJsonRpc" Version="2.24.84" PrivateAssets="compile" />
28+
<PackageReference Include="System.Text.Json" Version="10.0.2" />
29+
</ItemGroup>
30+
31+
<!-- Generate version props file at build time (gitignored) -->
32+
<Target Name="_GenerateVersionProps" BeforeTargets="BeforeBuild;Pack">
33+
<Exec Command="node -e &quot;console.log(require('./nodejs/package-lock.json').packages['node_modules/@github/copilot'].version)&quot;" WorkingDirectory="$(MSBuildThisFileDirectory)../.." ConsoleToMSBuild="true" StandardOutputImportance="low">
34+
<Output TaskParameter="ConsoleOutput" PropertyName="CopilotCliVersion" />
35+
</Exec>
36+
<Error Condition="'$(CopilotCliVersion)' == ''" Text="CopilotCliVersion could not be read from nodejs/package-lock.json" />
37+
<PropertyGroup>
38+
<_VersionPropsContent>
39+
<![CDATA[<Project>
340
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
5-
<ImplicitUsings>enable</ImplicitUsings>
6-
<Nullable>enable</Nullable>
7-
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
8-
<Version>0.1.0</Version>
9-
<Description>SDK for programmatic control of GitHub Copilot CLI</Description>
10-
<Authors>GitHub</Authors>
11-
<Company>GitHub</Company>
12-
<Copyright>Copyright (c) Microsoft Corporation. All rights reserved.</Copyright>
13-
<PackageLicenseExpression>MIT</PackageLicenseExpression>
14-
<PackageReadmeFile>README.md</PackageReadmeFile>
15-
<RepositoryUrl>https://github.com/github/copilot-sdk</RepositoryUrl>
16-
<PackageTags>github;copilot;sdk;jsonrpc;agent</PackageTags>
17-
<IsAotCompatible>true</IsAotCompatible>
41+
<CopilotCliVersion>$(CopilotCliVersion)</CopilotCliVersion>
1842
</PropertyGroup>
43+
</Project>]]>
44+
</_VersionPropsContent>
45+
</PropertyGroup>
46+
<WriteLinesToFile File="$(MSBuildThisFileDirectory)build\GitHub.Copilot.SDK.props" Lines="$(_VersionPropsContent)" Overwrite="true" WriteOnlyWhenDifferent="true" />
47+
<!-- Explicitly add props file to package content after generation -->
48+
<ItemGroup>
49+
<None Include="build\GitHub.Copilot.SDK.props" Pack="true" PackagePath="build\" />
50+
</ItemGroup>
51+
</Target>
1952

20-
<ItemGroup>
21-
<None Include="../README.md" Pack="true" PackagePath="/" />
22-
</ItemGroup>
23-
24-
<ItemGroup>
25-
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="10.2.0" />
26-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.2" />
27-
<PackageReference Include="StreamJsonRpc" Version="2.24.84" PrivateAssets="compile" />
28-
<PackageReference Include="System.Text.Json" Version="10.0.2" />
29-
</ItemGroup>
53+
<!-- Include .targets file in package (props is added dynamically by _GenerateVersionProps) -->
54+
<!-- Also import the .targets for local dev (same logic consumers get) -->
55+
<ItemGroup>
56+
<None Include="build\GitHub.Copilot.SDK.targets" Pack="true" PackagePath="build\" CopyToOutputDirectory="Never" />
57+
</ItemGroup>
58+
<Import Project="build\GitHub.Copilot.SDK.targets" />
3059

3160
</Project>

dotnet/src/Types.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ public enum ConnectionState
2424

2525
public class CopilotClientOptions
2626
{
27+
/// <summary>
28+
/// Path to the Copilot CLI executable. If not specified, uses the bundled CLI from the SDK.
29+
/// </summary>
2730
public string? CliPath { get; set; }
2831
public string[]? CliArgs { get; set; }
2932
public string? Cwd { get; set; }

0 commit comments

Comments
 (0)