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
55 changes: 16 additions & 39 deletions .github/workflows/java-publish-maven.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish to Maven Central
name: "Java Publish to Maven Central"

env:
# Disable Husky Git hooks in CI to prevent local development hooks
Expand Down Expand Up @@ -35,6 +35,10 @@ jobs:
publish-maven:
name: Publish Java SDK to Maven Central
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./java
outputs:
version: ${{ steps.versions.outputs.release_version }}
steps:
Expand Down Expand Up @@ -114,15 +118,6 @@ jobs:
run: |
VERSION="${{ steps.versions.outputs.release_version }}"

# Read the reference implementation SDK commit hash that this release is synced to
REFERENCE_IMPL_HASH=$(cat .lastmerge)
REFERENCE_IMPL_SHORT="${REFERENCE_IMPL_HASH:0:7}"
REFERENCE_IMPL_URL="https://github.com/github/copilot-sdk/commit/${REFERENCE_IMPL_HASH}"
echo "Reference implementation SDK sync: ${REFERENCE_IMPL_SHORT} (${REFERENCE_IMPL_URL})"

# Update CHANGELOG.md with release version and Reference implementation sync hash
../.github/scripts/release/update-changelog.sh "${VERSION}" "${REFERENCE_IMPL_HASH}"

# Update version in README.md (supports any version qualifier like -java.N, -java-preview.N, -beta-java.N)
sed -i "s|<version>[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)*</version>|<version>${VERSION}</version>|g" README.md
sed -i "s|copilot-sdk-java:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)*|copilot-sdk-java:${VERSION}|g" README.md
Expand All @@ -136,7 +131,7 @@ jobs:
sed -i 's|copilot-sdk-java:${project\.version}|copilot-sdk-java:'"${VERSION}"'|g' jbang-example.java

# Commit the documentation changes before release:prepare (requires clean working directory)
git add CHANGELOG.md README.md jbang-example.java
git add README.md jbang-example.java
git commit -m "docs: update version references to ${VERSION}"

# Save the commit SHA for potential rollback
Expand All @@ -150,7 +145,7 @@ jobs:
mvn -B release:prepare \
-DreleaseVersion=${{ steps.versions.outputs.release_version }} \
-DdevelopmentVersion=${{ steps.versions.outputs.dev_version }} \
-DtagNameFormat=v@{project.version} \
-DtagNameFormat=java/v@{project.version} \
-DpushChanges=true \
-Darguments="-DskipTests"
env:
Expand Down Expand Up @@ -185,6 +180,10 @@ jobs:
needs: publish-maven
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./java
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand All @@ -194,7 +193,7 @@ jobs:
VERSION="${{ needs.publish-maven.outputs.version }}"
GROUP_ID="com.github"
ARTIFACT_ID="copilot-sdk-java"
CURRENT_TAG="v${VERSION}"
CURRENT_TAG="java/v${VERSION}"

if gh release view "${CURRENT_TAG}" >/dev/null 2>&1; then
echo "Release ${CURRENT_TAG} already exists. Skipping creation."
Expand All @@ -203,11 +202,10 @@ jobs:

# Generate release notes from template
export VERSION GROUP_ID ARTIFACT_ID
RELEASE_NOTES=$(envsubst < .github/workflows/notes.template)
RELEASE_NOTES=$(envsubst < $GITHUB_WORKSPACE/.github/workflows/java.notes.template)

# Get the previous tag for generating notes
PREV_TAG=$(git tag --list 'v*' --sort=-version:refname \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-java(-preview)?\.[0-9]+)?$' \
PREV_TAG=$(git tag --list 'java/v*' --sort=-version:refname \
| grep -Fxv "${CURRENT_TAG}" \
| head -n 1)

Expand All @@ -229,28 +227,7 @@ jobs:
gh release create "${GH_ARGS[@]}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Move 'latest' tag to new release
run: |
VERSION="${{ needs.publish-maven.outputs.version }}"
git tag -f latest "v${VERSION}"
git push origin latest --force
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

deploy-site:
name: Deploy Documentation
needs: [publish-maven, github-release]
runs-on: ubuntu-latest
permissions:
actions: write
contents: read
steps:
- name: Trigger site deployment
run: |
gh workflow run deploy-site.yml \
--repo ${{ github.repository }} \
-f version="${{ needs.publish-maven.outputs.version }}" \
-f publish_as_latest=true
- name: Trigger changelog generation
run: gh workflow run release-changelog.lock.yml -f tag="java/v${{ needs.publish-maven.outputs.version }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Comment on lines +230 to 233
6 changes: 5 additions & 1 deletion .github/workflows/java-publish-snapshot.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish Snapshot to Maven Central
name: Java Publish Snapshot to Maven Central

