Skip to content

로컬 CI 병렬 실행과 사용 후 샌드박스 정리 — 전체 검증 7분 32초 (2026-09-10)

  • 기간: 2026-09-09~10, #1464 구현·실측과 HQ 통합. 오너 지시: “바벨릭 #1464좀 진행해줘 / 릴리스는 0.17.7”, 이후 병렬 수 확대 실측과 사용 후 샌드박스 정리 확인.
  • 랜딩: 통합 PR #1484, release merge e56604cb0ae4d9fcaa361fbd99c3978dabb60535(01:00 KST). staging PR #1488 merge 213aaeb7c21598e3023cf47d16ec756feabad80a(01:02 KST). #1464 자체 마이그레이션·Edge·제품 기능 변경 없음. 기록 시점 main·Production 미반영.
  • 설계서: 이슈의 분석·Phase 계획. 전체 릴리스 기록은 HQ가 별도로 관리한다.
  • 정본: 병렬 로컬 CI 운영, 로컬 CI, 릴리스 큐.
  • 도구: 앱의 scripts/ci-local.mjs, scripts/ci-local-sandboxes.mjs, scripts/e2e/build-legacy-bundle.mjs. 외부 작업 폴더의 capacity/legacy 재현 스크립트는 실측용이며 앱에 반입하지 않았다.
  • 게이트: 최종 full 34372922344, 00:59:39 KST 결과 요약. pgTAP 130파일·2,328 assert, 브라우저 56 pass, 화면 22 pass, 필수 완료 증거 통과. 별도 부분 실행에서는 CASE-009 총 24건과 CASE-039/040을 사용했으며 아래에서 성공·실패 범위를 구분한다. 폐기된 db:preflight·우회 표시·추가 full 실행은 사용하지 않았다.
  • 버그리포트: BUG-086 — 긴 구버전 worktree 경로로 인한 skip.
  • 문서 PR: Barbelic-docs #2. 초기 앱 PR #1467은 준비 이력이며 실제 반영은 통합 PR #1484다.

Phase 현황

Phase내용상태
Phase 1실행 단위 격리와 병렬 실행 구조완료, 통합 PR #1484
Phase 2실제 DB·브라우저 격리 및 부분 시간 측정완료, 초기 실패 한계 기록
Phase 3운영 문서·사전 검사·초안 PR완료
Phase 44·8·12 병렬 실측과 샌드박스 자동 정리완료, 기본 4 유지
Phase 5실측·운영값·기존 PR 문서화완료
Phase 6선행 변경과 HQ 고정 후보 통합완료
Phase 7구버전 준비 긴 경로 수리·실패 사유 보존완료, 본문 실패는 #1468 담당 수리와 통합

1. 배경

한 PC의 큐 검증이 정적·단위·DB·브라우저 단계를 순서대로 실행했다. 브라우저도 DB와 미리보기 서버를 공유해 한 작업자로 돌았다. 오너는 전체 검증 5분 내외를 목표로 지정했고, 로컬 자원에 맞는 병렬 수와 사용 후 샌드박스 정리도 요구했다.

2. 문제 제기

검사만 늘리면 DB 준비와 정리 비용도 함께 늘어난다

같은 CASE-009 24건을 나눠 실행한 한 번씩의 비교에서 4개는 280.56초, 8개는 389.36초, 12개는 568.24초였다. 공유 앱 빌드는 이 시간에서 제외했고 다른 작업의 부하를 통제하지 않았다. 12개는 23 pass/1 fail로 실패 원인과 부하의 인과는 확정하지 않았다.

격리하지 않은 상태 파일과 종료 처리가 실행 간 간섭을 만든다

Supabase의 공용 telemetry 상태 파일 갱신이 병렬 실행에서 EPERM을 냈다. 이벤트 전송을 꺼도 상태 파일 쓰기는 남았다. 초기 병렬 종료에서는 환경 3개가 남았고 오류 출력이 보존되지 않아 내부 원인을 확정할 수 없었다. 구버전 캐시의 긴 경로는 실제 Windows checkout을 실패시켜 두 케이스를 skip으로 만들었다.

3. 해결 방안

원칙

  • D1(2026-09-09): 릴리스는 오너 지정 0.17.7, 검증 내용과 검증한 merge commit 그대로 반영하는 큐 규칙을 유지한다.
  • D2(2026-09-09): 사용한 샌드박스를 정리하고, 다른 실행·원본 연결 대상은 보호한다.
  • D3(2026-09-09~10): 기존 CI 최소화 결정에 따라 담당 세션은 필요한 실패 재현만 하고, 최종 full은 HQ가 큐에서 실행한다.

접근

판단
독립 DB·포트·CLI HOME·보고서·구버전 캐시를 갖는 조각을 병렬 실행채택. 검사 간 간섭을 피하며 기존 작업자 1 설정과 증거 검사를 유지한다.
작업자를 늘려 같은 DB의 cron·대기열을 공유기각. 계정 범위를 넘어서는 잠금·정리 판정을 함께 다뤄야 하므로 이번 실행 구조 분리보다 범위가 크다.
병렬 수를 최대한 확대기각. 8·12개는 DB 준비·종료 비용을 포함한 실측에서 4개보다 느렸다.
시간 제한 완화·skip 허용·전역 Docker 정리기각. 원인이나 자원 소유권을 해결하지 못한다.

