Skip to content

Commit 2464f73

Browse files
GeneAIclaude
authored andcommitted
feat: Add platform compatibility CI integrations
Add three integration points for the cross-platform compatibility checker: 1. GitHub Actions (tests.yml): - New `platform-compat` job that runs on every push/PR - Generates JSON report as artifact - Currently non-blocking (warns but doesn't fail) - Change `continue-on-error: false` to make it blocking 2. Pre-commit hook (.pre-commit-config.yaml): - Manual stage: `pre-commit run platform-compat` - Change to `stages: [commit]` to run on every commit - Checks src/, empathy_llm_toolkit/, empathy_software_plugin/, coach_wizards/ 3. Pytest integration (test_platform_compat_ci.py): - Runs as part of normal test suite - Tests for critical platform issues - Verifies platform_utils module is importable and functional Usage: # Manual pre-commit check pre-commit run platform-compat # Run pytest integration pytest tests/test_platform_compat_ci.py -v # Direct script usage python scripts/check_platform_compat.py src/ --fix 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent f0b62ce commit 2464f73

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

.github/workflows/tests.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,36 @@ jobs:
7676
- name: Security scan with Bandit
7777
run: bandit -c .bandit -r src/ empathy_llm_toolkit/ coach_wizards/ empathy_software_plugin/ --severity-level medium --confidence-level medium
7878

79+
platform-compat:
80+
runs-on: ubuntu-latest
81+
steps:
82+
- uses: actions/checkout@v4
83+
84+
- name: Set up Python
85+
uses: actions/setup-python@v5
86+
with:
87+
python-version: '3.11'
88+
89+
- name: Check cross-platform compatibility
90+
id: compat
91+
run: |
92+
python scripts/check_platform_compat.py src/ --json > compat-report.json
93+
python scripts/check_platform_compat.py src/ --fix
94+
95+
- name: Upload compatibility report
96+
uses: actions/upload-artifact@v4
97+
with:
98+
name: platform-compat-report
99+
path: compat-report.json
100+
101+
- name: Fail on errors (non-blocking for now)
102+
run: |
103+
ERRORS=$(python -c "import json; r=json.load(open('compat-report.json')); print(r['summary']['errors'])")
104+
if [ "$ERRORS" -gt 0 ]; then
105+
echo "::warning::Found $ERRORS cross-platform compatibility errors"
106+
fi
107+
continue-on-error: true
108+
79109
code-quality:
80110
runs-on: ubuntu-latest
81111
steps:

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,13 @@ repos:
106106
pass_filenames: false
107107
stages: [manual] # Run manually with: pre-commit run pattern-review
108108
# Change to 'stages: [commit]' to run automatically on every commit
109+
110+
# Cross-platform compatibility check
111+
# Detects hardcoded paths, missing encoding, asyncio issues
112+
- id: platform-compat
113+
name: Cross-Platform Compatibility Check
114+
entry: python scripts/check_platform_compat.py src/ empathy_llm_toolkit/ empathy_software_plugin/ coach_wizards/
115+
language: python
116+
pass_filenames: false
117+
stages: [manual] # Run manually with: pre-commit run platform-compat
118+
# Change to 'stages: [commit]' to run automatically on every commit

tests/test_platform_compat_ci.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
"""
2+
CI integration test for cross-platform compatibility.
3+
4+
Runs the platform compatibility checker as part of pytest to catch
5+
cross-platform issues during regular test runs.
6+
7+
Copyright 2025 Smart-AI-Memory
8+
Licensed under Fair Source License 0.9
9+
"""
10+
11+
import subprocess
12+
import sys
13+
from pathlib import Path
14+
15+
import pytest
16+
17+
18+
class TestPlatformCompatibility:
19+
"""Tests for cross-platform compatibility in the codebase."""
20+
21+
@pytest.fixture
22+
def project_root(self) -> Path:
23+
"""Get the project root directory."""
24+
return Path(__file__).parent.parent
25+
26+
def test_no_critical_platform_issues(self, project_root: Path):
27+
"""Ensure no critical cross-platform errors in src/ directory."""
28+
script = project_root / "scripts" / "check_platform_compat.py"
29+
30+
if not script.exists():
31+
pytest.skip("Platform compatibility script not found")
32+
33+
result = subprocess.run(
34+
[sys.executable, str(script), str(project_root / "src"), "--json"],
35+
capture_output=True,
36+
text=True,
37+
cwd=str(project_root),
38+
)
39+
40+
import json
41+
42+
try:
43+
report = json.loads(result.stdout)
44+
except json.JSONDecodeError:
45+
pytest.fail(f"Failed to parse compatibility report: {result.stdout}")
46+
47+
errors = report["summary"]["errors"]
48+
assert (
49+
errors == 0
50+
), f"Found {errors} platform compatibility errors. Run: python scripts/check_platform_compat.py src/ --fix"
51+
52+
def test_platform_utils_available(self):
53+
"""Ensure platform_utils module is importable."""
54+
try:
55+
from empathy_os.platform_utils import (
56+
get_default_data_dir,
57+
get_default_log_dir,
58+
is_linux,
59+
is_macos,
60+
is_windows,
61+
setup_asyncio_policy,
62+
)
63+
64+
# Verify functions are callable
65+
assert callable(is_windows)
66+
assert callable(is_macos)
67+
assert callable(is_linux)
68+
assert callable(get_default_log_dir)
69+
assert callable(get_default_data_dir)
70+
assert callable(setup_asyncio_policy)
71+
except ImportError as e:
72+
pytest.fail(f"platform_utils module not importable: {e}")
73+
74+
def test_platform_detection_consistent(self):
75+
"""Ensure platform detection is consistent."""
76+
from empathy_os.platform_utils import is_linux, is_macos, is_windows
77+
78+
# At most one should be True
79+
platforms = [is_windows(), is_macos(), is_linux()]
80+
true_count = sum(platforms)
81+
82+
assert true_count <= 1, "Multiple platforms detected as True"
83+
84+
def test_default_directories_are_paths(self):
85+
"""Ensure directory functions return Path objects."""
86+
from empathy_os.platform_utils import (
87+
get_default_cache_dir,
88+
get_default_config_dir,
89+
get_default_data_dir,
90+
get_default_log_dir,
91+
)
92+
93+
assert isinstance(get_default_log_dir(), Path)
94+
assert isinstance(get_default_data_dir(), Path)
95+
assert isinstance(get_default_config_dir(), Path)
96+
assert isinstance(get_default_cache_dir(), Path)
97+
98+
def test_asyncio_policy_runs_without_error(self):
99+
"""Ensure asyncio policy setup doesn't raise."""
100+
from empathy_os.platform_utils import setup_asyncio_policy
101+
102+
# Should not raise on any platform
103+
setup_asyncio_policy()

0 commit comments

Comments
 (0)