build: 포터블 exe 에서 빠져 있던 프로그램별 캡처 도우미를 복구
Some checks failed
Windows / verify (push) Has been cancelled
Some checks failed
Windows / verify (push) Has been cancelled
livesub_capture.exe 가 없으면 포터블 빌드는 그대로 성공하되 프로그램별 캡처가 장치 전체 캡처로 조용히 폴백된다. 핵심 기능이 빠진 exe 가 나오는데 빌드는 PASS 로 보이는 조합이라 그대로 릴리스될 뻔했다. - win-ci VM 에 VS 2022 Build Tools(C++)를 깐다. WASAPI 프로세스 루프백 헤더와 WRL 은 Windows SDK + MSVC 에만 있어서 cmake 만으로는 못 만든다. - 검증 순서에 native_capture 단계를 windows_smoke 앞에 넣는다. 뒤에 두면 smoke 와 spec 이 둘 다 "없음"으로 통과해 버린다. - pyinstaller 단계가 거짓 PASS 를 내던 것을 고친다. 앞 회차의 exe 가 실행 중이면 PermissionError 로 빌드가 죽는데, 남아 있는 옛 exe 때문에 Test-Path 검사는 통과했다. 빌드 전에 프로세스를 죽이고 build/dist 를 지우며 PyInstaller 종료코드도 확인한다. - 통과한 exe 를 호스트로 회수한다. serve-host.py 는 32MB 상한이라 exe 를 413 으로 튕겼다. 상한을 올리고 조각으로 받아 디스크에 바로 쓰며, .part 로 받아 완료 후 옮겨 반쪽 파일이 결과물로 남지 않게 한다. - .gitignore 의 네이티브 산출물 경로가 예전 이름(hearo)이라 빌드한 exe 가 무시되지 않던 것을 livesub 로 고친다.
This commit is contained in:
@@ -113,6 +113,41 @@ if (Have 'cmake') {
|
||||
else { Log "WARN cmake 설치 실패 - 워크플로의 native 빌드 단계는 건너뛰어진다" }
|
||||
}
|
||||
|
||||
# ------------------------------------------------------ VS 2022 Build Tools (C++)
|
||||
# livesub_capture.exe (native\process_loopback) 는 WASAPI 프로세스 루프백을 쓴다.
|
||||
# 그 헤더(audioclientactivationparams.h)와 WRL 은 Windows SDK + MSVC 에만 있다.
|
||||
# cmake 만 깔면 "generator 는 있는데 컴파일러가 없다"로 configure 에서 죽는다.
|
||||
#
|
||||
# 왜 빠뜨리면 안 되나: 이 exe 가 없으면 포터블 빌드가 그대로 성공하되
|
||||
# 프로그램별 캡처가 장치 전체 캡처로 조용히 폴백된다. 즉 "게임 소리만 받는다"는
|
||||
# 핵심 기능이 빠진 채로 exe 가 나온다. 실제로 그 상태의 exe 가 한 번 나왔다.
|
||||
$VsWhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
|
||||
function Get-MsvcRoot {
|
||||
if (-not (Test-Path $VsWhere)) { return $null }
|
||||
$p = & $VsWhere -latest -products * `
|
||||
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
|
||||
-property installationPath 2>$null
|
||||
if ($p) { return ($p | Select-Object -First 1) }
|
||||
return $null
|
||||
}
|
||||
$msvc = Get-MsvcRoot
|
||||
if ($msvc) {
|
||||
Log "MSVC 이미 있음: $msvc"
|
||||
} else {
|
||||
$f = Get-File 'https://aka.ms/vs/17/release/vs_BuildTools.exe' 'vs_BuildTools.exe'
|
||||
Log "VS 2022 Build Tools 설치 중 (C++ 워크로드, 수 GB - 20분 이상 걸린다)"
|
||||
# --wait 없이 Start-Process -Wait 만 쓰면 부트스트래퍼가 먼저 반환해 버려
|
||||
# 설치가 끝나기 전에 다음 단계로 넘어간다. 둘 다 있어야 한다.
|
||||
$p = Start-Process $f -Wait -PassThru -ArgumentList `
|
||||
'--quiet', '--wait', '--norestart', '--nocache', `
|
||||
'--add', 'Microsoft.VisualStudio.Workload.VCTools', '--includeRecommended'
|
||||
# 3010 = 설치는 됐고 재부팅만 권고. 실패가 아니다.
|
||||
Log "Build Tools 설치기 종료코드 $($p.ExitCode)"
|
||||
$msvc = Get-MsvcRoot
|
||||
if ($msvc) { Log "MSVC 설치 완료: $msvc" }
|
||||
else { Log "WARN MSVC 설치 실패 - livesub_capture.exe 를 빌드할 수 없다" }
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ act_runner
|
||||
$RunnerDir = 'C:\gitea-runner'
|
||||
$RunnerExe = Join-Path $RunnerDir 'act_runner.exe'
|
||||
@@ -240,7 +275,9 @@ function Send-Artifact($name, $path) {
|
||||
$bytes = [IO.File]::ReadAllBytes($path)
|
||||
# 백틱 줄바꿈을 쓰지 않는다. LF 로 저장된 스크립트에서 토크나이저가
|
||||
# 어긋나 스크립트 전체가 무효가 된 전례가 있다 (NOTES.md 참고).
|
||||
$req = @{ Uri = "http://10.0.2.2:8099/artifact/$name"; Method = 'Post'; TimeoutSec = 120; Body = $bytes; ContentType = 'application/octet-stream' }
|
||||
# 타임아웃은 넉넉히. 로그는 수십 KB 지만 포터블 exe 는 100MB 를 넘고
|
||||
# slirp(QEMU user networking) 는 그만큼 빠르지 않다.
|
||||
$req = @{ Uri = "http://10.0.2.2:8099/artifact/$name"; Method = 'Post'; TimeoutSec = 1800; Body = $bytes; ContentType = 'application/octet-stream' }
|
||||
Invoke-RestMethod @req | Out-Null
|
||||
Log " -> 호스트로 $name ($($bytes.Length) bytes)"
|
||||
} catch {
|
||||
@@ -314,10 +351,47 @@ try {
|
||||
$r = [ordered]@{}
|
||||
$r['pytest'] = Step 'pytest' { & $py -m pytest tests -q -rf --tb=long; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } }
|
||||
$r['ruff'] = Step 'ruff' { & $py -m ruff check src tests scripts; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } }
|
||||
|
||||
# 캡처 도우미를 먼저 만든다. windows_smoke 가 이 exe 의 존재를 점검하고,
|
||||
# livesub.spec 도 있을 때만 포터블 exe 안에 담는다. 순서가 바뀌면 둘 다
|
||||
# "없음"으로 통과해서 기능이 빠진 exe 가 나온다.
|
||||
$r['캡처도우미'] = Step 'native_capture' {
|
||||
& cmake -S native\process_loopback -B native\process_loopback\build -A x64
|
||||
if ($LASTEXITCODE -ne 0) { throw "cmake configure exit $LASTEXITCODE" }
|
||||
& cmake --build native\process_loopback\build --config Release
|
||||
if ($LASTEXITCODE -ne 0) { throw "cmake build exit $LASTEXITCODE" }
|
||||
$cap = 'src\livesub\resources\bin\livesub_capture.exe'
|
||||
if (-not (Test-Path $cap)) { throw "$cap 없음" }
|
||||
"livesub_capture.exe $((Get-Item $cap).Length) bytes"
|
||||
}
|
||||
|
||||
$r['windows경로'] = Step 'windows_smoke' { & $py packaging\windows_smoke.py; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } }
|
||||
$r['exe빌드'] = Step 'pyinstaller' { & $py -m pip install pyinstaller --quiet; & $py -m PyInstaller packaging\livesub.spec --noconfirm; if (-not (Test-Path 'dist\LiveSub.exe')) { throw 'dist\LiveSub.exe 없음' }; "exe 크기 $([math]::Round((Get-Item 'dist\LiveSub.exe').Length/1MB,1)) MB" }
|
||||
|
||||
$r['exe빌드'] = Step 'pyinstaller' {
|
||||
& $py -m pip install pyinstaller --quiet
|
||||
# 이전 산출물을 반드시 지우고 시작한다. 남겨두면 두 가지가 겹쳐 터진다.
|
||||
# 1) 앞 회차의 exe기동 점검이 띄운 LiveSub 가 파일을 잡고 있어
|
||||
# PyInstaller 가 EXE 를 덮어쓰지 못하고 PermissionError 로 죽는다.
|
||||
# 2) 그런데 옛 exe 는 그대로 남아 있으니 Test-Path 는 통과한다.
|
||||
# 즉 빌드가 실패했는데 PASS 로 보고된다 - 실제로 그렇게 오보가 났다.
|
||||
Get-Process LiveSub -ErrorAction SilentlyContinue | Stop-Process -Force
|
||||
Start-Sleep -Seconds 2
|
||||
Remove-Item -Recurse -Force build, dist -ErrorAction SilentlyContinue
|
||||
& $py -m PyInstaller packaging\livesub.spec --noconfirm
|
||||
if ($LASTEXITCODE -ne 0) { throw "PyInstaller exit $LASTEXITCODE" }
|
||||
if (-not (Test-Path 'dist\LiveSub.exe')) { throw 'dist\LiveSub.exe 없음' }
|
||||
"exe 크기 $([math]::Round((Get-Item 'dist\LiveSub.exe').Length/1MB,1)) MB"
|
||||
}
|
||||
$r['exe기동'] = Step 'exe_smoke' { & $py packaging\windows_smoke.py --exe dist\LiveSub.exe; if ($LASTEXITCODE -ne 0) { throw "exit $LASTEXITCODE" } }
|
||||
|
||||
# 빌드와 기동이 둘 다 통과했을 때만 배포용으로 회수한다. 실패한 exe 를
|
||||
# 호스트로 올리면 그게 릴리스에 올라갈 위험이 있다.
|
||||
if ($r['exe빌드'] -and $r['exe기동']) {
|
||||
Send-Artifact 'LiveSub.exe' (Join-Path $Repo 'dist\LiveSub.exe')
|
||||
} else {
|
||||
Log "exe 회수 건너뜀 (빌드=$($r['exe빌드']) 기동=$($r['exe기동']))"
|
||||
}
|
||||
|
||||
# 판정 요약도 파일로 남긴다. 어떤 리비전을 검증한 결과인지 같이 박아야
|
||||
# 나중에 "언제 통과한 건지" 를 되짚을 수 있다.
|
||||
$rev = (& git rev-parse --short HEAD 2>&1 | Select-Object -First 1)
|
||||
|
||||
Reference in New Issue
Block a user