Skip to content

Commit 882498e

Browse files
committed
fix(ci): Remove emoji and fix Python path issues
Fixed Unicode encoding issues: - Removed emoji characters from all scripts (caused cp950 encoding errors on Windows) - Replaced with ASCII text: [OK], [ERROR], etc. Fixed Python import issues: - Added sys.path.insert(0, ...) to config_validation.py to find core module - Fixed relative import path for scripts Fixed missing dependencies: - Added pynput to import-check job dependencies - Added pywin32 to import-check job dependencies - Kept PySide6 for GUI tests Scripts updated: - .github/scripts/syntax_check.py - Removed emoji - .github/scripts/type_check.py - Removed emoji - .github/scripts/config_validation.py - Removed emoji, fixed path - .github/workflows/ci.yml - Added pynput, pywin32 This resolves CI errors: - UnicodeEncodeError: 'charmap' codec can't encode emoji - ModuleNotFoundError: No module named 'core' - ModuleNotFoundError: No module named 'pynput'
1 parent fae0466 commit 882498e

File tree

5 files changed

+152
-12
lines changed

5 files changed

+152
-12
lines changed

.github/scripts/config_validation.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import sys
44
import os
55

6+
# Add current directory to Python path
7+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8+
69
# Suppress Qt warnings for CI
710
os.environ['QT_QPA_PLATFORM'] = 'offscreen'
811

@@ -16,19 +19,19 @@ def validate_config():
1619

1720
# Test default config
1821
config = AppConfig()
19-
print(" Default configuration created successfully")
22+
print("[OK] Default configuration created successfully")
2023

2124
# Test schema validation
2225
settings = SettingsManager()
23-
print(" Schema validation passed")
26+
print("[OK] Schema validation passed")
2427

2528
# Test config save
2629
import tempfile
2730
temp_config = tempfile.mktemp(suffix='.ini')
2831
try:
2932
settings.filename = temp_config
3033
settings.save()
31-
print(" Config save works correctly")
34+
print("[OK] Config save works correctly")
3235
finally:
3336
if os.path.exists(temp_config):
3437
os.remove(temp_config)
@@ -37,7 +40,7 @@ def validate_config():
3740
return True
3841

3942
except Exception as e:
40-
print(f" Configuration validation failed: {e}")
43+
print(f"[ERROR] Configuration validation failed: {e}")
4144
import traceback
4245
traceback.print_exc()
4346
return False

