ci(cli): add CI pipelines for Node and Python CLI SDKs (#4640)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Saket Aryan
2026-03-31 22:30:31 +05:30
committed by GitHub
parent 9bebcf45f7
commit 32c1ccba5b
30 changed files with 3042 additions and 2457 deletions
+28 -3
View File
@@ -8,11 +8,19 @@ boundaries).
from __future__ import annotations
import os
import re
import subprocess
import sys
import pytest
_ANSI_RE = re.compile(r"\x1b\[[0-9;]*[mKJHABCDfsu]")
def _strip_ansi(text: str) -> str:
"""Remove ANSI escape codes so substring checks work regardless of color mode."""
return _ANSI_RE.sub("", text)
def _run(
args: list[str],
@@ -28,22 +36,35 @@ def _run(
reads config from ``<home_dir>/.mem0/config.json`` instead
of the user's real config. This is critical for tests that
depend on a clean (no API key) or custom config state.
Returns a CompletedProcess whose stdout/stderr have ANSI escape codes
stripped. GitHub Actions sets FORCE_COLOR=1 which causes Rich/Typer to
fragment option names like --user-id into separately-styled ANSI segments,
making plain ``in`` checks fail. Stripping here is version-agnostic and
ensures all assertions see the same plain text regardless of terminal env.
"""
env = os.environ.copy()
# Strip all MEM0_ env vars so tests start clean
for key in list(env.keys()):
if key.startswith("MEM0_"):
del env[key]
env.pop("FORCE_COLOR", None)
if home_dir:
env["HOME"] = home_dir
if env_override:
env.update(env_override)
return subprocess.run(
result = subprocess.run(
[sys.executable, "-m", "mem0_cli", *args],
capture_output=True,
text=True,
env=env,
)
return subprocess.CompletedProcess(
args=result.args,
returncode=result.returncode,
stdout=_strip_ansi(result.stdout),
stderr=_strip_ansi(result.stderr),
)
@pytest.fixture
@@ -67,7 +88,6 @@ class TestCLIIntegration:
assert result.returncode == 0
assert "0.1.0" in result.stdout
def test_add_help(self):
result = _run(["add", "--help"])
assert result.returncode == 0
@@ -161,7 +181,12 @@ class TestCLIIsolated:
)
assert result.returncode != 0
combined = result.stderr + result.stdout
assert "memory ID" in combined.lower() or "--all" in combined or "--entity" in combined or "Error" in combined
assert (
"memory ID" in combined.lower()
or "--all" in combined
or "--entity" in combined
or "Error" in combined
)
def test_config_show_clean(self, clean_home):
"""config show with no config should still work."""