Skip to content

Edburns/dd 2984436 make copilot cli versions consistent#137

Merged
edburns merged 4 commits intomainfrom
edburns/dd-2984436-make-copilot-cli-versions-consistent
Apr 30, 2026
Merged

Edburns/dd 2984436 make copilot cli versions consistent#137
edburns merged 4 commits intomainfrom
edburns/dd-2984436-make-copilot-cli-versions-consistent

Conversation

@edburns
Copy link
Copy Markdown
Collaborator

@edburns edburns commented Apr 30, 2026

This PR makes it so all the places that need to invoke Copilot CLI in the process of running tests or dealing with agentic workflows, use the same Copilot CLI installation, and therefore Copilot CLI version, as defined in the @github/copilot corresponding to the commit has in .lastmerge. This version number is also written to the POM as the value of the property readonly-copilot-sdk-ref-impl-version-from-lastmerge-file-updated-by-weekly-reference-impl-sync .

pom.xml (+70 / -0)

Four additions that together make pom.xml the single source of truth for the Copilot CLI version and make mvn clean verify self-contained:

  1. New property <readonly-copilot-sdk-ref-impl-version-from-lastmerge-file-updated-by-weekly-reference-impl-sync> = ^1.0.36-0. Mirrors dependencies."@github/copilot" in the cloned reference impl's nodejs/package.json. Long doc-comment marks it auto-managed (by the new sync script) and warns against manual edits.
  2. New property <copilot.cli.path> = ${copilot.sdk.clone.dir}/nodejs/node_modules/@github/copilot/index.js. Doc-comment shows the override syntax (-Dcopilot.cli.path=...).
  3. New exec-maven-plugin execution install-nodejs-cli-dependencies bound to generate-test-resources. Runs npm ci --ignore-scripts in ${copilot.sdk.clone.dir}/nodejs/, honors ${skip.test.harness}. Re-creates target/copilot-sdk/nodejs/node_modules after clean wipes it.
  4. maven-surefire-plugin configuration gains <environmentVariables><COPILOT_CLI_PATH>${copilot.cli.path}</…></…>, so the forked test JVM uses the pinned CLI with no manual env-var export.

.github/actions/setup-copilot/action.yml (+24 / -1)

Replaces the unpinned npm install -g @github/copilot with a two-step pinned install:

  1. New step Read pinned @github/copilot version from pom.xml (id: cli-version) extracts the pinned version with sed. Fails fast if the property is unset or still the PRIMER_TO_REPLACE placeholder.
  2. Install Copilot CLI (pinned to pom.xml version) runs npm install -g "@github/copilot@${CLI_VERSION}".

Adds new action output cli-version exposing the resolved version.


.github/scripts/reference-impl-sync/sync-cli-version-from-reference-impl.sh (new, +80)

New script that keeps the pinned CLI version in pom.xml in lockstep with the reference impl pinned in .lastmerge:

  • Reads dependencies."@github/copilot" from the reference impl's nodejs/package.json via node.
  • Locates the repo root by walking up from the script's own location until it finds a pom.xml — resilient to relocation, works from any CWD.
  • Rewrites the <readonly-…> property in pom.xml in place using portable sed.
  • Validates the property exists and a version was extractable; fails fast otherwise.
  • Usage: takes the reference-impl directory as $1 or via REFERENCE_IMPL_DIR env var.

.github/scripts/reference-impl-sync/merge-reference-impl-finish.sh (+12 / -2)

Wires the new sync script into the reference-impl merge flow:

  • After writing .lastmerge, invokes sync-cli-version-from-reference-impl.sh against the cloned reference impl directory.
  • Stages pom.xml alongside .lastmerge in the same commit so the two values always move together.
  • Updated header comment to reflect the new step (the numbered flow is now 5 steps instead of 4).

CONTRIBUTING.md (+18 / -2 net)