4. 적용한 내용

Phase 1~3 — 검사 묶음과 증거 분리

정적 검사, 단위 2조각, DB 검사, 브라우저 4조각, viewport를 의존 관계에 따라 실행한다. 브라우저와 viewport는 DB·포트·산출물 경로를 각각 사용한다. 현재 실행의 SHA·run·조각 완전성·첫 시도·실제 여정·cleanup 증거를 확인하고 다른 실행 결과를 섞지 않는다.

Phase 4~5 — 사용 후 종료와 유휴 정리

부분 실행도 성공·실패·중단 뒤 기본 종료하며 명시한 --keep만 환경을 유지한다. 사용 종료 시각부터 기본 6시간 지난 등록 환경은 다음 수동 또는 큐 전 --prune 때 회수한다. 활성 PID·불명확한 소유 정보·원본 경로는 보호한다. Edge 자식 프로세스 종료를 기다린 뒤 Docker 스택을 순차 종료하고, junction은 연결만 제거한다.

Phase 6~7 — 통합과 실제 준비 실패 수리

새 큐 명령·문서 저장소 분리·기존 시간 제한·검사 표시 이름을 HQ 후보에 통합했다. Git 전역 설정을 상속하지 않는 CI에서도 긴 태그 경로를 처리하도록 worktree 생성·제거 명령에만 core.longpaths=true를 적용했다. skip 사유와 증거 거부 메시지가 요약에서 사라지지 않게 했다.

작업 중 드러난 것

작은 Git fixture의 짧은 파일명으로 실제 태그의 긴 경로를 검증하지 못한 사전 검증 누락이 있었다. 긴 SQL source 240자·lane 260자 초과 fixture로 원본 실패→수정 후 통과를 확인했다. 실제 번들 준비는 6.740초에 통과했다. 이어서 CASE-039/040은 skip 0이 됐지만 본문에서 2 fail이 남아 #1468 담당에게 인계했고, 이후 통합 full에서 모두 통과했다. 번들 수리만으로 본문 실패까지 해결했다고 합산하지 않는다.

5. 적용 결과

항목결과
전체 CI최초 통합 7분 37초 실패 → 후속 수리 통합 7분 32초 성공. 성공 run은 위 링크. 목표 5분 내외는 미달이며 서로 다른 후보의 개선율을 계산하지 않는다.
브라우저·화면최종 browser 4조각 × 14 = 56 pass, viewport 22 pass; fail/skip/flaky 모두 0, 완료 증거 통과
단위최종 1,879 + 1,544 pass / 0 fail, 조건부 DB skip 12 + 18은 실제 DB 통과 수에 합산하지 않음
DBreset·schema 통과, pgTAP 130파일/2,328 assert, 동시 저장·통계 격리 통과
비브라우저 E2Elocal 12, empty 9, cardio 6, persistence 56 pass, 모두 fail/skip/flaky 0
병렬 수동일 24건 부분 실측: 4개 280.56초/24 pass, 8개 389.36초/24 pass, 12개 568.24초/23 pass·1 fail. 기본 4·지원 1~8 유지. 전체 CI의 최적값을 탐색 완료한 것은 아님.
자원 정리4·8·12 실험 스택 종료 exit 0. 6시간 유휴 회수 실험에서 폴더 제거·원본 해시 보존. 마지막 cil348c7884 재현도 Edge·DB 종료, 컨테이너/네트워크/볼륨 0·샌드박스 폴더 제거 확인
운영 적용release·staging 병합 완료. 기록 시점 staging 배포 진행 중, main·Production 및 trusted main의 큐 전 prune 활성화는 미완료

6. 이번 개선으로 향상된 것

병렬 수를 실제 준비·종료 비용까지 포함해 선택한다

같은 PC의 자원을 공유하므로 브라우저 구간이 줄어도 전체가 느려질 수 있음을 실측으로 확인했다. 기본 4는 비교한 세 조건 중 가장 빨랐고 실패도 없었다. 최종 전체 검증은 기존 검사 범위와 증거 기준을 지키면서 7분 32초에 통과했다.

실행 뒤 자원이 남거나 실패 원인이 가려지는 것을 줄인다

소유권이 확인된 환경만 기본 종료·유휴 회수하며 원본과 다른 실행을 보호한다. 실패·skip·정리 오류를 결과에 보존하고 필수 완료 증거가 없으면 통과시키지 않는다.

남은 것

전체 5분 내외 목표는 달성하지 않았다. main·Production 승격과 전체 릴리스 기록은 HQ 담당이며, 이 기록은 해당 완료를 미리 선언하지 않는다. 운영 전 큐 prune의 자동 호출은 해당 컨트롤러 코드가 trusted main에 반영된 뒤 판단한다.