diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 9291a3e..075fc61 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -26,6 +26,8 @@ jobs: run: | pip install pytest python -m pytest tests/test_validate_integrations.py -q + - name: Test composite action dependency paths + run: python -m pytest tests/test_composite_action_paths.py -q - name: Test conditional schema rules run: | pip install pytest diff --git a/copilot/action.yml b/copilot/action.yml index 0f970a6..9849337 100644 --- a/copilot/action.yml +++ b/copilot/action.yml @@ -39,10 +39,10 @@ runs: using: composite steps: # The engine imports agentrust-capture-core, which has no dependencies of its - # own, so this stays one small install rather than a tree. Pinned to a minor - # range so a core release cannot silently change what this check measures. + # own, so this stays one small install rather than a tree. The core ships in + # this action checkout, binding it to the same referenced revision. - shell: bash - run: pip install --quiet "$GITHUB_WORKSPACE/packages/agentrust-capture-core" + run: pip install --quiet "${{ github.action_path }}/../packages/agentrust-capture-core" - id: check shell: bash diff --git a/cursor/action.yml b/cursor/action.yml index 80f9611..b0bc4df 100644 --- a/cursor/action.yml +++ b/cursor/action.yml @@ -39,7 +39,7 @@ runs: using: composite steps: - shell: bash - run: pip install --quiet "$GITHUB_WORKSPACE/packages/agentrust-capture-core" + run: pip install --quiet "${{ github.action_path }}/../packages/agentrust-capture-core" - id: check shell: bash diff --git a/gemini-cli/action.yml b/gemini-cli/action.yml index c0d56ab..66f1fc1 100644 --- a/gemini-cli/action.yml +++ b/gemini-cli/action.yml @@ -39,7 +39,7 @@ runs: using: composite steps: - shell: bash - run: pip install --quiet "$GITHUB_WORKSPACE/packages/agentrust-capture-core" + run: pip install --quiet "${{ github.action_path }}/../packages/agentrust-capture-core" - id: check shell: bash diff --git a/tests/test_composite_action_paths.py b/tests/test_composite_action_paths.py new file mode 100644 index 0000000..ba77d5f --- /dev/null +++ b/tests/test_composite_action_paths.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +import shlex +import shutil +from pathlib import Path + +import pytest +import yaml + + +REPOSITORY_ROOT = Path(__file__).resolve().parent.parent +ACTION_NAMES = ("copilot", "cursor", "gemini-cli", "windsurf") +CAPTURE_CORE = Path("packages/agentrust-capture-core") + + +@pytest.mark.parametrize("action_name", ACTION_NAMES) +def test_capture_core_is_resolved_from_the_action_checkout( + action_name: str, tmp_path: Path +) -> None: + """A reusable action must not resolve its code from the caller's checkout.""" + action_store = tmp_path / "_actions" / "agentrust-io" / "integrations" / "ref" + action_path = action_store / action_name + consumer_workspace = tmp_path / "consumer" + action_core = action_store / CAPTURE_CORE + consumer_core = consumer_workspace / CAPTURE_CORE + + # Model a remote action checkout and the consumer repository as separate + # trees. A local ``uses: ./`` smoke test puts both under + # GITHUB_WORKSPACE and therefore cannot catch this boundary error. + action_path.mkdir(parents=True) + shutil.copytree(REPOSITORY_ROOT / CAPTURE_CORE, action_core) + consumer_core.mkdir(parents=True) + + document = yaml.safe_load( + (REPOSITORY_ROOT / action_name / "action.yml").read_text(encoding="utf-8") + ) + install_commands = [ + step["run"] + for step in document["runs"]["steps"] + if "agentrust-capture-core" in step.get("run", "") + ] + + assert len(install_commands) == 1 + command = install_commands[0] + assert "$GITHUB_WORKSPACE" not in command + + rendered = command.replace("${{ github.action_path }}", str(action_path)) + arguments = shlex.split(rendered) + + assert arguments[:3] == ["pip", "install", "--quiet"] + assert len(arguments) == 4 + resolved_core = Path(arguments[3]).resolve() + assert resolved_core == action_core.resolve() + assert resolved_core != consumer_core.resolve() + assert (resolved_core / "pyproject.toml").is_file() diff --git a/windsurf/action.yml b/windsurf/action.yml index b6ed9e8..888ec6e 100644 --- a/windsurf/action.yml +++ b/windsurf/action.yml @@ -38,7 +38,7 @@ runs: using: composite steps: - shell: bash - run: pip install --quiet "$GITHUB_WORKSPACE/packages/agentrust-capture-core" + run: pip install --quiet "${{ github.action_path }}/../packages/agentrust-capture-core" - id: check shell: bash