.github/scripts/monitor_ci.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/env python3
2+
"""Monitor GitHub Actions CI runs until success."""
3+
import subprocess
4+
import json
5+
import time
6+
import sys
7+
8+
def get_latest_run_id():
9+
"""Get latest Code Quality run ID."""
10+
try:
11+
result = subprocess.run(
12+
['gh', 'run', 'list', '--workflow=Code Quality', '--limit=1', '--json', 'databaseId'],
13+
capture_output=True,
14+
text=True,
15+
check=True
16+
)
17+
data = json.loads(result.stdout)
18+
if data:
19+
return data[0]['databaseId']
20+
return None
21+
except Exception as e:
22+
print(f"Error getting run ID: {e}")
23+
return None
24+
25+
def get_run_status(run_id):
26+
"""Get status of a specific run."""
27+
try:
28+
result = subprocess.run(
29+
['gh', 'run', 'view', str(run_id), '--json', 'status', 'conclusion'],
30+
capture_output=True,
31+
text=True,
32+
check=True
33+
)
34+
data = json.loads(result.stdout)
35+
return data.get('status'), data.get('conclusion')
36+
except Exception as e:
37+
print(f"Error getting run status: {e}")
38+
return None, None
39+
40+
def get_job_errors(run_id):
41+
"""Get error logs from failed jobs."""
42+
try:
43+
result = subprocess.run(
44+
['gh', 'run', 'view', str(run_id), '--log'],
45+
capture_output=True,
46+
text=True,
47+
check=True
48+
)
49+
logs = result.stdout
50+
51+
# Extract error lines
52+
errors = []
53+
for line in logs.split('\n'):
54+
if 'Error:' in line or 'Traceback' in line or 'X' in line:
55+
if 'Checkout code' not in line and 'Set up Python' not in line:
56+
errors.append(line)
57+
58+
return errors[:20] # Return first 20 errors
59+
except Exception as e:
60+
print(f"Error getting job logs: {e}")
61+
return []
62+
63+
def monitor_run(run_id, max_wait=1800):
64+
"""Monitor a run until it completes or times out."""
65+
print(f"\n{'='*60}")
66+
print(f"Monitoring Run ID: {run_id}")
67+
print(f"{'='*60}\n")
68+
69+
start_time = time.time()
70+
check_interval = 30 # Check every 30 seconds
71+
72+
while True:
73+
elapsed = time.time() - start_time
74+
if elapsed > max_wait:
75+
print(f"\nTimeout after {max_wait} seconds")
76+
return False
77+
78+
status, conclusion = get_run_status(run_id)
79+
80+
if status is None:
81+
print(f"Unable to get status, retrying...")
82+
time.sleep(check_interval)
83+
continue
84+
85+
if status == 'queued':
86+
print(f"[QUEUED] ({int(elapsed)}s elapsed)")
87+
elif status == 'in_progress':
88+
print(f"[IN PROGRESS] ({int(elapsed)}s elapsed)")
89+
elif status == 'completed':
90+
print(f"\nRun completed! Status: {status}, Conclusion: {conclusion}")
91+
92+
if conclusion == 'success':
93+
print("\n*** All CI checks passed! ***")
94+
return True
95+
else:
96+
print(f"\nRun failed with conclusion: {conclusion}")
97+
errors = get_job_errors(run_id)
98+
if errors:
99+
print("\nErrors found:")
100+
for i, error in enumerate(errors, 1):
101+
print(f"{i}. {error}")
102+
return False
103+
104+
time.sleep(check_interval)
105+
106+
if __name__ == "__main__":
107+
print("GitHub Actions CI Monitor")
108+
print("="*60)
109+
110+
# Get latest run ID
111+
run_id = get_latest_run_id()
112+
113+
if not run_id:
114+
print("Could not find any Code Quality runs")
115+
sys.exit(1)
116+
117+
# Check if run is already completed
118+
status, conclusion = get_run_status(run_id)
119+
if status == 'completed':
120+
print(f"\nLatest run ({run_id}) already completed")
121+
print(f"Status: {status}, Conclusion: {conclusion}")
122+
if conclusion == 'success':
123+
print("\nAll checks passed!")
124+
sys.exit(0)
125+
else:
126+
print("\nRun failed")
127+
errors = get_job_errors(run_id)
128+
if errors:
129+
print("\nErrors found:")
130+
for i, error in enumerate(errors, 1):
131+
print(f"{i}. {error}")
132+
sys.exit(1)
133+
134+
# Monitor the run
135+
success = monitor_run(run_id)
136+
137+
sys.exit(0 if success else 1)

.github/scripts/syntax_check.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@ def check_directory(directory):
1212
filepath = os.path.join(root, file)
1313
try:
1414
py_compile.compile(filepath, doraise=True)
15-
print(f" {filepath} - OK")
15+
print(f"[OK] {filepath}")
1616
except py_compile.PyCompileError as e:
17-
print(f" {filepath} - FAILED: {e}")
17+
print(f"[FAILED] {filepath}: {e}")
1818
return False
1919
return True
2020

2121
# Check main.py
2222
try:
2323
py_compile.compile('main.py', doraise=True)
24-
print(" main.py - OK")
24+
print("[OK] main.py")
2525
except py_compile.PyCompileError as e:
26-
print(f" main.py - FAILED: {e}")
26+
print(f"[FAILED] main.py: {e}")
2727
sys.exit(1)
2828

2929
# Check core/ directory

.github/scripts/type_check.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ def check_file(filepath):
2929
for filepath in files_to_check:
3030
ok, error = check_file(filepath)
3131
if ok:
32-
print(f" {filepath} - type hints valid")
32+
print(f"[OK] {filepath} - type hints valid")
3333
else:
34-
print(f" {filepath} - ERROR: {error}")
34+
print(f"[ERROR] {filepath}: {error}")
3535
errors.append((filepath, error))
3636
all_ok = False
3737

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ jobs:
7171
- name: Install dependencies
7272
run: |
7373
python -m pip install --upgrade pip
74-
pip install PySide6
74+
pip install pynput pywin32 PySide6
7575
7676
- name: Test imports
7777
shell: pwsh
@@ -119,7 +119,7 @@ jobs:
119119
- name: Install dependencies
120120
run: |
121121
python -m pip install --upgrade pip
122-
pip install PySide6
122+
pip install pynput pywin32 PySide6
123123
124124
- name: Validate config schema
125125
shell: pwsh

0 commit comments

Comments
 (0)