diff --git a/scripts/win-ci/serve/stage2.ps1 b/scripts/win-ci/serve/stage2.ps1 index 201b54c..aeb6f6d 100644 --- a/scripts/win-ci/serve/stage2.ps1 +++ b/scripts/win-ci/serve/stage2.ps1 @@ -247,8 +247,12 @@ try { Log "포터블 조건(torch 없음) = $($LASTEXITCODE -eq 0)" $env:PYTHONPATH = 'src' + # Windows 콘솔 기본 인코딩(cp1252)에서는 한글 print 가 UnicodeEncodeError 로 + # 죽는다. 검증 스크립트가 한글을 찍으므로 UTF-8 로 고정한다. + $env:PYTHONIOENCODING = 'utf-8' + $env:PYTHONUTF8 = '1' $r = @{} - $r['pytest'] = Step 'pytest' { & $py -m pytest tests -q 2>&1 | Select-Object -Last 8 | ForEach-Object { Log " $_" }; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } } + $r['pytest'] = Step 'pytest' { & $py -m pytest tests -q 2>&1 | Select-Object -Last 30 | ForEach-Object { Log " $_" }; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } } $r['ruff'] = Step 'ruff' { & $py -m ruff check src tests scripts 2>&1 | Select-Object -Last 5 | ForEach-Object { Log " $_" }; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } } $r['windows경로'] = Step 'windows_smoke' { & $py packaging\windows_smoke.py 2>&1 | ForEach-Object { Log " $_" }; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } } $r['exe빌드'] = Step 'pyinstaller' { & $py -m pip install pyinstaller --quiet; & $py -m PyInstaller packaging\livesub.spec --noconfirm 2>&1 | Select-Object -Last 4 | ForEach-Object { Log " $_" }; if (-not (Test-Path 'dist\LiveSub.exe')) { throw 'dist\LiveSub.exe 없음' }; Log " exe 크기 $([math]::Round((Get-Item 'dist\LiveSub.exe').Length/1MB,1)) MB" } @@ -256,7 +260,7 @@ try { Log "=== Windows 검증 결과 ===" foreach ($k in $r.Keys) { Log ("{0,-14} {1}" -f $k, $(if ($r[$k]) { 'PASS' } else { 'FAIL' })) } - Log "=== 검증 끝 ===" + Log "=== 검증 끝 (rev2: .gitignore 수정 반영) ===" Pop-Location } catch { Log "검증 준비 단계에서 실패: $($_.Exception.Message)" diff --git a/scripts/win-ci/win-ci-http.service b/scripts/win-ci/win-ci-http.service new file mode 100644 index 0000000..7a6956a --- /dev/null +++ b/scripts/win-ci/win-ci-http.service @@ -0,0 +1,12 @@ +[Unit] +Description=win-ci guest control channel (host -> Windows VM) +Before=win-ci.service + +[Service] +Type=simple +ExecStart=/usr/bin/python3 /home/claude/win-ci/serve-host.py +Restart=always +RestartSec=5 + +[Install] +WantedBy=default.target diff --git a/scripts/win-ci/win-ci.service b/scripts/win-ci/win-ci.service new file mode 100644 index 0000000..e14eea8 --- /dev/null +++ b/scripts/win-ci/win-ci.service @@ -0,0 +1,20 @@ +[Unit] +Description=win-ci Windows CI VM (nested KVM) +Wants=win-ci-http.service +After=win-ci-http.service + +[Service] +Type=simple +WorkingDirectory=/home/claude/win-ci +ExecStart=/bin/bash /home/claude/win-ci/run-vm.sh +# 봇(ejclaw.service) cgroup 밖 - 안에서 돌면 MemoryHigh=16G 를 쳐서 봇이 OOM 으로 죽는다 +MemoryMax=12G +# .5 의 운영 컨테이너 19개가 같은 물리 호스트를 쓴다. 4코어를 넘기면 .5 응답이 +140% +CPUQuota=400% +CPUWeight=50 +Restart=on-failure +RestartSec=15 +TimeoutStopSec=120 + +[Install] +WantedBy=default.target