요약
문서를 올렸고, PR을 머지했고, CI도 초록불이었다. 그런데 사이트에는 없었다. 한 달 넘게 “배포 대기”라고 적으며 9건을 이월했는데, 파고들어 보니 기다리던 배포가 애초에 존재하지 않았다.
이 문서는 “올렸다”와 “보인다” 사이에 몇 개의 단계가 숨어 있는지 확인하는 방법이다. 결론부터 말하면, 성공 메시지는 증거가 아니다.
왜 이 기술인가
AI와 함께 일하면 산출물이 빨리 쌓인다. 문서를 만들고, 커밋하고, 푸시하고, 머지한다. 각 단계마다 초록색 체크가 뜬다. 그래서 다 됐다고 믿기 쉽다.
그런데 우리가 실제로 확인한 것은 “내가 한 동작이 성공했다”까지다. 그 동작이 사람이 볼 수 있는 곳까지 갔는지는 다른 문제다. 그 사이에 자동화되지 않은 단계가 하나라도 있으면, 아무도 모르는 채로 몇 주가 지나간다.
단계별 따라하기
1단계. 그 주소가 정말 우리 사이트인지부터 본다
가장 먼저 의심할 것은 배포가 아니라 주소다.
우리 경우, 위키 문서를 머지한 뒤 매번 어떤 주소에서 404를 확인하고 “아직 반영 안 됐네”라고 적었다. 그 주소를 열어 보니 다른 사람의 개인 위키였다. 우리가 올린 문서가 들어갈 자리가 처음부터 없었다.
확인 방법은 단순하다. 사이트 첫 화면을 열어 카테고리 구조를 본다. 우리 문서가 들어갈 분류가 거기 있는가? 없다면 주소가 틀린 것이다.
2단계. 저장소에 발행 장치가 있는지 본다
레포가 웹으로 발행되려면 발행 장치가 있어야 한다. 없으면 레포 자체가 결과물이다.
gh repo view <owner>/<repo> --json homepageUrl,description
gh api repos/<owner>/<repo>/pages # 404면 Pages 미설정
gh workflow list --repo <owner>/<repo> # 비어 있으면 자동 빌드 없음세 가지가 모두 비어 있으면 웹 발행이 없는 저장소다. 그러면 “머지 = 공개”이고, 그 이상 기다릴 것이 없다. 우리는 이걸 몰라서 존재하지 않는 배포를 기다렸다.
3단계. 응답 헤더로 누가 서빙하는지 확인한다
발행 장치가 있는 쪽도 안심하면 안 된다. 실제로 응답하는 서버가 그 장치가 맞는지는 헤더가 알려준다.
curl -sS -I "https://<도메인>/<경로>/" | grep -iE "^(HTTP|Server|Last-Modified)"우리는 GitHub Pages로 배포된다고 믿고 있었는데, 헤더에 Server: Caddy 가 찍혔다. GitHub이 아니라 직접 운영하는 서버가 정적 파일을 서빙하고 있었다. Last-Modified는 열흘 전에 멈춰 있었다.
여기서 그림이 완전히 달라졌다. CI가 아무리 성공해도 그 결과물이 자동으로 그 서버에 가지는 않았던 것이다.
4단계. 사슬을 그리고 자동·수동을 표시한다
원인을 알았으면 단계를 전부 적고 각각 자동인지 수동인지 표시한다. 우리 경우는 이렇게 나왔다.
| 단계 | 내용 | 자동 여부 |
|---|---|---|
| 1 | 소스 저장소에 문서 push | 수동 |
| 2 | CI가 빌드해 산출물 생성 | 자동 |
| 3 | 산출물을 배포용 저장소에 반영 | 수동 |
| 4 | 서버에서 배포 스크립트 실행 | 수동(SSH) |
네 단계 중 자동은 하나뿐이었다. 그런데 우리는 1단계를 하고 2단계가 성공한 것을 보고 “배포됐다”고 적어 왔다.
사슬을 그리면 어디서 끊겼는지와 내가 어디까지 할 수 있는지가 같이 드러난다. 우리는 3단계까지 대신 할 수 있었고(4단계는 서버 접속이 필요해 못 했다), 그 사실을 그대로 보고했다.
5단계. 중간 산출물은 재빌드하지 말고 그대로 옮긴다
3단계를 대신할 때 유혹이 있다. “로컬에서 빌드해서 올리면 되겠네.”
그러지 않는 편이 낫다. 로컬 환경과 CI 환경이 미묘하게 다르면 결과물이 달라지고, 나중에 “왜 사이트가 이상하지”의 원인이 된다. CI가 만든 산출물을 그대로 받아서 올린다.
gh run download <runId> --repo <owner>/<repo> --dir art
tar -xf art/<아티팩트>/artifact.tar -C public
# 배포용 저장소에서 .git만 남기고 지운 뒤 public/* 복사 → commit → push6단계. 완료 보고를 정확한 단어로 적는다
이게 가장 중요하다. 4단계 중 3단계까지 했으면 “배포 완료”가 아니라 “3단계까지 완료, 서버 반영 대기” 라고 적는다.
그리고 확인은 셸로 한다. 사람이나 AI에게 “몇 개 있어?”라고 물으면 어림값이 돌아온다. 우리도 한 번은 79개를 72개로 세어, 나중에 숫자가 바뀐 것처럼 보이는 혼선을 만들었다.
curl -sS -I "<사이트>/sitemap.xml" | grep -iE "^(HTTP|Last-Modified|Server)"
curl -sS "<사이트>/sitemap.xml" | grep -c "<loc>" # 정확한 페이지 수
curl -sS -o /dev/null -w "%{http_code}\n" "<문서 URL>" # 개별 문서 상태코드세 가지를 함께 본다. 페이지가 열리는지만 보면 캐시에 속고, 개수만 보면 어림값에 속는다.
교훈
- 성공 메시지는 증거가 아니다. 내 동작이 성공한 것과 결과가 사람에게 닿은 것은 다른 일이다.
- 404를 봤으면 배포를 의심하기 전에 주소를 의심하라. 우리는 한 달 넘게 남의 사이트에서 우리 문서를 찾고 있었다.
- 헤더를 봐라.
Server와Last-Modified두 줄이면 누가 서빙하는지, 언제 멈췄는지가 나온다. - 사슬을 그리고 자동·수동을 표시하라. 수동 단계는 반드시 잊힌다. 표에 적어 두면 잊혀도 찾을 수 있다.
- 중간 산출물은 재빌드하지 말고 옮겨라. 환경 차이가 만드는 버그는 나중에 원인을 못 찾는다.
- 못 한 것은 못 했다고 적어라. “배포 완료”라고 뭉뚱그리면 다음 사람이 같은 곳에서 또 막힌다.
참고
- 이 진단은 공동위키와 기관 위키 두 곳에 문서를 올리다가, 한쪽이 한 달 넘게 404였던 것을 파고들면서 나왔다. 원인은 두 곳이 서로 다른 방식으로 운영되는데 같은 완료 정의를 쓰고 있었던 것이다.
- 조직 안에 위키나 사이트가 둘 이상이면, 각각의 완료 정의를 따로 적어 두는 것이 이 문제를 미리 막는다. 하나는 “머지가 곧 공개”이고 다른 하나는 “서버 반영까지”일 수 있다.
문서 정리 = 데카(deka2026)