Repository navigation
Claude Post Inventory #97
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
| name: Claude Post Inventory | |
| # 블로그 배포가 끝날 때마다 초안(draft)·예약(scheduled) 글 현황을 이슈 하나에 | |
| # 갱신합니다. 사실 나열만 하며, 발행 권유·재촉은 하지 않습니다. | |
| # | |
| # 역할을 둘로 나눠 둔 이유: | |
| # - 수집(post-inventory-collect.py): frontmatter·git 이력·sitemap 대조 | |
| # - 서술(Claude): 표 렌더링과 이슈 갱신 | |
| # 2026-08-04 수동 실행이 7턴 27초 만에 permission denial 4건으로 끝났는데, | |
| # exit 0이라 잡은 초록이었고 이슈 #163은 7/30 상태 그대로였다. 세는 일을 | |
| # 스크립트로 내리면 그 실패 모드가 사라지고, 수집 결과가 Step Summary에 남는다. | |
| # | |
| # 월간 cron 대신 deploy-blog.yml 완료(workflow_run)를 트리거로 쓴다 — 배포마다 | |
| # sitemap이 갱신되므로 그 직후에 봐야 in_sitemap 판정이 그 시점 기준으로 맞다. | |
| # deploy-blog는 push·매일 cron·수동 실행 전부에서 돌므로 이 워크플로도 그때마다 | |
| # 같이 갱신된다. 배포가 실패하면 sitemap이 그대로이므로 건너뛴다(아래 if). | |
| on: | |
| workflow_run: | |
| # workflow_run은 파일 경로가 아니라 워크플로의 `name`으로 매칭한다 — | |
| # deploy-blog.yml의 name을 고치면 여기도 함께 고쳐야 한다. 어긋나면 | |
| # 실패가 아니라 **아예 실행되지 않아서** Actions 탭에 흔적도 남지 않는다. | |
| workflows: ['Deploy Blog to Cloudflare Workers'] | |
| types: [completed] | |
| workflow_dispatch: | |
| concurrency: | |
| group: claude-post-inventory | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| issues: write | |
| id-token: write | |
| jobs: | |
| inventory: | |
| # workflow_run은 deploy-blog가 실패해도 완료되면 일단 트리거된다. | |
| # 배포 실패 시 sitemap이 갱신되지 않으므로 다시 볼 이유가 없어 건너뛴다. | |
| if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| # 초안이 언제 생겼는지 git 이력으로 계산하기 위해 전체 이력 필요 | |
| fetch-depth: 0 | |
| # workflow_run은 기본 checkout이 default 브랜치 최신 커밋을 받아오지 | |
| # 않으므로, 트리거한 deploy-blog 런의 커밋을 명시한다. workflow_dispatch로 | |
| # 수동 실행할 때는 head_sha가 없으므로 일반 checkout으로 폴백한다. | |
| ref: ${{ github.event.workflow_run.head_sha || github.sha }} | |
| # frontmatter·git 이력·sitemap 대조는 세면 끝나는 일이라 스크립트가 맡는다. | |
| # 2026-08-04 수동 실행이 7턴 27초 만에 denial 4건으로 끝나 이슈가 갱신되지 | |
| # 않았는데, exit 0이라 로그만으로는 정상처럼 보였다. 그 실패 모드를 없앤다. | |
| - name: Collect draft/scheduled facts | |
| run: | | |
| python3 .github/scripts/post-inventory-collect.py \ | |
| --out "${GITHUB_WORKSPACE}/post-inventory-facts.json" | |
| - name: Run Claude post inventory | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| # 예약 실행 잡은 "아무것도 만들지 않음"이 정상 종료라 성공 로그만 | |
| # 남는다. 실행 리포트를 Step Summary에 찍어 두면 무엇을 확인하고 | |
| # 왜 만들지 않았는지를 raw 로그를 펼치지 않고 볼 수 있다. | |
| display_report: true | |
| prompt: | | |
| 당신은 블로그 초안·예약글 인벤토리 담당입니다. 블로그가 배포될 때마다 | |
| 현황을 사실만 기록합니다. 모든 산출물은 한글로 작성하세요. | |
| <중요 — 어조 규칙> | |
| 발행을 권유·재촉·평가하는 문구를 절대 쓰지 마세요. | |
| ("슬슬 발행하면 좋겠다", "오래 방치되었다", "완성도가 높아 보인다" | |
| 전부 금지) 날짜와 상태의 사실 나열만 합니다. 이 저장소 주인의 원칙: | |
| 글은 내용을 완전히 숙지하기 전에는 발행하지 않으며, 그 판단은 | |
| 본인만 합니다. | |
| </중요> | |
| <입력> | |
| `post-inventory-facts.json` (저장소 루트)에 이번 실행의 수집 결과가 | |
| 있습니다. 이 파일을 Read 하세요. 저장소를 다시 훑거나 git·curl을 | |
| 돌릴 필요가 없습니다 — 그런 도구는 주어지지 않습니다. | |
| - `drafts` / `scheduled`: status별 글 목록. 각 항목에 title, series, | |
| date, scheduledDate, publish_at(= scheduledDate ?? date), | |
| first_commit, last_commit, in_sitemap이 들어 있습니다 | |
| - `today_kst`: 오늘 날짜 | |
| - `shallow_clone`: true면 first_commit이 잘린 값이니 표에 "-"로 | |
| 적고 각주를 다세요 (정상 실행에서는 false입니다) | |
| - `sitemap.status`가 200이 아니면 in_sitemap을 신뢰할 수 없습니다. | |
| 그때는 scheduled 표를 그대로 싣되 비고에 "sitemap 조회 실패로 | |
| 배포 여부 미확인"이라고 적으세요 | |
| </입력> | |
| <표에 넣을 것> | |
| - draft: 전부 | |
| - scheduled: `in_sitemap`이 false인 글만. true면 이미 사이트에 | |
| 올라간 글이라 제외합니다. `publish_at`이 `today_kst`보다 과거인데 | |
| in_sitemap이 false면 비고에 "예정일 경과, 배포 대기"라고 적으세요 | |
| </표에 넣을 것> | |
| <산출 — 이슈 하나를 계속 갱신> | |
| 제목이 "📋 블로그 초안·예약글 인벤토리"인 열린 이슈를 찾으세요. | |
| - 있으면 `gh issue edit <번호> --body-file <파일>`로 본문 전체를 | |
| 이번 결과로 교체 | |
| - 없으면 같은 제목으로 새로 생성 | |
| 본문 구성: 갱신 일자 + draft 표 + scheduled 표 (마크다운 표). | |
| 본문 파일은 **하위 디렉터리를 만들지 말고** 작업 디렉터리 루트에 | |
| 바로 쓰세요 (디렉터리 생성은 차단됩니다). | |
| 초안·예약글이 모두 0개인 경우: 기존 이슈가 있으면 "현재 없음"으로 | |
| 갱신하고, 이슈 자체가 없다면 새로 만들지 말고 종료하세요. | |
| </산출> | |
| # 수집이 끝난 뒤라 git·curl이 필요 없다. Bash는 이슈 조작 하나뿐. | |
| claude_args: '--model claude-sonnet-5 --allowed-tools "Read,Write,Grep,Glob,Bash(gh issue:*)"' |