Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/actions/java-test-report/action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: "Java Test Report"
description: "Generate and publish test reports with summary for Java SDK tests."
inputs:
title:
description: "Heading to display in the summary (identifies the JDK variant)"
required: false
default: "Copilot Java SDK :: Test Results"
report-path:
description: "Path to the test report XML files (glob pattern)"
required: false
Expand All @@ -13,6 +17,10 @@ inputs:
description: "Path to the JaCoCo CSV report"
required: false
default: "java/target/site/jacoco-coverage/jacoco.csv"
show-coverage:
description: "Whether to include JaCoCo coverage in the summary"
required: false
default: "true"
check-name:
description: "Name for the check run"
required: false
Expand All @@ -23,7 +31,7 @@ runs:
- name: Generate Test Summary
shell: bash
run: |
echo "## 🧪 Copilot Java SDK :: Test Results" >> $GITHUB_STEP_SUMMARY
echo "## 🧪 ${{ inputs.title }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if ls ${{ inputs.report-path }} 1>/dev/null 2>&1; then
Expand Down Expand Up @@ -81,6 +89,7 @@ runs:
fi

- name: Generate Coverage Summary
if: inputs.show-coverage == 'true'
shell: bash
run: |
JACOCO_XML="${{ inputs.jacoco-path }}"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/java-publish-maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ jobs:

- uses: ./.github/actions/setup-copilot

- name: Set up JDK 17
- name: Set up JDK 25
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: "17"
java-version: "25"
distribution: "microsoft"
cache: "maven"
server-id: central
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/java-publish-snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ jobs:

- uses: ./.github/actions/setup-copilot

- name: Set up JDK 17
- name: Set up JDK 25
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: "17"
java-version: "25"
distribution: "microsoft"
cache: "maven"
server-id: central
Expand Down
35 changes: 34 additions & 1 deletion .github/workflows/java-sdk-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ on:
- "!**/*.gif"
- "!**/*.svg"
workflow_dispatch:
inputs:
test-jdk17:
description: "Also run tests on JDK 17 (compatibility check)"
type: boolean
required: false
default: true
merge_group:

permissions:
Expand All @@ -52,7 +58,7 @@ jobs:

- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: "17"
java-version: "25"
distribution: "microsoft"
cache: "maven"

Expand Down Expand Up @@ -116,6 +122,8 @@ jobs:
- name: Generate Test Report Summary
if: always()
uses: ./.github/actions/java-test-report
with:
title: "Copilot Java SDK :: Test Results (JDK 25)"

- name: Upload test results on failure
if: failure()
Expand All @@ -126,3 +134,28 @@ jobs:
java/target/surefire-reports/
java/target/surefire-reports-isolated/
retention-days: 7

- name: Switch to JDK 17
if: inputs.test-jdk17 == true || inputs.test-jdk17 == null
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: "17"
distribution: "microsoft"

- name: Re-run tests on JDK 17 (no recompilation)
if: inputs.test-jdk17 == true || inputs.test-jdk17 == null
env:
CI: "true"
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_CLI_PATH: ${{ steps.setup-copilot.outputs.cli-path }}
run: |
echo "Running tests against JDK 25-built classes using JDK 17 runtime..."
java -version
mvn antrun:run@print-test-jdk-banner surefire:test -Denforcer.skip=true -DtestExecutionAgentArgs=

- name: Generate Test Report Summary (JDK 17)
if: always() && (inputs.test-jdk17 == true || inputs.test-jdk17 == null)
uses: ./.github/actions/java-test-report
with:
title: "Copilot Java SDK :: Test Results (JDK 17)"
show-coverage: "false"
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
"[go]": {
"editor.defaultFormatter": "golang.go"
},
"java.configuration.updateBuildConfiguration": "automatic"
"java.configuration.updateBuildConfiguration": "automatic",
"java.compile.nullAnalysis.mode": "automatic"
}
1,208 changes: 1,208 additions & 0 deletions java/20261027-2202-job-logs.txt

Large diffs are not rendered by default.

11 changes: 2 additions & 9 deletions java/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Java SDK for programmatic control of GitHub Copilot CLI, enabling you to build A

### Requirements

- Java 17 or later. **JDK 25 recommended**. Selecting JDK 25 enables the use of virtual threads, as shown in the [Quick Start](#quick-start).
- Java 17 or later. **JDK 25 recommended**. On JDK 25 and later, the SDK automatically uses virtual threads for its default internal executor.
- GitHub Copilot CLI 1.0.17 or later installed and in `PATH` (or provide custom `cliPath`)

### Maven
Expand Down Expand Up @@ -66,23 +66,16 @@ implementation 'com.github:copilot-sdk-java:1.0.0-beta-java.4'
import com.github.copilot.CopilotClient;
import com.github.copilot.generated.AssistantMessageEvent;
import com.github.copilot.generated.SessionUsageInfoEvent;
import com.github.copilot.rpc.CopilotClientOptions;
import com.github.copilot.rpc.MessageOptions;
import com.github.copilot.rpc.PermissionHandler;
import com.github.copilot.rpc.SessionConfig;

import java.util.concurrent.Executors;

public class CopilotSDK {
public static void main(String[] args) throws Exception {
var lastMessage = new String[]{null};

// Create and start client
try (var client = new CopilotClient()) { // JDK 25+: comment out this line
// JDK 25+: uncomment the following 3 lines for virtual thread support
// var options = new CopilotClientOptions()
// .setExecutor(Executors.newVirtualThreadPerTaskExecutor());
// try (var client = new CopilotClient(options)) {
try (var client = new CopilotClient()) {
client.start().get();

// Create a session
Expand Down
163 changes: 163 additions & 0 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@
</target>
</configuration>
</execution>
<execution>
<id>print-test-jdk-banner</id>
<phase>process-test-classes</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo level="warning" message="⚠⚠⚠ Using Java ${java.version} (${java.vendor}) to run tests." />
</target>
</configuration>
</execution>
</executions>
<dependencies>
<!-- Required for if:set and unless:set -->
Expand Down Expand Up @@ -307,6 +319,33 @@
</execution>
</executions>
</plugin>
<!--
Failsafe runs integration tests against the actually packaged
JAR (after the package phase). Used to validate multi-release
JAR behaviour end-to-end without reflecting on private fields
or hand-rolling a synthetic JAR. See
src/test/java/com/github/copilot/InternalExecutorProviderIT.java.
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.5.5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<project.build.directory>${project.build.directory}</project.build.directory>
<project.build.finalName>${project.build.finalName}</project.build.finalName>
<project.build.testOutputDirectory>${project.build.testOutputDirectory}</project.build.testOutputDirectory>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand Down Expand Up @@ -447,6 +486,10 @@
<configuration>
<dataFile>${project.build.directory}/jacoco-test-results/sdk-tests.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-coverage</outputDirectory>
<excludes>
<!-- Exclude multi-release classes to avoid duplicate class analysis. -->
<exclude>META-INF/versions/**/*.class</exclude>
</excludes>
</configuration>
</execution>
</executions>
Expand Down Expand Up @@ -489,6 +532,44 @@
<autoPublish>true</autoPublish>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>enforce-jdk25</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[25,)</version>
<message>JDK 25+ is required to build the Multi-Release JAR with the virtual-thread overlay.</message>
</requireJavaVersion>
</rules>
</configuration>
</execution>
<execution>
<id>verify-multi-release-overlay</id>
<phase>verify</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireFilesExist>
<files>
<file>${project.build.outputDirectory}/META-INF/versions/25/com/github/copilot/InternalExecutorProvider.class</file>
</files>
<message>Multi-Release JAR overlay missing: META-INF/versions/25/com/github/copilot/InternalExecutorProvider.class was not compiled. Ensure the build runs on JDK 25+.</message>
</requireFilesExist>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand All @@ -507,6 +588,88 @@
<surefire.jvm.args>-XX:+EnableDynamicAgentLoading</surefire.jvm.args>
</properties>
</profile>
<profile>
<id>java25-multi-release</id>
<activation>
<jdk>[25,)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile-java25</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>25</release>
<useIncrementalCompilation>false</useIncrementalCompilation>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java25</compileSourceRoot>
</compileSourceRoots>
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!--
Structural guard: when this profile is active (JDK 25+
builds), assert that the packaged JAR contains the
JDK 25 multi-release overlay class. Catches accidental
profile-disable / classifier / shading regressions
before the failsafe IT runs.
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>verify-java25-overlay</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<condition property="java25.overlay.present">
<resourceexists>
<zipentry zipfile="${project.build.directory}/${project.build.finalName}.jar"
name="META-INF/versions/25/com/github/copilot/InternalExecutorProvider.class"/>
</resourceexists>
</condition>
<fail unless="java25.overlay.present">
JDK 25 multi-release overlay class is missing from the packaged JAR.
Expected entry: META-INF/versions/25/com/github/copilot/InternalExecutorProvider.class
JAR: ${project.build.directory}/${project.build.finalName}.jar

This usually means the 'java25-multi-release' Maven profile did not activate
(e.g. the build is running on a JDK older than 25) or maven-compiler-plugin
did not produce the multi-release output. Re-build on JDK 25+ and verify the
'compile-java25' execution ran during the 'compile' phase.
</fail>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- Skip git-clone + npm install of the copilot-sdk test harness -->
<profile>
<id>skip-test-harness</id>
Expand Down
Loading
Loading