From d982c2f67f1212304c235b44f139edc534599442 Mon Sep 17 00:00:00 2001 From: WOLIKIMCHENG <35391914+WOLIKIMCHENG@users.noreply.github.com> Date: Thu, 2 Jul 2026 00:35:53 +0800 Subject: [PATCH] feat(copilot): warn before skills default rollout (#3256) * feat(copilot): default to skills mode * feat(copilot): warn before skills default rollout * Make Copilot skills warning test less brittle --------- Co-authored-by: root --- .../integrations/copilot/__init__.py | 13 ++++ .../integrations/test_integration_copilot.py | 72 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/specify_cli/integrations/copilot/__init__.py b/src/specify_cli/integrations/copilot/__init__.py index 5cc34d2b1..747b7e9ca 100644 --- a/src/specify_cli/integrations/copilot/__init__.py +++ b/src/specify_cli/integrations/copilot/__init__.py @@ -57,6 +57,17 @@ def _allow_all() -> bool: return True +def _warn_legacy_markdown_default() -> None: + """Warn that Copilot's default markdown scaffold is being phased out.""" + warnings.warn( + "Copilot legacy markdown mode is deprecated and will stop being the " + 'default in a future Spec Kit release; pass --integration-options "--skills" ' + "to opt in to Copilot skills mode now.", + UserWarning, + stacklevel=3, + ) + + class _CopilotSkillsHelper(SkillsIntegration): """Internal helper used when Copilot is scaffolded in skills mode. @@ -316,6 +327,8 @@ class CopilotIntegration(IntegrationBase): self._skills_mode = bool(parsed_options.get("skills")) if self._skills_mode: return self._setup_skills(project_root, manifest, parsed_options, **opts) + if "skills" not in parsed_options: + _warn_legacy_markdown_default() return self._setup_default(project_root, manifest, parsed_options, **opts) def _setup_default( diff --git a/tests/integrations/test_integration_copilot.py b/tests/integrations/test_integration_copilot.py index 8a7c8ec99..41261ba1c 100644 --- a/tests/integrations/test_integration_copilot.py +++ b/tests/integrations/test_integration_copilot.py @@ -2,7 +2,9 @@ import json import os +import warnings +import pytest import yaml from specify_cli.integrations import get_integration @@ -34,6 +36,31 @@ class TestCopilotIntegration: assert f.parent == tmp_path / ".github" / "agents" assert f.name.endswith(".agent.md") + def test_setup_warns_legacy_markdown_default_is_deprecated(self, tmp_path): + from specify_cli.integrations.copilot import CopilotIntegration + copilot = CopilotIntegration() + m = IntegrationManifest("copilot", tmp_path) + + with pytest.warns(UserWarning, match="Copilot legacy markdown mode is deprecated"): + created = copilot.setup(tmp_path, m) + + assert any(f.name.endswith(".agent.md") for f in created) + + def test_skills_setup_does_not_warn_about_legacy_default(self, tmp_path): + from specify_cli.integrations.copilot import CopilotIntegration + copilot = CopilotIntegration() + m = IntegrationManifest("copilot", tmp_path) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + created = copilot.setup(tmp_path, m, parsed_options={"skills": True}) + + assert not any( + "Copilot legacy markdown mode is deprecated" in str(item.message) + for item in caught + ) + assert any(f.name == "SKILL.md" for f in created) + def test_setup_creates_companion_prompts(self, tmp_path): from specify_cli.integrations.copilot import CopilotIntegration copilot = CopilotIntegration() @@ -295,6 +322,51 @@ class TestCopilotIntegration: f"Extra: {sorted(set(actual) - set(expected))}" ) + def test_default_cli_init_warns_legacy_markdown_is_deprecated(self, tmp_path): + """Default Copilot init should warn users about the future skills default.""" + from typer.testing import CliRunner + from specify_cli import app + project = tmp_path / "default-warning" + project.mkdir() + old_cwd = os.getcwd() + try: + os.chdir(project) + with pytest.warns( + UserWarning, + match="Copilot legacy markdown mode is deprecated", + ): + result = CliRunner().invoke(app, [ + "init", "--here", "--integration", "copilot", "--script", "sh", + ], catch_exceptions=False) + finally: + os.chdir(old_cwd) + + assert result.exit_code == 0, result.output + + def test_skills_cli_init_does_not_warn_about_legacy_markdown(self, tmp_path): + """Explicit Copilot skills mode should not warn about the legacy default.""" + from typer.testing import CliRunner + from specify_cli import app + project = tmp_path / "skills-no-warning" + project.mkdir() + old_cwd = os.getcwd() + try: + os.chdir(project) + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + result = CliRunner().invoke(app, [ + "init", "--here", "--integration", "copilot", + "--integration-options", "--skills", "--script", "sh", + ], catch_exceptions=False) + finally: + os.chdir(old_cwd) + + assert result.exit_code == 0, result.output + assert not any( + "Copilot legacy markdown mode is deprecated" in str(item.message) + for item in caught + ) + class TestCopilotSkillsMode: """Tests for Copilot integration in --skills mode."""