env:
HUSKY: 0
Expand All @@ -19,6 +19,10 @@ jobs:
publish-snapshot:
name: Publish SNAPSHOT to Maven Central
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./java
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand Down
161 changes: 161 additions & 0 deletions .github/workflows/java-smoke-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
name: "Java smoke test"

on:
workflow_dispatch:
workflow_call:
secrets:
COPILOT_GITHUB_TOKEN:
required: true

permissions:
contents: read

jobs:
smoke-test-jdk17:
name: Build SDK and run smoke test (JDK 17)
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
defaults:
run:
shell: bash
working-directory: ./java
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: "17"
distribution: "microsoft"
cache: "maven"

- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v6
with:
node-version: 22

- name: Read pinned @github/copilot version from pom.xml
id: cli-version
run: |
PROP="readonly-copilot-sdk-ref-impl-version-from-lastmerge-file-updated-by-reference-impl-sync"
VERSION=$(sed -n "s|.*<${PROP}>\(.*\)</${PROP}>.*|\1|p" pom.xml | head -n 1 | tr -d '[:space:]')
if [[ -z "$VERSION" || "$VERSION" == "PRIMER_TO_REPLACE" ]]; then
echo "::error::Could not read pinned @github/copilot version from pom.xml property <${PROP}>" >&2
exit 1
fi
echo "Pinned @github/copilot version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
Comment on lines +40 to +46

- name: Install Copilot CLI globally (pinned to pom.xml version)
run: npm install -g "@github/copilot@${{ steps.cli-version.outputs.version }}"

- name: Verify CLI works
run: copilot --version

- name: Build SDK and install to local repo
run: mvn -DskipTests -Pskip-test-harness clean install

- name: Create and run smoke test via Copilot CLI
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
run: |
cat > /tmp/smoke-test-prompt.txt << 'PROMPT_EOF'
You are running inside the copilot-sdk monorepo, in the java/ subdirectory.
The SDK has already been built and installed into the local Maven repository.
JDK 17 and Maven are already installed and on PATH.

Execute the prompt at `src/test/prompts/PROMPT-smoke-test.md` with the following critical overrides:

**Critical override — disable SNAPSHOT updates (but allow downloads):** The goal of this workflow is to validate the SDK SNAPSHOT that was just built and installed locally, not any newer SNAPSHOT that might exist in a remote repository. To ensure Maven does not download a newer timestamped SNAPSHOT of the SDK while still allowing it to download any missing plugins or dependencies, you must run the smoke-test Maven build without `-U` and with `--no-snapshot-updates`, so that it uses the locally installed SDK artifact. Use `mvn --no-snapshot-updates clean package` instead of `mvn -U clean package` or `mvn -o clean package`.

**Critical override — do NOT run the jar:** Stop after the `mvn --no-snapshot-updates clean package` build succeeds. Do NOT execute Step 4 (java -jar) or Step 5 (verify exit code) from the prompt. The workflow will run the jar in a separate deterministic step to guarantee the exit code propagates correctly.

Follow steps 1-3 only: create the `smoke-test/` directory, create `pom.xml` and the Java source file exactly as specified, and build with `mvn --no-snapshot-updates clean package` (no SNAPSHOT updates and without `-U`).

If any step fails, exit with a non-zero exit code. Do not silently fix errors.
PROMPT_EOF

copilot --yolo --prompt "$(cat /tmp/smoke-test-prompt.txt)"

- name: Run smoke test jar
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
run: |
cd smoke-test
java -jar ./target/copilot-sdk-smoketest-1.0-SNAPSHOT.jar
echo "Smoke test passed (exit code 0)"

smoke-test-java25:
name: Build SDK and run smoke test (JDK 25)
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
defaults:
run:
shell: bash
working-directory: ./java
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up JDK 25
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: "25"
distribution: "microsoft"
cache: "maven"

- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v6
with:
node-version: 22

- name: Read pinned @github/copilot version from pom.xml
id: cli-version
run: |
PROP="readonly-copilot-sdk-ref-impl-version-from-lastmerge-file-updated-by-reference-impl-sync"
VERSION=$(sed -n "s|.*<${PROP}>\(.*\)</${PROP}>.*|\1|p" pom.xml | head -n 1 | tr -d '[:space:]')
if [[ -z "$VERSION" || "$VERSION" == "PRIMER_TO_REPLACE" ]]; then
echo "::error::Could not read pinned @github/copilot version from pom.xml property <${PROP}>" >&2
exit 1
fi
echo "Pinned @github/copilot version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Install Copilot CLI globally (pinned to pom.xml version)
run: npm install -g "@github/copilot@${{ steps.cli-version.outputs.version }}"

