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:
@@ -29,7 +29,10 @@ ROOT = "/home/claude/win-ci/serve"
|
||||
LOG = "/home/claude/win-ci/guest.log"
|
||||
RESULTS = "/home/claude/win-ci/results"
|
||||
PORT = 8099
|
||||
MAX_ARTIFACT = 32 * 1024 * 1024
|
||||
# 로그 전문뿐 아니라 빌드된 포터블 exe(100MB+)도 이 통로로 회수한다.
|
||||
# 32MB 로 두면 배포할 exe 가 413 으로 튕긴다.
|
||||
MAX_ARTIFACT = 1024 * 1024 * 1024
|
||||
CHUNK = 1024 * 1024
|
||||
|
||||
|
||||
class Handler(http.server.SimpleHTTPRequestHandler):
|
||||
@@ -82,11 +85,28 @@ class Handler(http.server.SimpleHTTPRequestHandler):
|
||||
if n > MAX_ARTIFACT:
|
||||
self.send_error(413, "artifact too large")
|
||||
return
|
||||
data = self.rfile.read(n)
|
||||
os.makedirs(RESULTS, exist_ok=True)
|
||||
with open(os.path.join(RESULTS, name), "wb") as f:
|
||||
f.write(data)
|
||||
print(f"artifact {name} {len(data)} bytes", flush=True)
|
||||
# 통째로 read() 하지 않는다. exe 는 100MB 가 넘어서 메모리에 다 올리면
|
||||
# 봇 cgroup 의 메모리 상한을 건드린다. 조각으로 받아 바로 디스크에 쓴다.
|
||||
#
|
||||
# 그리고 임시 이름으로 받아 끝난 뒤에 옮긴다. 전송 중에 끊기면 반쪽짜리
|
||||
# 파일이 정상 결과물처럼 남아 그대로 릴리스에 올라갈 수 있다.
|
||||
final = os.path.join(RESULTS, name)
|
||||
tmp = final + ".part"
|
||||
left = n
|
||||
with open(tmp, "wb") as f:
|
||||
while left > 0:
|
||||
block = self.rfile.read(min(CHUNK, left))
|
||||
if not block:
|
||||
break
|
||||
f.write(block)
|
||||
left -= len(block)
|
||||
if left:
|
||||
os.remove(tmp)
|
||||
self.send_error(400, "artifact truncated")
|
||||
return
|
||||
os.replace(tmp, final)
|
||||
print(f"artifact {name} {n} bytes", flush=True)
|
||||
self.send_response(204)
|
||||
self.end_headers()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user