Reworks the "Running tests and linters" section:

  • Renamed to "Running locally, including tests and linters".
  • Removed the suggestion to run mvn generate-test-resources + npm ci + manual COPILOT_CLI_PATH export — pom.xml now handles all of that automatically.
  • Replaced with a single sentence: the POM ensures a known-correct CLI installation; contributors can override with the copilot.cli.path Maven property.
  • Added a new section "Running the known correct Copilot CLI installation" with self-contained POSIX and PowerShell snippets that locate COPILOT_CLI_PATH (scoped to */nodejs/node_modules/... so the older harness copy under target/copilot-sdk/test/harness/node_modules/ can never be selected) and invoke it via node.

.gitignore (+1)

Minor housekeeping: added *.sln (Visual Studio solution files generated when the workspace is opened in VS).

edburns added 2 commits April 29, 2026 16:34
Previously, three different code paths determined the Copilot CLI version
inconsistently:

- Path A (build-test.yml) installed the CLI from the cloned reference impl
  pinned by .lastmerge — reproducible.
- Path B (run-smoke-test.yml, update-copilot-dependency.yml via the
  setup-copilot action) ran `npm install -g @github/copilot` with no
  version pin — floated to whatever was latest on npm.
- Path C (local dev) fell through to whatever `copilot` was on PATH
  (often whatever VS Code Insiders had installed).

When the CLI protocol vocabulary changed between 1.0.35 and 1.0.39, this
inconsistency made it hard to land reference-impl merges that required a
specific CLI version.

This change makes pom.xml the single source of truth for the
@github/copilot version that all paths must use, while keeping .lastmerge
as the source of truth for the reference implementation commit.

Changes:

- pom.xml: replace the PRIMER_TO_REPLACE placeholder in the property
  <readonly-copilot-sdk-ref-impl-version-from-lastmerge-file-updated-by-weekly-reference-impl-sync>
  with the current value (^1.0.36-0) extracted from the cloned
  reference impl's nodejs/package.json. Add a doc-comment explaining
  that the property is auto-managed and is the canonical CLI version
  for all CI paths.

- .github/scripts/reference-impl-sync/sync-cli-version-from-reference-impl.sh
  (new): reads dependencies."@github/copilot" from the reference impl's
  nodejs/package.json (via node) and rewrites the pom.xml property in
  place. Locates the repo root by walking up from the script's own
  location until it finds a pom.xml, so it is resilient to relocation
  and works from any CWD. Uses portable sed for the rewrite.

- .github/scripts/reference-impl-sync/merge-reference-impl-finish.sh:
  call the new sync script right after writing .lastmerge, and stage
  pom.xml alongside .lastmerge in the same commit. .lastmerge and the
  CLI version property now always move together.

- .github/actions/setup-copilot/action.yml: read the pinned version from
  pom.xml using sed and run `npm install -g "@github/copilot@VERSION"`
  instead of installing the latest. Fail fast if the property is unset
  or still the primer. Expose the resolved version as an action output.

- CONTRIBUTING.md: document the local-dev workflow that mirrors what
  build-test.yml does in CI. The cloned reference impl contains two
  separate package.json files that both pin @github/copilot:

    * target/copilot-sdk/nodejs/package.json (^1.0.36-0) — the SDK-test
      pin; this is the CLI the tests must run against.
    * target/copilot-sdk/test/harness/package.json (^1.0.32) — the
      replay-harness pin; incidental, NOT the CLI under test.

  `mvn generate-test-resources` runs `npm install` only in the harness
  subtree, so a generic `find target -path '*/@github/copilot/index.js'`
  picks the wrong (older) copy. The instructions now:
    1. Run `npm ci` in target/copilot-sdk/nodejs/ explicitly.
    2. Scope the COPILOT_CLI_PATH lookup to '*/nodejs/node_modules/...'
       so the harness copy can never be selected, even if both are
       present. Both POSIX (find) and PowerShell (Get-ChildItem) forms
       are tightened.

- .gitignore: minor housekeeping.

