Conversation
git push 가 exec 로 돌고 있었는데 그 메서드는 종료 코드를 읽지 않는다. 인증 실패든 보호 브랜치든 그냥 문자열이 돌아왔고, 호출자는 성공으로 알고 다음으로 갔다. 그 대가가 크다. 감사 로그에는 PREVIEW_BRANCH_PUSHED 가 성공으로 남고, 사용자에게는 "작업물을 preview 브랜치에 올렸습니다 — 프리뷰가 만료돼도 코드는 남습니다"가 표시된다. 실제로는 아무것도 올라가지 않았고, 컨테이너가 만료되면 작업물은 사라진다. 사용자는 안전하다고 들은 것을 잃는다. CLAUDE.md 에 적힌 "push 실패 시 스텝이 완료로 넘어가지 않는다"는 보장도 실제로는 성립하지 않았다. 그 문장은 push 실패가 예외로 올라올 때만 참이다. 실패가 의미 있는 단계만 execWithExitCode 로 바꾸고 비-0 이면 던진다 — git init, remote add/set-url, checkout -B, add, commit, push. apk add 와 git config 는 그대로 둔다. 이미 git 이 깔려 있거나 이미지가 alpine 이 아닐 수 있어서, 그것까지 실패로 보면 멀쩡히 돌던 컨테이너에서 푸시가 막힌다 — 정말 git 이 없으면 뒤의 strict 단계가 드러낸다. commit 은 변경이 없으면 git diff --cached --quiet 가 0 으로 끝나 건너뛴다. 변경이 있으면 1 을 주고 커밋이 돌며 그 커밋이 실패해야 비-0 이 된다. 그래서 strict 로 둬도 "고칠 것이 없었다"가 오류가 되지 않는다. 예외 메시지에는 명령 전문을 넣지 않는다. 이 클래스는 자격 증명을 다루고, 메시지는 로그와 사용자 화면으로 흘러간다 — 단계 이름과 git 출력만 남긴다. 호출부는 이미 이 예외를 전제로 쓰여 있었다. ResultApprovalGate 는 javadoc 에 AgentPlanExecutor 의 catch-all 로 전파돼 태스크가 FAILED 가 된다고 적어뒀고, RepositoryBindingService 는 "push 가 실패하면 트랜잭션이 통째로 롤백된다"를 근거로 연결 저장을 push 앞에 둔다. 저장소 생성도 repositoryExists 로 멱등이라 재시도가 같은 저장소를 재사용한다. 설계는 이미 그렇게 돼 있었고 예외만 오지 않았다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(agent): preview 브랜치 push 실패가 성공으로 보고되던 문제
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. #174 하나뿐이고 마이그레이션 변경은 없다.
무엇을 고치나
git push가 종료 코드를 읽지 않는exec로 돌아서, 실패해도 호출자가 성공으로 알았다.그 결과 사용자에게 이렇게 안내된다.
push 가 실패했다면 거짓이다. 컨테이너가 만료되는 순간 작업물이 사라지고, 감사 로그에는
PREVIEW_BRANCH_PUSHED가 성공으로 남아 추적도 안 된다. 안전하다고 들은 것을 잃는다.해결
실패가 의미 있는 단계만
execWithExitCode로 바꾸고 비-0 이면 던진다(git init,remote add/set-url,checkout -B,add,commit,push).apk add와git config는 그대로 둔다 — 이미 git 이 있거나 이미지가 alpine 이 아닐 수 있어 그것까지 실패로 보면 멀쩡한 컨테이너에서 푸시가 막힌다.예외 메시지에는 명령 전문을 넣지 않는다. 이 클래스는 자격 증명을 다루고 메시지는 로그와 화면으로 흘러간다.
호출부는 이미 이 예외를 전제로 쓰여 있었다
ResultApprovalGatejavadoc: 예외가AgentPlanExecutorcatch-all 로 전파돼 태스크 FAILED(재시도 가능)RepositoryBindingService: "push 가 실패하면 트랜잭션이 통째로 롤백되므로" 를 근거로 연결 저장을 push 앞에 둔다repositoryExists로 멱등이라 재시도가 같은 저장소를 재사용한다설계는 그렇게 돼 있었고 예외만 오지 않았다. CLAUDE.md 의 "push 실패 시 스텝이 완료로 넘어가지 않는다"도 이제 참이 된다.
검증
DeployAgentServiceTest갱신./gradlew test전체 통과, CI 통과, dev 배포 성공(2dc6c9f) 및 기동 확인(200)🤖 Generated with Claude Code