From 7f989bad304d0e1ebae51ac523310e25d0109003 Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Tue, 3 Nov 2026 14:30:47 -0500 Subject: [PATCH 1/4] Docs: separate Java artifact and site versions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a93f06c-3318-405d-ad86-fcf729e58207 --- .github/workflows/deploy-site.yml | 31 ++++--- pom.xml | 2 + scripts/prepare-site-versions.mjs | 110 +++++++++++++++++++++++++ scripts/prepare-site-versions.test.mjs | 50 +++++++++++ src/site/markdown/getting-started.md | 13 ++- src/site/markdown/index.md | 13 ++- 6 files changed, 200 insertions(+), 19 deletions(-) create mode 100644 scripts/prepare-site-versions.mjs create mode 100644 scripts/prepare-site-versions.test.mjs diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml index ae35e3e9f0..17a06bd449 100644 --- a/.github/workflows/deploy-site.yml +++ b/.github/workflows/deploy-site.yml @@ -18,6 +18,11 @@ on: description: 'Tag in github/copilot-sdk monorepo (e.g., java/v1.0.1-java.0)' type: string required: true + artifact_version: + description: 'Java Maven artifact version. Defaults to the site version for older callers.' + type: string + required: false + default: '' permissions: contents: write @@ -80,23 +85,27 @@ jobs: echo "Compiling Java source from tag ${{ inputs.monorepo_tag }}" mvn clean compile test -DskipTests=false -Dcheckstyle.skip=true -B - # 5. Update hardcoded version strings in site content - # Cookbook files and other markdown pages embed JBang //DEPS lines with - # hardcoded artifact versions for direct browsing on GitHub. Update them - # to the version being released. (${project.version} references are - # handled by Maven resource filtering during mvn site.) - - name: Update version strings in site content + # 5. Prepare Java artifact versions and snapshot repository instructions + - name: Prepare site artifact versions run: | VERSION="${{ inputs.version }}" - echo "Updating copilot-sdk-java version references to ${VERSION}" - find src/site/markdown -name "*.md" -type f -exec \ - 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" {} \; + ARTIFACT_VERSION="${{ inputs.artifact_version }}" + if [[ -z "${ARTIFACT_VERSION}" ]]; then + if [[ "${{ inputs.publish_as_latest }}" == "false" ]]; then + echo "::error::artifact_version is required for preview documentation" + exit 1 + fi + ARTIFACT_VERSION="${VERSION}" + fi + node scripts/prepare-site-versions.mjs \ + "${VERSION}" "${ARTIFACT_VERSION}" src/site/markdown + echo "ARTIFACT_VERSION=${ARTIFACT_VERSION}" >> "$GITHUB_ENV" # 6. Build the Maven Site using THIS repo's pom.xml + src/site/ - name: Build documentation site run: | - echo "Building site for version ${{ inputs.version }}" - mvn site -Dsite.version=${{ inputs.version }} -B + echo "Building site for version ${{ inputs.version }} with Java artifacts ${ARTIFACT_VERSION}" + mvn site -Dsite.version=${{ inputs.version }} -Dartifact.version="${ARTIFACT_VERSION}" -B # 7. Prepare gh-pages deployment directory - name: Prepare gh-pages directory diff --git a/pom.xml b/pom.xml index e34688255d..55410049ba 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,8 @@ UTF-8 0.0.0-SNAPSHOT + + ${site.version} ${project.basedir}/monorepo/java diff --git a/scripts/prepare-site-versions.mjs b/scripts/prepare-site-versions.mjs new file mode 100644 index 0000000000..aaf5ebb148 --- /dev/null +++ b/scripts/prepare-site-versions.mjs @@ -0,0 +1,110 @@ +import assert from "node:assert/strict"; +import { readFileSync, readdirSync, statSync, writeFileSync } from "node:fs"; +import { join } from "node:path"; +import { pathToFileURL } from "node:url"; + +const VERSION_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/; +const SNAPSHOT_REPOSITORY = "https://central.sonatype.com/repository/maven-snapshots/"; + +function markdownFiles(directory) { + return readdirSync(directory).flatMap((name) => { + const path = join(directory, name); + return statSync(path).isDirectory() + ? markdownFiles(path) + : path.endsWith(".md") + ? [path] + : []; + }); +} + +export function prepareSiteVersions(siteVersion, artifactVersion, markdownDirectory) { + assert.match(siteVersion, VERSION_PATTERN, "Invalid site version"); + assert.match(artifactVersion, VERSION_PATTERN, "Invalid artifact version"); + const siteBase = /^\d+\.\d+\.\d+/.exec(siteVersion)?.[0]; + if (artifactVersion.endsWith("-SNAPSHOT")) { + assert.equal( + artifactVersion, + `${siteBase}-SNAPSHOT`, + "Snapshot artifact version must use the site version's base" + ); + } else { + assert.equal( + artifactVersion, + siteVersion, + "Non-snapshot artifact version must match the site version" + ); + } + + const snapshot = artifactVersion.endsWith("-SNAPSHOT"); + const replacements = new Map([ + [ + "", + snapshot + ? `Snapshot builds require this repository: + +\`\`\`xml + + + central-snapshots + ${SNAPSHOT_REPOSITORY} + false + true + + +\`\`\`` + : "", + ], + [ + "", + snapshot + ? `Snapshot builds require this repository: + +\`\`\`groovy +repositories { + mavenCentral() + maven { + url = uri('${SNAPSHOT_REPOSITORY}') + mavenContent { snapshotsOnly() } + } +} +\`\`\`` + : "", + ], + [ + "//ARTIFACT_REPOSITORY", + snapshot ? `//REPOS central,central-snapshots=${SNAPSHOT_REPOSITORY}` : "", + ], + ]); + + let hardcodedCoordinates = 0; + const markerCounts = new Map([...replacements.keys()].map((marker) => [marker, 0])); + for (const path of markdownFiles(markdownDirectory)) { + let content = readFileSync(path, "utf8"); + content = content.replace( + /copilot-sdk-java:\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?/g, + () => { + hardcodedCoordinates++; + return `copilot-sdk-java:${artifactVersion}`; + } + ); + for (const [marker, replacement] of replacements) { + const count = content.split(marker).length - 1; + markerCounts.set(marker, markerCounts.get(marker) + count); + content = content.replaceAll(marker, replacement); + } + writeFileSync(path, content); + } + assert(hardcodedCoordinates > 0, "Expected hardcoded Java coordinates in site content"); + for (const [marker, count] of markerCounts) { + assert(count > 0, `Expected site marker: ${marker}`); + } +} + +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + assert.equal( + process.argv.length, + 5, + "Usage: prepare-site-versions.mjs " + ); + prepareSiteVersions(process.argv[2], process.argv[3], process.argv[4]); +} diff --git a/scripts/prepare-site-versions.test.mjs b/scripts/prepare-site-versions.test.mjs new file mode 100644 index 0000000000..860aa4dc81 --- /dev/null +++ b/scripts/prepare-site-versions.test.mjs @@ -0,0 +1,50 @@ +import assert from "node:assert/strict"; +import { cpSync, mkdtempSync, readFileSync, rmSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join, resolve } from "node:path"; +import test from "node:test"; +import { prepareSiteVersions } from "./prepare-site-versions.mjs"; + +function fixture(t) { + const root = mkdtempSync(join(tmpdir(), "copilot-java-site-")); + t.after(() => rmSync(root, { recursive: true, force: true })); + const markdown = join(root, "markdown"); + cpSync(resolve("src/site/markdown"), markdown, { recursive: true }); + return markdown; +} + +test("renders preview dependency coordinates and snapshot repositories", (t) => { + const markdown = fixture(t); + prepareSiteVersions("1.0.15-preview.2", "1.0.15-SNAPSHOT", markdown); + + const gettingStarted = readFileSync(join(markdown, "getting-started.md"), "utf8"); + assert.match(gettingStarted, /\$\{artifact\.version\}<\/version>/); + assert.match(gettingStarted, /implementation 'com\.github:copilot-sdk-java:\$\{artifact\.version\}'/); + assert.match(gettingStarted, /false<\/enabled><\/releases>/); + assert.match(gettingStarted, /mavenContent \{ snapshotsOnly\(\) \}/); + assert.match( + gettingStarted, + /\/\/REPOS central,central-snapshots=https:\/\/central\.sonatype\.com\/repository\/maven-snapshots\// + ); + const cookbook = readFileSync(join(markdown, "cookbook", "managing-local-files.md"), "utf8"); + assert.match(cookbook, /copilot-sdk-java:1\.0\.15-SNAPSHOT/); +}); + +test("keeps stable dependency rendering free of snapshot configuration", (t) => { + const markdown = fixture(t); + prepareSiteVersions("1.0.15", "1.0.15", markdown); + + const gettingStarted = readFileSync(join(markdown, "getting-started.md"), "utf8"); + assert.doesNotMatch(gettingStarted, /maven-snapshots/); + assert.doesNotMatch(gettingStarted, /ARTIFACT_/); + const cookbook = readFileSync(join(markdown, "cookbook", "managing-local-files.md"), "utf8"); + assert.match(cookbook, /copilot-sdk-java:1\.0\.15/); +}); + +test("rejects an artifact version from another shared base", (t) => { + const markdown = fixture(t); + assert.throws( + () => prepareSiteVersions("1.0.15-preview.2", "1.0.16-SNAPSHOT", markdown), + /site version's base/ + ); +}); diff --git a/src/site/markdown/getting-started.md b/src/site/markdown/getting-started.md index 0bde2ef50d..6f9705e37e 100644 --- a/src/site/markdown/getting-started.md +++ b/src/site/markdown/getting-started.md @@ -29,17 +29,19 @@ copilot --version ## Step 1: Install the SDK -> If you want to test a _-SNAPSHOT_ version, you may have to clone the project's repository and install the library locally with _mvn install_. +Preview documentation can use a rolling `-SNAPSHOT` artifact version. Multiple previews of the same base SDK version update that coordinate, so an older preview's documentation directory does not guarantee an exact historical preview build. ### Apache Maven Add the dependency to your `pom.xml`: + + ```xml com.github copilot-sdk-java - ${project.version} + ${artifact.version} ``` @@ -47,8 +49,10 @@ Add the dependency to your `pom.xml`: Add the dependency to your `build.gradle`: + + ```groovy -implementation 'com.github:copilot-sdk-java:${project.version}' +implementation 'com.github:copilot-sdk-java:${artifact.version}' ``` ### JBang (Quick Start) @@ -56,7 +60,8 @@ implementation 'com.github:copilot-sdk-java:${project.version}' For the fastest way to try the SDK without setting up a project, use [JBang](https://www.jbang.dev/). Create a file named `HelloCopilot.java` with the following header, and then proceed to Step 2 by appending the proposed content into this same file. ```bash -//DEPS com.github:copilot-sdk-java:${project.version} +//ARTIFACT_REPOSITORY +//DEPS com.github:copilot-sdk-java:${artifact.version} ``` ## Step 2: Send Your First Message diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 7819c5f05e..45a4e33bf8 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -15,22 +15,26 @@ Welcome to the documentation for the **GitHub Copilot SDK for Java** — a Java Add the dependency to your project: -> **Note:** If this is a `-SNAPSHOT` version, clone the project repository and run `./mvnw install` locally first so the artifact is available in your local Maven cache. Otherwise, the version is available on Maven Central. +Preview documentation can use a rolling `-SNAPSHOT` artifact version. Multiple previews of the same base SDK version update that coordinate, so an older preview's documentation directory does not guarantee an exact historical preview build. **Maven:** + + ```xml com.github copilot-sdk-java - ${project.version} + ${artifact.version} ``` **Gradle:** + + ```groovy -implementation 'com.github:copilot-sdk-java:${project.version}' +implementation 'com.github:copilot-sdk-java:${artifact.version}' ``` ### Quick Example @@ -86,7 +90,8 @@ You can quickly try the SDK without setting up a full project using [JBang](http # Create a simple script cat > hello-copilot.java << 'EOF' -//DEPS com.github:copilot-sdk-java:${project.version} +//ARTIFACT_REPOSITORY +//DEPS com.github:copilot-sdk-java:${artifact.version} import com.github.copilot.CopilotClient; import com.github.copilot.generated.AssistantMessageEvent; import com.github.copilot.generated.SessionIdleEvent; From e009fcc6b4f45c0eeaa6c2db12bc700fddbd19e1 Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Tue, 3 Nov 2026 18:44:34 -0500 Subject: [PATCH 2/4] Docs: address rolling snapshot review Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a93f06c-3318-405d-ad86-fcf729e58207 --- .github/workflows/deploy-site.yml | 8 +++++--- scripts/prepare-site-versions.mjs | 7 +++++++ scripts/prepare-site-versions.test.mjs | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml index 17a06bd449..4ebb3905d1 100644 --- a/.github/workflows/deploy-site.yml +++ b/.github/workflows/deploy-site.yml @@ -87,11 +87,13 @@ jobs: # 5. Prepare Java artifact versions and snapshot repository instructions - name: Prepare site artifact versions + env: + VERSION: ${{ inputs.version }} + ARTIFACT_VERSION_INPUT: ${{ inputs.artifact_version }} run: | - VERSION="${{ inputs.version }}" - ARTIFACT_VERSION="${{ inputs.artifact_version }}" + ARTIFACT_VERSION="${ARTIFACT_VERSION_INPUT}" if [[ -z "${ARTIFACT_VERSION}" ]]; then - if [[ "${{ inputs.publish_as_latest }}" == "false" ]]; then + if [[ "${VERSION}" == *-* ]]; then echo "::error::artifact_version is required for preview documentation" exit 1 fi diff --git a/scripts/prepare-site-versions.mjs b/scripts/prepare-site-versions.mjs index aaf5ebb148..7e78127055 100644 --- a/scripts/prepare-site-versions.mjs +++ b/scripts/prepare-site-versions.mjs @@ -87,6 +87,13 @@ repositories { return `copilot-sdk-java:${artifactVersion}`; } ); + if (snapshot) { + const dependency = `//DEPS com.github:copilot-sdk-java:${artifactVersion}`; + content = content.replaceAll( + dependency, + `//REPOS central,central-snapshots=${SNAPSHOT_REPOSITORY}\n${dependency}` + ); + } for (const [marker, replacement] of replacements) { const count = content.split(marker).length - 1; markerCounts.set(marker, markerCounts.get(marker) + count); diff --git a/scripts/prepare-site-versions.test.mjs b/scripts/prepare-site-versions.test.mjs index 860aa4dc81..5a4eb5c918 100644 --- a/scripts/prepare-site-versions.test.mjs +++ b/scripts/prepare-site-versions.test.mjs @@ -28,6 +28,18 @@ test("renders preview dependency coordinates and snapshot repositories", (t) => ); const cookbook = readFileSync(join(markdown, "cookbook", "managing-local-files.md"), "utf8"); assert.match(cookbook, /copilot-sdk-java:1\.0\.15-SNAPSHOT/); + for (const match of cookbook.matchAll(/\/\/DEPS com\.github:copilot-sdk-java:1\.0\.15-SNAPSHOT/g)) { + assert.equal( + cookbook.slice(0, match.index).trimEnd().split("\n").at(-1), + "//REPOS central,central-snapshots=https://central.sonatype.com/repository/maven-snapshots/" + ); + } + + const cookbookContent = readFileSync(join(markdown, "cookbook", "error-handling.md"), "utf8"); + assert.equal( + cookbookContent.match(/\/\/REPOS central,central-snapshots=/g)?.length, + cookbookContent.match(/\/\/DEPS com\.github:copilot-sdk-java:1\.0\.15-SNAPSHOT/g)?.length + ); }); test("keeps stable dependency rendering free of snapshot configuration", (t) => { @@ -48,3 +60,15 @@ test("rejects an artifact version from another shared base", (t) => { /site version's base/ ); }); + +test("passes artifact inputs through the workflow environment and detects previews by version", () => { + const workflow = readFileSync(resolve(".github/workflows/deploy-site.yml"), "utf8"); + const prepareStep = workflow.slice( + workflow.indexOf("- name: Prepare site artifact versions"), + workflow.indexOf("# 6. Build the Maven Site") + ); + assert.match(prepareStep, /ARTIFACT_VERSION_INPUT: \$\{\{ inputs\.artifact_version \}\}/); + assert.doesNotMatch(prepareStep.match(/run: \|([\s\S]*)/)?.[1] ?? "", /inputs\.artifact_version/); + assert.match(prepareStep, /if \[\[ "\$\{VERSION\}" == \*-\* \]\]/); + assert.doesNotMatch(prepareStep, /inputs\.publish_as_latest/); +}); From 7f263f9ff97184c2f2abbe885e7f48a99f1e0d0a Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Tue, 3 Nov 2026 18:51:52 -0500 Subject: [PATCH 3/4] CI: refresh license compliance evaluation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a93f06c-3318-405d-ad86-fcf729e58207 From e5823d2987136557b478498047c9d1dfff1926af Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Tue, 3 Nov 2026 18:59:00 -0500 Subject: [PATCH 4/4] Docs: clarify rolling snapshot property Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a93f06c-3318-405d-ad86-fcf729e58207 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 55410049ba..cd234fd0c5 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ UTF-8 0.0.0-SNAPSHOT - + ${site.version} ${project.basedir}/monorepo/java