Verified mvn clean package -Pskip-test-harness -DskipTests succeeds with
the new POM, the sync script correctly rewrites the property when invoked
from any CWD, and the tightened CONTRIBUTING.md sequence resolves
COPILOT_CLI_PATH to the 1.0.36-0 CLI under target/copilot-sdk/nodejs.
modified:   CONTRIBUTING.md

- Simplify this after realizing the POM can handle the `npm ci`.

modified:   pom.xml

- Ensure the COPILOT_CLI_PATH is set to the built-in Copilot CLI instance. This ensures a user's local Copilot instance, which is not guaranteed to be the correct version, and thus the correct RPC protocol, will get in the way.
@edburns edburns marked this pull request as ready for review April 30, 2026 01:10
Copilot AI review requested due to automatic review settings April 30, 2026 01:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR centralizes how the repo installs and locates the Copilot CLI so local mvn clean verify, CI workflows, and the reference-impl sync flow all converge on a single configured CLI source/version.

Changes:

  • Add Maven properties + Surefire env injection so tests use a configured COPILOT_CLI_PATH, and add a Maven execution to npm ci the reference-impl nodejs/ dependencies.
  • Add scripts to sync the pinned @github/copilot version into pom.xml during reference-impl merges, and wire that into the merge finish script.
  • Update the setup-copilot composite action and CONTRIBUTING docs to use the pinned version/path.
Show a summary per file
File Description
pom.xml Defines CLI path + “pinned” CLI version property; installs CLI deps via npm ci; injects COPILOT_CLI_PATH into test JVM.
.github/actions/setup-copilot/action.yml Reads the pinned version from pom.xml and installs that CLI globally; exposes the resolved version as an output.
.github/scripts/reference-impl-sync/sync-cli-version-from-reference-impl.sh New helper to sync @github/copilot version from the reference implementation into pom.xml.
.github/scripts/reference-impl-sync/merge-reference-impl-finish.sh Calls the new sync script and stages pom.xml alongside .lastmerge.
CONTRIBUTING.md Updates local run instructions and adds snippets for running the known-correct CLI.
.gitignore Ignores *.sln.

Copilot's findings

Comments suppressed due to low confidence (1)

CONTRIBUTING.md:72

  • Similarly, the PowerShell example should quote the path when invoking node (e.g., node "$env:COPILOT_CLI_PATH") so it works when the repo path contains spaces.
$env:COPILOT_CLI_PATH = (Get-ChildItem -Path "$PWD\target" -Recurse -Filter 'index.js' -File | Where-Object { $_.FullName -match '[\\/]nodejs[\\/]node_modules[\\/]@github[\\/]copilot[\\/]index\.js$' } | Select-Object -First 1 -ExpandProperty FullName)
node $env:COPILOT_CLI_PATH
  • Files reviewed: 5/6 changed files
  • Comments generated: 8

Comment thread .github/scripts/reference-impl-sync/sync-cli-version-from-reference-impl.sh Outdated
Comment thread CONTRIBUTING.md
Comment thread .github/actions/setup-copilot/action.yml Outdated
Comment thread .github/actions/setup-copilot/action.yml
Comment thread .github/scripts/reference-impl-sync/merge-reference-impl-finish.sh Outdated
Comment thread pom.xml
Comment thread pom.xml
Address review comment on PR #137 (discussion_r3165129538): the
install-nodejs-cli-dependencies execution previously ran on every
invocation of generate-test-resources because it was only guarded by
${skip.test.harness}. That made non-test builds (e.g. mvn package
-DskipTests, mvn deploy -Dmaven.test.skip=true) require npm and
network access unnecessarily.

Introduce a new ${skip.cli.install} property that defaults to
${skip.test.harness} but is forced to true when -DskipTests=true or
-Dmaven.test.skip=true is set, via two auto-activated profiles. Wire
the install-nodejs-cli-dependencies execution's <skip> to this new
property.
@edburns edburns merged commit bd072c9 into main Apr 30, 2026
10 checks passed
@edburns edburns deleted the edburns/dd-2984436-make-copilot-cli-versions-consistent branch April 30, 2026 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants