Skip to content

릴리스 하네스 ​

제품 저장소의 develop → main 릴리스를 다른 모델의 리뷰 → 사람의 결정 → 사람이 발행한 태그로 배포로 잇습니다. 실제 운영에서 15일 동안 릴리스 20개를 이 흐름으로 냈고, 릴리스 PR 위 GPT 리뷰 24회 중 20회가 사람 결정을 요청했습니다.

정확히 말하기

Slack 결정이 정하는 것은 main 머지까지입니다. 운영 배포는 사람이 GitHub 릴리스(태그)를 발행할 때만 일어납니다. 「Slack 승인하면 배포된다」고 쓰지 않습니다.

흐름 ​

  1. 개발자가 develop → main PR 을 엽니다. 같은 저장소 · 믿는 계정 · 초안이 아닌 PR 만 받습니다.
  2. 러너(개발 Mac 의 launchd, 60초 주기)가 Codex CLI 로 리뷰합니다.
    • 읽기 전용 샌드박스, 승인 없음(approval_policy=never), 30분 상한
    • 출력은 데이터로만 다룹니다: 스키마로 검사하고, 비밀 꼴은 가리고, 명령으로 실행하지 않습니다
  3. 리뷰를 PR 댓글로 남깁니다.
  4. 「리뷰 불필요」이고 안전 규칙(아래)도 통과하면 바로 머지합니다.
  5. 아니면 Slack 카드: 수정 반영 후 머지 / 그대로 머지
  6. 「수정 반영」이면 Codex 가 네트워크 없는 쓰기 샌드박스에서 고칩니다.
  7. 러너가 샌드박스 밖에서 전체 검사를 돌리고, 수정 PR 을 develop 에 squash 합니다.
  8. CI 통과를 확인하고 --match-head-commit 으로 그 커밋 그대로 main 에 머지합니다.
  9. 사람이 GitHub 릴리스를 발행하면 배포 워크플로가 검사 후 배포합니다. 태그 발행

결정의 원본은 PR 댓글 ​

  • 러너는 기계용 표시와 믿는 계정의 한 낱말 댓글(승인 · 거절 · 재시도)만 읽습니다.
  • Slack 버튼은 그 댓글을 대신 달 뿐입니다. Slack 이 죽어도 GitHub 에서 결정할 수 있습니다.
  • 멈춤 스위치(PAUSE 파일), 사람의 손 머지 감지 · 경고, Slack 재시도와 카드 재게시가 있습니다.

늘 사람이 결정하는 경로 ​

리뷰 결과와 상관없이 아래가 바뀌면 자동 머지하지 않습니다.

text
packages/db/src/migrations/**     DB 마이그레이션
infra/**                          인프라
.github/workflows/**              워크플로
**/Dockerfile                     이미지
.claude/**                        에이전트 권한 · 스킬
pnpm-lock.yaml 의 새 의존성

GPT 가 고칠 수 없는 경로: 위 경로 전부, .github/**, vendor/**, 릴리스 러너 자신(scripts/release/**), package.json, .env*. 수정안에 토큰 꼴이 보이면 멈춥니다. 위험한 샌드박스 모드(전체 접근)는 코드로 만들 수 없게 막습니다.

태그 배포 검사 ​

release: published 이벤트를 받은 워크플로가 다음을 모두 확인한 뒤에야 배포를 부릅니다.

  • 태그 꼴이 <서비스>@vMAJOR.MINOR.PATCH 인가
  • 태그 커밋 = 이벤트 커밋, main 의 조상인가
  • 그 커밋의 main CI 가 성공했나
  • 발행자가 write 권한 이상인가
  • 가장 높은 태그이고, 앞 태그 커밋을 품고 있나

배포는 main 에서 workflow_dispatch 로 부릅니다. 그래야 OIDC subject 가 늘 main 으로 고정됩니다.

배포 워크플로 ​

  1. 동시성 잠금을 얻은 뒤 사전 확인을 한 번 더
  2. 코드 변경 없는 태그는 건너뜀, 같은 SHA 이미지는 재사용
  3. 이전 리비전과 롤백 명령을 기록, 리비전 경합 감지
  4. 마이그레이션 단발 태스크 → api → web → 스모크 → 수집 스케줄
  5. 배포 기록을 S3 에, 시작 · 실패를 Slack 에
  6. 앱 자동 롤백은 ECS 서킷 브레이커가 합니다(DB 는 되돌리지 않음 → 그래서 마이그레이션은 사람 결정)

실제 운영을 바꾼 배포만 릴리스 노트로 Slack 에 공지합니다.

서버 오류 분석 (같은 러너) ​

  1. 15분마다 읽기 전용 프로필로 api · web 로그를 읽습니다.
  2. 토큰 · JWT · 쿼리 값 · 메일 · 주민번호 · 전화 · 카드 · IP · SQL 값을 가립니다. 원문은 어디에도 쓰지 않습니다.
  3. 오류 지문마다 GitHub issue 를 엽니다.
  4. GPT 분석을 Slack 카드로 올리고, 승인돼도 수정은 develop 에만 들어갑니다.

스캐너가 보내는 가짜 Server Action 요청(7일 오류 97건 중 91건)은 잡음으로 거르고, web 에서는 해당 헤더 요청을 404 로 끊었습니다.

Claude 검증 ​

GPT 리뷰의 지적이 타당한지는 러너가 아니라 개발 세션에서 Claude 로 하나씩 확인합니다. 두 모델이 서로의 맹점을 덮게 하되, 최종 판단은 사람이 합니다.

사내에서 운영 중인 하네스를 새 프로젝트에 다시 쓰기 위해 일반화해 정리한 문서입니다.