Skip to content

Commit afeda9b

Browse files
authored
fix: downgrade python-ripgrep version to 0.0.8 in dependencies (#7514)
* fix: downgrade python-ripgrep version to 0.0.8 in dependencies * fix: update smoke test workflow to support multiple OS and Python versions
1 parent 533a0bd commit afeda9b

4 files changed

Lines changed: 143 additions & 26 deletions

File tree

.github/workflows/smoke_test.yml

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,23 @@ on:
1313

1414
jobs:
1515
smoke-test:
16-
name: Run smoke tests
17-
runs-on: ubuntu-latest
16+
name: Smoke test (${{ matrix.os }}, Python ${{ matrix.python-version }})
17+
runs-on: ${{ matrix.os }}
1818
timeout-minutes: 10
19-
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
os:
23+
- ubuntu-latest
24+
- macos-latest
25+
- windows-latest
26+
python-version:
27+
- '3.10'
28+
- '3.11'
29+
- '3.12'
30+
- '3.13'
31+
- '3.14'
32+
2033
steps:
2134
- name: Checkout
2235
uses: actions/checkout@v6
@@ -26,33 +39,21 @@ jobs:
2639
- name: Set up Python
2740
uses: actions/setup-python@v6
2841
with:
29-
python-version: '3.12'
30-
31-
- name: Install UV package manager
42+
python-version: ${{ matrix.python-version }}
43+
cache: 'pip'
44+
cache-dependency-path: requirements.txt
45+
46+
- name: Install uv
3247
run: |
33-
pip install uv
48+
python -m pip install --upgrade pip
49+
python -m pip install uv
3450
3551
- name: Install dependencies
3652
run: |
37-
uv sync
53+
uv pip install --system -r requirements.txt
3854
timeout-minutes: 15
3955

4056
- name: Run smoke tests
4157
run: |
42-
uv run main.py &
43-
APP_PID=$!
44-
45-
echo "Waiting for application to start..."
46-
for i in {1..60}; do
47-
if curl -f http://localhost:6185 > /dev/null 2>&1; then
48-
echo "Application started successfully!"
49-
kill $APP_PID
50-
exit 0
51-
fi
52-
sleep 1
53-
done
54-
55-
echo "Application failed to start within 30 seconds"
56-
kill $APP_PID 2>/dev/null || true
57-
exit 1
58+
python scripts/smoke_startup_check.py
5859
timeout-minutes: 2

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ dependencies = [
6464
"python-socks>=2.8.0",
6565
"pysocks>=1.7.1",
6666
"packaging>=24.2",
67-
"python-ripgrep==0.0.9",
67+
"python-ripgrep==0.0.8",
6868
]
6969

7070
[dependency-groups]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,4 @@ shipyard-python-sdk>=0.2.4
5353
shipyard-neo-sdk>=0.2.0
5454
packaging>=24.2
5555
qrcode>=8.2
56-
python-ripgrep==0.0.9
56+
python-ripgrep==0.0.8

scripts/smoke_startup_check.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
"""Cross-platform startup smoke check for AstrBot."""
2+
3+
from __future__ import annotations
4+
5+
import os
6+
import shutil
7+
import subprocess
8+
import sys
9+
import tempfile
10+
import time
11+
import urllib.error
12+
import urllib.request
13+
from pathlib import Path
14+
15+
REPO_ROOT = Path(__file__).resolve().parents[1]
16+
HEALTH_URL = "http://127.0.0.1:6185"
17+
STARTUP_TIMEOUT_SECONDS = 60
18+
REQUEST_TIMEOUT_SECONDS = 2
19+
20+
21+
def _tail(path: Path, lines: int = 80) -> str:
22+
try:
23+
content = path.read_text(encoding="utf-8", errors="replace").splitlines()
24+
except OSError as exc:
25+
return f"Unable to read smoke log: {exc}"
26+
return "\n".join(content[-lines:])
27+
28+
29+
def _is_ready() -> bool:
30+
try:
31+
with urllib.request.urlopen( # noqa: S310
32+
HEALTH_URL,
33+
timeout=REQUEST_TIMEOUT_SECONDS,
34+
) as response:
35+
return response.status < 400
36+
except (OSError, urllib.error.URLError):
37+
return False
38+
39+
40+
def _stop_process(proc: subprocess.Popen[bytes]) -> None:
41+
if proc.poll() is not None:
42+
return
43+
44+
proc.terminate()
45+
try:
46+
proc.wait(timeout=10)
47+
except subprocess.TimeoutExpired:
48+
proc.kill()
49+
proc.wait(timeout=10)
50+
51+
52+
def main() -> int:
53+
env = os.environ.copy()
54+
env.setdefault("PYTHONUTF8", "1")
55+
env.setdefault("TESTING", "true")
56+
57+
smoke_root = Path(tempfile.mkdtemp(prefix="astrbot-smoke-root-"))
58+
env["ASTRBOT_ROOT"] = str(smoke_root)
59+
log_path = smoke_root / "smoke.log"
60+
webui_dir = smoke_root / "webui"
61+
webui_dir.mkdir()
62+
(webui_dir / "index.html").write_text(
63+
"<!doctype html><title>AstrBot</title>",
64+
encoding="utf-8",
65+
)
66+
67+
with log_path.open("wb") as log_file:
68+
proc = subprocess.Popen(
69+
[
70+
sys.executable,
71+
str(REPO_ROOT / "main.py"),
72+
"--webui-dir",
73+
str(webui_dir),
74+
],
75+
cwd=REPO_ROOT,
76+
stdout=log_file,
77+
stderr=subprocess.STDOUT,
78+
env=env,
79+
)
80+
81+
print(f"Starting smoke test on {HEALTH_URL}")
82+
deadline = time.monotonic() + STARTUP_TIMEOUT_SECONDS
83+
try:
84+
while time.monotonic() < deadline:
85+
if _is_ready():
86+
print("Smoke test passed")
87+
return 0
88+
89+
return_code = proc.poll()
90+
if return_code is not None:
91+
print(
92+
f"AstrBot exited before becoming healthy. Exit code: {return_code}",
93+
file=sys.stderr,
94+
)
95+
print(_tail(log_path), file=sys.stderr)
96+
return 1
97+
98+
time.sleep(1)
99+
100+
print(
101+
"Smoke test failed: health endpoint did not become ready in time.",
102+
file=sys.stderr,
103+
)
104+
print(_tail(log_path), file=sys.stderr)
105+
return 1
106+
finally:
107+
_stop_process(proc)
108+
try:
109+
log_path.unlink()
110+
except OSError:
111+
pass
112+
shutil.rmtree(smoke_root, ignore_errors=True)
113+
114+
115+
if __name__ == "__main__":
116+
raise SystemExit(main())

0 commit comments

Comments
 (0)