Skip to content

fix(race): use O_CREAT|O_EXCL for atomic PID lock #927

fix(race): use O_CREAT|O_EXCL for atomic PID lock

fix(race): use O_CREAT|O_EXCL for atomic PID lock #927

Workflow file for this run

name: CI
on:
push:
branches: [main, master]
pull_request:
jobs:
# ── Fast syntax check (runs in ~10s, blocks everything else) ──────────────
lint:
name: Syntax & Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Check Python syntax (all .py files, Python 3.9 compatible)
run: |
python3 -c "
import ast, glob, sys
errors = 0
for f in ['dashboard.py'] + glob.glob('clawmetry/**/*.py', recursive=True):
try:
ast.parse(open(f).read(), filename=f)
except SyntaxError as e:
print(f'❌ {f}:{e.lineno}: {e.msg}')
errors += 1
if errors:
sys.exit(1)
print(f'✅ Syntax OK ({len(glob.glob(\"clawmetry/**/*.py\", recursive=True)) + 1} files)')
"
- name: Install ruff (fast linter)
run: pip install ruff
- name: Lint (warnings only, don't fail)
run: ruff check dashboard.py --select E,W --ignore E501,W503 || true
# ── API tests across all 3 platforms ─────────────────────────────────────
api-tests:
name: API Tests (${{ matrix.os }})
needs: lint
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.11"]
exclude:
# Only test py3.9 on Linux to keep matrix manageable
- os: macos-latest
python-version: "3.9"
- os: windows-latest
python-version: "3.9"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install flask pytest requests waitress
- name: Start server (Unix)
if: runner.os != 'Windows'
run: |
OPENCLAW_GATEWAY_TOKEN=ci-test-token python3 dashboard.py --port 8900 --no-debug &
for i in $(seq 1 30); do
curl -sf -H "Authorization: Bearer ci-test-token" http://localhost:8900/api/health && echo "Ready" && break
sleep 1
done
shell: bash
- name: Start server (Windows)
if: runner.os == 'Windows'
run: |
$env:OPENCLAW_GATEWAY_TOKEN = "ci-test-token"
$env:PYTHONIOENCODING = "utf-8"
$env:PYTHONUTF8 = "1"
Start-Process python -ArgumentList "-u -X utf8 dashboard.py --port 8900 --no-debug" -NoNewWindow -RedirectStandardOutput "server_out.txt" -RedirectStandardError "server_err.txt"
$ready = $false
for ($i = 0; $i -lt 30; $i++) {
try {
$r = Invoke-WebRequest -Uri "http://localhost:8900/api/health" -Headers @{"Authorization"="Bearer ci-test-token"} -UseBasicParsing -ErrorAction Stop
if ($r.StatusCode -eq 200) { $ready = $true; break }
} catch {}
Start-Sleep 1
}
if (-not $ready) {
Write-Host "=== server_out.txt ==="
if (Test-Path server_out.txt) { Get-Content server_out.txt }
Write-Host "=== server_err.txt ==="
if (Test-Path server_err.txt) { Get-Content server_err.txt }
Write-Error "Server failed to start"; exit 1
}
shell: pwsh
- name: Run API tests
env:
CLAWMETRY_URL: http://localhost:8900
CLAWMETRY_TOKEN: ci-test-token
run: python3 -m pytest tests/test_api.py -v --tb=short
# ── E2E Playwright tests (Linux only for speed, allowed to fail) ──────────
e2e-tests:
name: E2E Browser Tests
needs: lint
runs-on: ubuntu-latest
continue-on-error: true # Remove once tests are fully stable
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install flask pytest pytest-playwright requests
- name: Install Playwright browsers
run: python3 -m playwright install chromium --with-deps
- name: Start server
run: |
OPENCLAW_GATEWAY_TOKEN=ci-test-token python3 dashboard.py --port 8900 --no-debug &
for i in $(seq 1 30); do
curl -sf -H "Authorization: Bearer ci-test-token" http://localhost:8900/api/health && break
sleep 1
done
- name: Run E2E tests
env:
CLAWMETRY_URL: http://localhost:8900
CLAWMETRY_TOKEN: ci-test-token
run: python3 -m pytest tests/test_e2e.py -v --tb=short
# ── pip install smoke test across platforms ───────────────────────────────
pip-install:
name: pip install (${{ matrix.os }})
needs: lint
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install from source
run: pip install flask .
- name: Smoke test - help works
run: python3 -c "import dashboard" || python3 dashboard.py --version 2>/dev/null || echo 'import OK'
continue-on-error: true
- name: Smoke test - syntax valid
run: python3 -c "import dashboard; print('✅ Import OK')"
continue-on-error: true # May fail if dashboard has top-level side effects