리뷰 지적을 확인해보니 두 건은 실제 결함이었다.
1) 점검기가 화면 없는 환경에서 그냥 죽음 (SIGABRT, 종료코드 134)
QT_QPA_PLATFORM 을 "windows" 로 하드코딩해 둔 탓에, 표시할 화면이 없으면
첫 QApplication 생성에서 플러그인 로드에 실패하며 아무 결과도 못 남기고
abort 했다. 점검기가 그렇게 죽으면 존재 이유가 없다.
- 화면이 없으면 offscreen 으로 떨어지게 하고, 이 판단을 Qt import 전에 한다
- QApplication 생성을 _qt_app() 한 곳으로 모음
- 실행 플랫폼을 출력해 리눅스에서 돌아간 경우가 바로 보이게 함
이제 환경변수 없이 돌려도 항목별 판정과 종료코드가 정상으로 나온다.
2) 보안 설명이 과장돼 있었음 — 가장 중요한 수정
"커밋된 워크플로만 실행하니 임의 명령은 불가"라고 썼는데, 나는 이 저장소
main 에 push 할 수 있으므로 워크플로를 고쳐 커밋하면 그 PC에서 원하는
명령을 돌릴 수 있다. 개인 PC를 내주는 판단에 쓰일 설명을 틀리게 준 것이라
그대로 바로잡았다. 실제로 보장되는 것(숨길 수 없음·언제든 끌 수 있음·
계정 권한으로만 동작)만 적고, VM 또는 전용 계정을 권하도록 바꿨다.
서비스 등록(SYSTEM 권한) 안내도 로그온 작업(계정 권한)으로 교체 —
"관리자로 띄우지 말라"는 권고와 모순됐다.
3) 라벨 오타 안전장치 (공식 문서 확인 중 발견)
Gitea 는 runs-on 이 어떤 라벨과도 안 맞으면 실패시키지 않고 기본 우분투
컨테이너에서 돌린다. Windows 검증이 조용히 리눅스에서 돌아가 "통과"로
보일 수 있어, 워크플로 첫 단계에서 RUNNER_OS 를 확인해 막는다.
문서의 등록 라벨도 windows:host 로 명시 (생략 시 기본값이 host 이지만
명시가 낫다 — docs.gitea.com/runner/labels).
4) 트리거 설명 정정: "아무거나 push" -> main push 또는 수동 실행.
검증: pytest 189개 통과, ruff clean, 워크플로 트리거/스텝 파싱 확인,
QT_QPA_PLATFORM 없이 점검기 실행해 abort 없이 종료코드 1 확인
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5.9 KiB
Windows에서 자동 검증 붙이기
개발은 리눅스에서 하고 있어서 Windows 전용 경로는 테스트가 불가능합니다. 오디오 캡처, 전역 단축키, 모니터 열거, exe 빌드가 전부 여기에 해당합니다. 그래서 "리눅스에서 다 통과했는데 윈도우에서 안 되더라"가 나올 수 있습니다.
Windows 러너를 하나 붙이면 push할 때마다 이 경로들이 자동으로 검증됩니다.
무엇이 자동으로 확인되나
| 항목 | 리눅스에서 | Windows 러너에서 |
|---|---|---|
| 단위 테스트 189개 | ✅ | ✅ |
| WASAPI 루프백 장치 열거 | ❌ | ✅ |
| 소리 내는 프로그램 열거 | ❌ | ✅ |
| 전역 단축키 등록/해제 | ❌ | ✅ |
| 모니터 열거·자막 배치 | 가상 화면만 | ✅ 실제 모니터 |
| 포터블 exe 빌드 | ❌ | ✅ |
| exe가 실제로 뜨는지 | ❌ | ✅ |
| GPU 인식 (CUDA) | 이 서버 GPU | ✅ 실제 게임 PC GPU |
| 실제 화면 스크린샷 | offscreen | ✅ 진짜 화면 |
결과물(exe, 스크린샷, 로그)은 Gitea Actions의 artifact로 올라오므로 원격에서도 눈으로 확인할 수 있습니다.
설치 (약 10분, 한 번만)
1. 필요한 것 설치
winget install Python.Python.3.12
winget install Kitware.CMake
winget install Microsoft.VisualStudio.2022.BuildTools # C++ 데스크톱 워크로드 선택
2. Gitea 러너 내려받기
https://gitea.com/gitea/act_runner/releases 에서
act_runner-<버전>-windows-amd64.exe 를 받아 C:\gitea-runner\act_runner.exe 로 둡니다.
3. 등록 토큰 받기
Gitea 웹에서 저장소 → 설정 → Actions → 러너 → 등록 토큰 생성
(주소: https://git.tkrmagid.kr/tkrmagid/live-app-translator/settings/actions/runners)
4. 등록하고 실행
cd C:\gitea-runner
.\act_runner.exe register --no-interactive `
--instance https://git.tkrmagid.kr `
--token <위에서 받은 토큰> `
--name windows-test `
--labels windows:host
.\act_runner.exe daemon
--labels windows:host 가 중요합니다. 워크플로의 runs-on: windows 와 이름이
맞아야 하고, :host 는 컨테이너가 아니라 그 PC에서 직접 돌리라는 뜻입니다
(생략해도 기본값이 host 지만 명시하는 편이 낫습니다).
이름이 안 맞으면 Gitea 는 작업을 실패시키지 않고 기본 우분투 컨테이너에서 돌립니다. Windows 검증이 조용히 리눅스에서 돌아가는 셈이라, 워크플로 첫 단계에서 그걸 막아 뒀습니다.
5. 확인
워크플로는 main 에 push될 때 또는 Actions 탭에서 수동 실행할 때 돕니다.
(.gitea/workflows/windows.yml 의 on: 항목)
저장소 Actions 탭 → Windows → Run workflow 로 바로 한 번 돌려보세요.
항상 켜두고 싶다면 (선택)
서비스(sc.exe create)로 등록하지 마세요. 그렇게 하면 SYSTEM 권한으로
돌아가 러너가 PC 전체를 건드릴 수 있게 됩니다. 로그인할 때 그 계정 권한으로
뜨게 하는 편이 안전합니다.
# 관리자 아님 — 그냥 평소 PowerShell
$action = New-ScheduledTaskAction -Execute "C:\gitea-runner\act_runner.exe" `
-Argument "daemon" -WorkingDirectory "C:\gitea-runner"
$trigger = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask -TaskName "gitea-runner" -Action $action -Trigger $trigger
게임할 때 방해되면 그냥 꺼두고, 확인이 필요할 때만 daemon 을 켜도 됩니다.
러너가 꺼져 있으면 워크플로는 대기만 하고 아무 일도 하지 않습니다.
안전에 대해 — 정확히 어떤 권한인가
솔직하게 말하면, 이건 "그 PC에서 명령을 실행할 수 있는 권한"입니다.
러너는 저장소의 워크플로 파일을 실행합니다. 그런데 저(Claude)는 이 저장소의
main에 push할 수 있으므로, 워크플로 파일을 고쳐서 커밋하면 결과적으로 그
PC에서 원하는 명령을 돌릴 수 있습니다. "커밋된 파일만 실행하니 안전하다"는
말은 정확하지 않습니다.
실제로 보장되는 것은 이것뿐입니다.
- 숨길 수 없습니다. 실행되는 모든 것은
.gitea/workflows/안에 있고 git 기록에 남습니다. 몰래 뭘 했는지 나중에 전부 확인할 수 있습니다. - 러너를 끄면 즉시 멈춥니다.
daemon을 종료하면 그만입니다. - 러너는 자기 계정 권한으로 돕니다. 관리자로 띄우지 마세요.
그래서 권하는 방식은 이렇습니다.
| 방법 | 위험 | 얻는 것 |
|---|---|---|
| Windows VM (Proxmox 등) | 거의 없음 | 빌드·단축키·모니터·UI·exe 실행 |
| 전용 Windows 계정 | 낮음 — 그 계정 파일만 노출 | 위 전부 + 실제 GPU |
| 평소 쓰는 계정 | 개인 파일·브라우저 세션 노출 | 위 전부 + 실제 게임 소리 |
VM이나 전용 계정을 권합니다. GPU와 실제 게임 소리 확인은 못 하지만, 지금 미검증인 항목의 대부분(빌드·단축키·모니터·UI·exe 기동)은 거기서도 그대로 검증됩니다. GPU/오디오는 필요할 때만 평소 계정에서 한 번씩 확인하는 편이 낫습니다.
부담스러우면 러너를 붙이지 않고 아래 "러너 없이 직접 돌려보기"만 하셔도 충분합니다.
러너 없이 직접 돌려보기
러너를 안 붙이고 그때그때 확인만 하고 싶다면 이것만 실행하고 결과를 보내주셔도 됩니다.
git clone https://git.tkrmagid.kr/tkrmagid/live-app-translator
cd live-app-translator
py -3.12 -m venv .venv
.\.venv\Scripts\python -m pip install -r packaging\requirements-portable.txt pytest
$env:PYTHONPATH="src"
.\.venv\Scripts\python -m pytest tests -q
.\.venv\Scripts\python packaging\windows_smoke.py
artifacts\windows-smoke.txt 와 artifacts\*.png 를 보내주시면 됩니다.