Conversation
VERIFYING 에서 CONNECTED 로 가는 길은 checkVerification 호출 하나뿐인데 그것을 밟는 주체가 없었다. 그래서 DNS 도 호스팅 설정도 끝난 도메인이 영원히 VERIFYING 에 머물고, domainSummary.url 은 status 가 CONNECTED 일 때만 채워지므로 사용자는 주소를 직접 치면 열리는 도메인의 링크를 화면에서 영영 못 봤다. VERIFYING 도메인을 1분마다 검증하는 DomainVerificationWorker 를 둔다. - 워커에는 요청한 사용자가 없다. checkVerificationAsSystem 이 도메인의 프로젝트에서 소유자를 찾아 검증에 쓸 GitHub 토큰의 주인을 얻는다 - 인증서는 종료 조건이 아니다. 관리형 서브도메인은 Cloudflare 프록시 뒤에 있어 GitHub Pages 가 인증서를 발급하지 못하고 certificateStatus 가 영원히 ACTIVE 가 되지 않는다(#154). 연결 판정은 dnsConnected && domainConfigured 만 본다 - 포기 조건은 타입별로 다르다. 관리형은 우리가 Cloudflare 레코드를 직접 만들므로 30분, 커스텀은 사용자가 자기 registrar 에서 CNAME 을 걸어야 하므로 24시간. 넘기면 FAILED 로 닫는다 — 잘못된 CNAME 은 영원히 성공하지 않는다 - 한 도메인의 실패가 나머지를 막지 않는다. 배치 상한(기본 20)으로 주기당 외부 API 호출 수를 묶는다 - 구매형은 검증 자체가 미지원이라 건너뛴다. 태우면 매 주기 예외만 남는다 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
워커는 PENDING 만 집으므로 웹훅을 한 번 놓치면 그 이력은 영구히 IN_PROGRESS 에 멈춘다. 화면에는 그것이 "진행 중"으로도 "실패"로도 보이지 않는다 — 대화에는 "접수했습니다"가 마지막 말로 남고, FE 폴링은 붙을 메시지가 없어 조용히 끝난다. 사용자에게는 아무 일도 일어나지 않은 것처럼 보인다. 그렇다고 시간이 지났다고 FAILED 로 닫아서는 안 된다. 실제로 겪은 사고가 정확히 그 반대였다 — GitHub 쪽은 전부 성공하고 사이트도 200 으로 떴는데 우리 이력만 멈춰 있었다. 그것을 실패로 적으면 멀쩡히 배포된 것을 실패했다고 알리게 된다. 그래서 StuckDeploymentRecoveryWorker 는 상태를 추측하지 않고 GitHub 의 실행 결과를 읽어 그대로 반영한다. - 대상은 리스 없이 IN_PROGRESS 인 이력이다. 워커가 붙들고 준비 중인 것은 리스를 갖고 있고 그 만료는 recoverExpiredLeases 가 따로 회수한다. markDispatched 가 리스를 비우므로, 리스 없는 IN_PROGRESS 는 GitHub 의 답만 기다리는 상태다 - 완료면 conclusion 그대로 확정한다. 아직 도는 중이면 건드리지 않는다 - 판정을 못 얻은 채 포기 시각(기본 2시간)을 넘긴 것만 닫고, 사유를 "실패"가 아니라 "결과를 확인할 수 없습니다"로 적는다 - runId 가 비어 있는 이력은 correlationId 로 다시 찾는다. finishDispatch 는 실행을 못 찾아도 IN_PROGRESS 로 넘기기 때문이다 결과 확정 로직은 DeploymentOutcomeService 로 옮겨 웹훅과 워커가 공유한다. 각자 자기 버전을 갖고 있으면 한쪽만 고쳐져 배포는 성공했는데 대화에는 아무 말도 안 남는 식으로 갈라진다. 웹훅 테스트는 이 서비스의 실제 인스턴스를 끼워 넣어, 수신부터 대화 알림까지 한 경로를 그대로 검증하게 뒀다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(domain): VERIFYING 도메인을 아무도 검증하지 않아 영원히 멈추던 문제
fix(deploy): 결과 웹훅을 놓쳐 IN_PROGRESS 에 멈춘 배포를 회수하도록
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
develop → main. #160 · #161 두 건이고 마이그레이션 변경은 없다.
두 건 다 같은 부류다 — 아무도 밟지 않으면 영원히 그 상태에 머무는 흐름에 밟아 줄 주체를 붙였다.
#160 도메인 VERIFYING 자동 검증
VERIFYING에서CONNECTED로 가는 길은checkVerification호출 하나뿐인데 그것을 밟는 주체가 없었다.domainSummary.url은CONNECTED일 때만 채워지므로, DNS 도 호스팅 설정도 끝나 주소를 직접 치면 열리는 도메인의 링크를 사용자가 영영 못 봤다.DomainVerificationWorker가 1분마다 검증한다.certificateStatus가 영원히ACTIVE가 되지 않는다.dnsConnected && domainConfigured만 본다FAILED#161 멈춘 배포 회수
워커가
PENDING만 집으므로 결과 웹훅을 한 번 놓치면 그 이력은 영구히IN_PROGRESS에 멈춘다. 화면에는 "진행 중"으로도 "실패"로도 보이지 않는다.StuckDeploymentRecoveryWorker가 리스 없는IN_PROGRESS를 1분마다 GitHub 에 직접 물어 확정한다.시간만 보고 닫지 않는다. 원래 사고가 "GitHub 은 성공했는데 우리 이력만 멈춘 것"이었으므로, 시간 기준으로 닫으면 멀쩡히 배포된 것을 실패라고 알리게 된다. 판정을 못 얻은 채 2시간을 넘긴 것만 닫고, 그때 사유도 "실패"가 아니라 "배포 결과를 확인할 수 없습니다"로 적는다.
결과 확정 로직은
DeploymentOutcomeService로 모아 웹훅과 워커가 공유한다.dev 실사용 검증 (2026-08-19)
FE 로컬 → BE dev 로 실제 흐름을 끝까지 돌렸다.
LIVE로 확정되고 대화에 완료 메시지가 붙었다. 어제 fix(deploy): 배포 완료 웹훅이 run-name 때문에 걸러지던 문제 #150(run-name 필터) 수정이 실제로 작동하는 것을 처음 끝까지 확인했다부수적으로 FE 쪽 결함 두 개도 이 과정에서 갈라져 FE 가 수정했다(배포 완료 안내 폴링 교착, 재인증 진입점 부재). 백엔드는 메시지를 붙이고 있었고 화면이 읽지 않던 것이었다.
검증
./gradlew test전체 통과bbff40e,a3857a1)배포 후 주의
두 워커가 운영에서 1분 주기로 돌기 시작한다.
VERIFYING도메인과 리스 없는IN_PROGRESS배포가 있으면 그만큼 Cloudflare·GitHub API 를 쓴다. 배치 상한은 각각 20이고 전부 환경변수로 조절할 수 있다.관련: #162 (동시 요청 토큰 갱신 경합 — 워커가 늘어 창이 넓어졌다)
🤖 Generated with Claude Code