fix: correct Copilot CLI config surface and default to stable channel - #77
Merged
Conversation
The action wrote user settings to ~/.copilot/config.json, which the CLI documents as managed state (loggedInUsers, installedPlugins). Clobbering it destroys auth state on persistent/self-hosted runners. User-editable settings belong in settings.json, so write there and merge instead of overwrite. The default copilot-config also carried two values the current CLI schema rejects: "theme": "auto" is not in the theme enum, and trustedFolders is not a recognized key (directory trust is handled by --add-dir, which the action already passes). Defaulting copilot-version to `prerelease` shipped bleeding-edge CLI builds to every consumer. Default to `latest` and keep drift detection via a dedicated nightly prerelease-drift job. Also bumps actions/upload-artifact v4 -> v7; v4 targets Node 20, which is deprecated and already force-migrated to Node 24 by the runner. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Aug 20, 2026
npm already resolves ranges, dist-tags, and exact versions from a single spec, so the latest/prerelease special cases were redundant. The spec is now quoted because ranges like '>=1.0.80' were being parsed as shell redirection. Default is pinned to a known-good stable version rather than floating, so a given action ref installs the same CLI every run. version-pin-drift keeps the pin honest by failing the nightly build (not PRs) once it falls behind latest. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
User settings moved out of config.json into settings.json in CLI 1.0.35 (2026-04-23). Pins below that never read settings.json, so writing there silently dropped copilot-config. Detect the resolved version and write to whichever file the CLI actually reads, stripping the // comments newer config.json files carry so jq can merge them. Invalid JSON now fails fast instead of no-opping.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes three correctness problems in how the action talks to the Copilot CLI, plus a deprecated runtime.
1. Writing user settings to the wrong file (
config.json→settings.json)The action wrote
copilot-configto~/.copilot/config.jsonand overwrote it. The CLI self-documents that file:config.jsonholds CLI-managed state —loggedInUsers,installedPlugins,firstLaunchAt. On an ephemeral GitHub-hosted runner that's harmless, but on a persistent or self-hosted runner it destroys the CLI's auth state. Per the config dir reference, user settings were moved tosettings.jsonand legacyconfig.jsonvalues are only auto-migrated on startup.Now writes
settings.jsonand merges rather than clobbers, so pre-existing runner settings survive.2. Two invalid values in the default
copilot-config"theme": "auto"autois not in the theme enum (default,github,dim,high-contrast,colorblind)"trustedFolders": []config.json, notsettings.json— so it was silently ignored there. Directory trust is handled by--add-dir, which the action already passes.Docs state invalid values are ignored and surfaced as config problems. Both removed;
bannerandrenderMarkdownare verified-valid and stay.3.
copilot-versiondefaulted toprereleaseEvery consumer of this action was installing bleeding-edge CLI builds (currently
1.0.81-5) instead of stable (1.0.80). One bad prerelease broke every downstream repo.Default is now
latest. Drift detection is not lost — a dedicatedprerelease-driftjob in the nightly matrix pinscopilot-version: prerelease, so a breaking CLI release still gets caught here first, before it reaches consumers.4.
actions/upload-artifact@v4→v7v4 targets Node 20. Every run currently logs:
Reviewed v5/v6/v7 release notes — no breaking change for this usage (
archivedefaults to the old zip behavior; multi-path +if-no-files-foundunchanged). v6+ needs runner ≥ 2.327.1; hosted runners are on 2.336.0. Supersedes #66.Testing
configtest job rewritten: it previously passedrender_markdown,theme: "dark", andtrusted_folders— all invalid keys/values that asserted nothing. It now seeds a pre-existing setting, then asserts the action's config was merged in and the pre-existing key survived.bash -n+shellcheckclean on the embedded script; YAML parses.Verified against Copilot CLI
1.0.80and the live docs. Separately confirmed all 44 flags the action passes still exist in the current CLI — no flag drift.Follow-up: version spec input + the
settings.jsoncutoverTwo more fixes landed on this branch after review.
copilot-versionnow takes a version specIt defaulted to
latest, so every CLI release shipped straight into everyone'sworkflows unreviewed. It now defaults to a pinned
1.0.80and accepts any npmspec —
1.0.80,1.x,>=1.0.80,latest,prerelease— matching thenode-versionconvention fromactions/setup-node.This also fixed a latent bug: the install ran
npm install -g @github/copilot@$COPILOT_VERSIONunquoted, so a range like
>=1.0.80was parsed as shell redirection andcreated a file named
=1.0.80instead of installing anything. Theversion-specjob is the regression test.
version-pin-driftfails only on the nightly schedule when the pinneddefault falls behind
latest, so PRs aren't blocked every time the CLI shipsbut the pin can't silently rot either.
copilot-configwas silently dropped on older CLIsUser settings moved out of
config.jsonintosettings.jsonin CLI 1.0.35(2026-04-23). Writing to
settings.jsonunconditionally meant anyone pinningbelow that got their
copilot-configsilently ignored. The action nowresolves the installed version and writes to whichever file that CLI actually
reads, warning when it takes the legacy path.
Newer
config.jsonfiles also open with//comments, whichjqcannot parse,so the legacy path strips them before merging. Invalid
copilot-configJSON nowfails fast instead of no-opping.
New jobs:
config-legacy(pins1.0.34, assertsconfig.json) andconfig-invalid(asserts the action rejects malformed JSON).