- name: Verify CLI works
run: copilot --version

- name: Build SDK and install to local repo
run: mvn -DskipTests -Pskip-test-harness clean install

- name: Create and run smoke test via Copilot CLI
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
run: |
cat > /tmp/smoke-test-prompt.txt << 'PROMPT_EOF'
You are running inside the copilot-sdk monorepo, in the java/ subdirectory.
The SDK has already been built and installed into the local Maven repository.
JDK 25 and Maven are already installed and on PATH.

Execute the prompt at `src/test/prompts/PROMPT-smoke-test.md` with the following critical overrides:

**Critical override — disable SNAPSHOT updates (but allow downloads):** The goal of this workflow is to validate the SDK SNAPSHOT that was just built and installed locally, not any newer SNAPSHOT that might exist in a remote repository. To ensure Maven does not download a newer timestamped SNAPSHOT of the SDK while still allowing it to download any missing plugins or dependencies, you must run the smoke-test Maven build without `-U` and with `--no-snapshot-updates`, so that it uses the locally installed SDK artifact. Use `mvn --no-snapshot-updates clean package` instead of `mvn -U clean package` or `mvn -o clean package`.

**Critical override — do NOT run the jar:** Stop after the `mvn --no-snapshot-updates clean package` build succeeds. Do NOT execute Step 4 (java -jar) or Step 5 (verify exit code) from the prompt. The workflow will run the jar in a separate deterministic step to guarantee the exit code propagates correctly.

**Critical override — enable Virtual Threads for JDK 25:** After creating the Java source file from the README "Quick Start" section but BEFORE building, you must modify the source file to enable virtual thread support. The Quick Start code contains inline comments that start with `// JDK 25+:` — these are instructions. Find every such comment and follow what it says (comment out lines it says to comment out, uncomment lines it says to uncomment). Add any imports required by the newly uncommented code (e.g. `java.util.concurrent.Executors`).
Also set `maven.compiler.source` and `maven.compiler.target` to `25` in the `pom.xml`.

Follow steps 1-3 only: create the `smoke-test/` directory, create `pom.xml` and the Java source file exactly as specified, apply the JDK 25 virtual thread modifications described above, and build with `mvn --no-snapshot-updates clean package` (no SNAPSHOT updates and without `-U`).

If any step fails, exit with a non-zero exit code. Do not silently fix errors.
PROMPT_EOF

copilot --yolo --prompt "$(cat /tmp/smoke-test-prompt.txt)"

- name: Run smoke test jar
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
run: |
cd smoke-test
java -jar ./target/copilot-sdk-smoketest-1.0-SNAPSHOT.jar
echo "Smoke test passed (exit code 0)"
26 changes: 26 additions & 0 deletions .github/workflows/java.notes.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Installation

ℹ️ **Public Preview:** This is the official Java SDK for GitHub Copilot. This repository treats the official .NET and Node.js SDKs for GitHub Copilot as reference implementations. These SDKs are all officially supported as GitHub open source projects. The Java implementation follows the backward compatibility guarantees offered by the reference implementations.

⚠️ **Artifact versioning plan:** Releases of this implementation track releases of the reference implementation. For each release of the reference implementation, there may follow a corresponding release of this implementation with the same number as the reference implementation. Release identifiers of the reference implementation are in the form `vMaj.Min.Micro`. For example v0.1.32. The corresponding maven version for the release will be `Maj.Min.Micro-java.N`, where `Maj`, `Min` and `Micro` are the corresponding numbers for the reference implementation release, and `N` is a monotonically increasing sequence number starting with 0 for each release. See the corresponding architectural decision record for more information in the `docs/adr` directory of the source code.

📦 [View on Maven Central](https://central.sonatype.com/artifact/${GROUP_ID}/${ARTIFACT_ID}/${VERSION})

## Maven
```xml
<dependency>
<groupId>${GROUP_ID}</groupId>
<artifactId>${ARTIFACT_ID}</artifactId>
<version>${VERSION}</version>
</dependency>
```

## Gradle (Kotlin DSL)
```kotlin
implementation("${GROUP_ID}:${ARTIFACT_ID}:${VERSION}")
```

## Gradle (Groovy DSL)
```groovy
implementation '${GROUP_ID}:${ARTIFACT_ID}:${VERSION}'
```
Loading
Loading