main 푸시에 Wrangler가 붙었다 — GitHub Actions로 배포 간극을 메운 기록
Workers Builds 0건 상태에서 cron은 글만 main에 올리고 사이트는 그대로였다. deploy.yml과 wrangler-action@v3를 연결한 뒤 push→build→deploy 한 줄기를 레포 실측으로 정리합니다.

Workers Builds가 0건일 때 main 푸시와 seominhyuk.com HTML 사이에 빈 구간이 있다고 적었다. 그때 해결책 후보 첫 번째가 “GitHub Actions에 npm run deploy를 연결”이었다. 이번에 .github/workflows/deploy.yml을 main에 올리고, push 트리거 → npm ci → npm run build → wrangler deploy 순서를 Actions로 고정했다. Notion «클라우드플레어 배포» 메모에는 “깃허브에 자동 배포(워커는 별도)”라는 문장만 남아 있었고, 비밀값·토큰 원문은 글에 넣지 않는다(C.9). 여기서는 레포에 실제로 들어간 워크플로와 그 전후를 실측 관점으로만 정리한다.
사실: 워크플로가 하는 일
deploy.yml은 main 브랜치 push와 workflow_dispatch에 반응한다. concurrency로 같은 ref의 배포는 한 번에 하나만 돌게 막았다.
- name: Build
run: npm run build
- name: Deploy Worker
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy
레포 루트 package.json의 deploy는 여전히 npm run build && wrangler deploy다. Actions는 build를 한 번 돌린 뒤 wrangler-action에 command: deploy만 넘긴다. wrangler.jsonc는 assets.directory: "./dist"로 Astro 산출물을 Workers 정적 자산으로 올린다. 시크릿 이름은 저장소 Settings에만 두고, 커밋·PR·블로그 본문에는 CLOUDFLARE_API_TOKEN 값을 적지 않는다.
이전 상태와 비교하면 이렇다. (1) cron/에이전트가 md를 main에 push → (2) 예전: Worker 버전은 그대로, 새 slug는 404 → (3) 지금: Actions가 같은 커밋에서 build·deploy → (4) curl -sI https://seominhyuk.com/posts/<slug>가 200을 기대할 수 있다. Cloud Agent VM에 토큰이 없어도 저장소 시크릿만 맞으면 push만으로 프로덕션이 따라온다.
이유: “발행 완료” 정의를 한 단계로 줄였다
오토메이션 글쓰기 규칙(F절)은 src/content/posts/ 작성 → build → 커밋·푸시·배포까지를 한 사이클로 본다. Workers Builds가 Git과 연결되지 않은 동안은 “푸시 = 소스 저장”과 “배포 = Wrangler 실행”이 분리돼 있었다. 그래서 run 로그에 “발행 완료”를 남겨도 독자 URL은 며칠 뒤까지 404인 일이 반복됐다.
Actions로 묶으면 실패 지점이 명확해진다. build 실패면 deploy 단계까지 가지 않는다. deploy 실패면 GitHub Actions 탭에 빨간 X가 남고, 어느 SHA가 라이브에 안 올라갔는지 추적할 수 있다. Wrangler를 손으로 돌리던 날의 비상 레일은 유지하되, 기본 경로는 CI가 맡는 구조다.
반례도 있다. PR 브랜치만 갱신하고 main에 merge·push하지 않으면 Actions deploy는 돌지 않는다. fork PR에서 시크릿이 막혀 wrangler-action이 실패하는 설정도 흔하다. “워크플로 파일이 있다”와 “매 push마다 성공한다”는 다르다.
평가: 어디에 쓰고, 어디에 안 쓰는지
쓰는 곳: Astro 정적 블로그 + Workers assets, main 단일 프로덕션 브랜치, cron/에이전트가 직접 main에 push하는 레포. 토큰을 사람 채팅·Notion·커밋에 넣지 않고 GitHub Secrets에만 두는 팀.
안 쓰는 곳: preview URL마다 다른 Worker를 띄워야 할 때(브랜치별 deploy 전략 필요), deploy 전 수동 승인 게이트가 규정으로 필수일 때, npm run build가 외부 API·Notion에 의존해 CI에서 불안정할 때.
한계: Actions 분(minutes)과 Wrangler 업로드 시간은 push마다 든다. concurrency cancel-in-progress는 연속 push 시 중간 커밋 deploy가 취소될 수 있다. cron이 7편을 연속 push하면 마지막 SHA만 살아남는지 확인할 필요가 있다. Pagefind·콘텐츠 스키마 오류는 build 단계에서 걸러지므로, deploy 성공 전에 npm run build 로컬 재현 습관은 그대로 유효하다.
부연: 발행 후 스모크
푸시 후 최소 네 가지를 본다. GitHub Actions run이 success인가 → run 로그에 static asset 업로드 수가 보이는가 → 홈 curl -sI가 200인가 → 이번 run에서 추가한 slug /posts/...가 200인가. 네 번째가 빠지면 “빌드는 됐는데 라우팅·slug 오타”를 의심한다. relatedSlugs 침묵 버그처럼 HTML은 200인데 UI만 비는 경우도 build 스모크와 분리해 본다.
다음 관찰 포인트: Workers Builds 대시보드에 Git 연동 이력이 생기는지, 아니면 Actions만 deploy 주체로 남는지. 둘 다 켜면 이중 배포·경합 가능성이 있다. 지금 레포는 Actions + wrangler deploy 한 줄기를 기준으로 삼는 편이 단순하다.
출처
- 내부 실측:
.github/workflows/deploy.yml,package.jsonscripts.deploy,wrangler.jsoncassets.directory (2026-08-26, 비밀값 제외) - Notion 시드: «클라우드플레어 배포» — 자동 배포 개념만 참고, 토큰·계정 ID는 미인용
- Cloudflare wrangler-action (GitHub) — 열람: 2026-08-26