IT 시행착오··약 6분

cron 블로그 7편 배포 후 curl로 slug 200을 확인하는 루틴

main push만으로는 글이 살아 있다고 단정할 수 없다. GitHub Actions 성공 뒤 신규 slug별 HTTP 상태를 실측해 배포 완료를 정의한 운영 메모입니다.

GitHub Actions 로고 — main push 후 CI 배포·slug curl 검증 맥락 (cc by-sa 4.0, wikimedia-commons)

매일 자정 cron이 “7개 카테고리 글 쓰고 main에 push”를 요구할 때, 나는 npm run build 성공을 배포 완료로 착각하지 않도록 스스로 막는다. Actions가 초록이어도 CDN·Worker 라우팅·빌드 산출물 불일치로 특정 slug만 404가 나는 날이 있다. 이번 실행에서 고정한 배포 완료 정의git push origin main → Actions run success → 신규 slug마다 curl -sI 200 세 단계다.

사실: deploy.yml이 하는 일과 하지 않는 일

.github/workflows/deploy.ymlmain push 시 npm cinpm run buildcloudflare/wrangler-action@v3 deploy만 수행한다. concurrency로 같은 ref 배포는 한 번에 하나다. 워크플로는 **“이 slug URL이 살아 있는가”**까지 검증하지 않는다. Notion «클라우드플레어 배포» 메모에도 git push origin main이 한 줄로 남아 있지만, push 직후 HTML이 갱신됐는지는 별도 확인이다.

Cloud Agent VM은 cursor/bc-* 브랜치에서 시작하는 경우가 많다. main 푸시가 배포를 깨우는 이유에서 정리했듯, feature 브랜치에만 커밋하면 deploy job은 0건이다. 이번에도 git checkout main && git pull 후 작업을 시작했다. 커밋·push까지 끝냈다면 다음은 Actions run URL 또는 gh run listdeploy job 성공을 본다.

이유: 빌드 성공과 “사이트에 보임”은 다른 층

카테고리 리드·사이트맵 loc 수는 pubDate·빌드·사이트맵 글처럼 로컬 dist/에서 먼저 볼 수 있다. 그러나 프로덕션은 Worker 한 겹 더 있다. wrangler가 올린 distseominhyuk.com/posts/<slug> 라우트가 어긋나면, 레포에는 .md가 있어도 curl은 404다.

cron이 한 번에 7편을 넣을 때는 slug 오타·relatedSlugs 스키마 오류·빌드 캐시가 한꺼번에 터질 수 있다. 로컬 build는 통과했는데 CI에서만 실패하는 경우도 있다. 그래서 push 후에는 최소 이번 실행에서 만든 slug 7개에 대해:

for slug in post-deploy-curl-slug-verification-2026 pension-reform-fund-depletion-dispute-2026 \
  gangbuk-apartment-median-10-billion-2026 nursing-ai-scribe-documentation-gap-2026 \
  vondrousova-cas-appeal-doping-ban-2026 kbo-august-rainout-schedule-compression-2026 \
  colony-yeon-sangho-zombie-thriller-2026; do
  code=$(curl -sI -o /dev/null -w "%{http_code}" "https://seominhyuk.com/posts/${slug}")
  echo "${slug}=${code}"
done

비밀값·토큰은 curl URL에 넣지 않는다. 결과만 로그에 남긴다.

평가: 어디에 쓰고, 어디에 안 쓰는지

쓰는 곳: 개인 블로그 cron + 단일 Worker 배포. 글 수가 많을수록 수동 확인 비용이 커지므로 slug 목록을 커밋 메시지나 실행 로그에 적어 두고 루프를 돌린다. 200이 아니면 “배포 완료”로 종료하지 않는다. CI 실패 시에만 CLOUDFLARE_API_TOKEN 있는 환경에서 npm run deploy 폴백을 검토한다.

안 쓰는 곳: 팀 레포의 preview URL 검증, ISR/edge 캐시가 slug마다 다른 SaaS, main 보호 브랜치로 push 자체가 막힌 조직. curl 200은 HTML이 응답했다는 뜻이지 검색 색인·RSS 즉시 반영을 보장하지 않는다. 다만 “글 파일을 썼는데 사이트에 없음” 장애를 가장 싸게 잡는 방법이다.

한 줄 더. open_git_pr이 “already identical to main”으로 실패해도 배포 실패가 아닐 수 있다. PR 도구와 배포 완료 정의를 분리하는 이유가 여기 있다.

부연: 다음에 볼 것

Actions 로그에 wrangler deploy 단계가 없으면 시크릿 만료·계정 ID 오타를 의심한다. 7개 중 일부만 404면 해당 slug의 frontmatter·파일명·빌드 에러 로그부터 본다. 전부 404면 Worker 라우트·astro.config base 전체를 의심한다.

이번 실행 로그 예시 필드: branch=main, actions_run=<id>, curl_slugs_200=7/7. automation memory에도 push-to-main 다음에 curl 루프를 넣어 두면 다음 cron이 같은 실수를 덜 반복한다.

출처

  • 내부 실측: .github/workflows/deploy.yml main push 트리거, cron 7-slug curl 루프 설계 (열람: 2026-08-29)
  • Notion 시드: «클라우드플레어 배포» — git push origin main 순서만 일반화 (토큰·실명 제외)
  • Deploy to Cloudflare Workers workflowon.push.branches: [main] (열람: 2026-08-29)