chore: LLM wiki 파이프라인 워크플로우 추가 - #562
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Summary by CodeRabbit
Walkthrough수동 실행형 ChangesLLM Wiki Pipeline 자동화
Estimated code review effort: 5 (Critical) | ~90+ minutes Sequence Diagram(s)sequenceDiagram
participant Runner as GitHub Actions runner
participant Scaffold as 고정 스캐폴더
participant Claude as Claude
participant DocsLint as docs-lint
participant GitHubAPI as GitHub REST API
Runner->>Scaffold: 지식 베이스 스캐폴딩 실행
Runner->>Claude: 변경 범위와 제한된 도구 전달
Claude->>Runner: 문서 및 AGENTS.md 생성
Runner->>DocsLint: docs-lint --json 실행
DocsLint->>Runner: 링크 및 orphan atom 결과 반환
Runner->>Claude: 보정 대상 문서 전달
Claude->>Runner: 문서 보정 결과 반환
Runner->>DocsLint: docs-lint --strict 실행
DocsLint->>Runner: 검증 결과 반환
Runner->>GitHubAPI: 검증된 변경 사항으로 PR 생성 또는 갱신
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
.github/workflows/llm-wiki-pipeline.yml (1)
544-549: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
Read전역 허용과persist-credentials: true가 겹칩니다. deny 규칙으로.git을 차단하세요.Line 77-82의 주석이 지적한 대로 token은
.git/config에 남고, 현재Read에는 경로 제한이 없습니다.claude-code-action@v1의claude_args는--disallowedTools를 전달하며 deny 규칙이 allow 규칙보다 우선하므로,.git경로를 명시적으로 차단해야 합니다.claude_args: | - --allowedTools "Read,Write,Edit,Bash(rg:*),Bash(grep:*),Bash(node scripts/docs-lint.mjs:*),Bash(node scripts/owners-from-git.mjs:*),Bash(git log:*),Bash(git diff:*),Bash(git show:*),Bash(git blame:*),Bash(git shortlog:*)" + --allowedTools "Read,Write,Edit,Bash(rg:*),Bash(grep:*),Bash(node scripts/docs-lint.mjs:*),Bash(node scripts/owners-from-git.mjs:*),Bash(git log:*),Bash(git diff:*),Bash(git show:*),Bash(git blame:*),Bash(git shortlog:*)" + --disallowedTools "Read(./.git/**)"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/llm-wiki-pipeline.yml around lines 544 - 549, Update the claude_args configuration to add a --disallowedTools deny rule covering .git paths, while preserving the existing allowed tools and persist-credentials behavior. Ensure the deny rule blocks Read access to .git and takes precedence over the global Read allowance.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/llm-wiki-pipeline.yml:
- Around line 889-899: Update the human-commit detection block around HUMAN so
git log failures are captured and checked separately instead of being suppressed
by `|| true`; abort the workflow when `origin/${BASE_BRANCH}..origin/${BRANCH}`
cannot be evaluated, and only perform the existing HUMAN-based branch split
after a successful git log.
- Around line 378-382: Update the Scaffold step’s environment to expose the
existing agents_state value, then adjust the AGENTS.md restoration condition in
the non-full MODE branch to skip checkout when agents_state is human. Preserve
restoration for other states so intentionally removed human-managed documents
are not reintroduced.
- Around line 305-318: Update the classification condition preceding the
CK=agents_target assignment to also require that CLAUDE.md is not a symlink.
This preserves agents_target only when AGENTS.md points to the regular CLAUDE.md
file, allowing CLAUDE.md → AGENTS.md repositories to reach the existing symlink
handling branch and be restored correctly.
---
Nitpick comments:
In @.github/workflows/llm-wiki-pipeline.yml:
- Around line 544-549: Update the claude_args configuration to add a
--disallowedTools deny rule covering .git paths, while preserving the existing
allowed tools and persist-credentials behavior. Ensure the deny rule blocks Read
access to .git and takes precedence over the global Read allowance.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d1b56076-04df-4cb5-be40-07f7d0bd50ff
📒 Files selected for processing (1)
.github/workflows/llm-wiki-pipeline.yml
| AGENTS_FILE_REAL=$(readlink -f -- "$AGENTS_FILE" 2>/dev/null || echo "") | ||
| CLAUDE_REAL=$(readlink -f -- CLAUDE.md 2>/dev/null || echo "") | ||
| if [ -n "$AGENTS_FILE_REAL" ] && [ "$AGENTS_FILE_REAL" = "$CLAUDE_REAL" ]; then | ||
| # AGENTS.md 심링크의 대상이 CLAUDE.md 인 경우. 마커 블록이 이 파일에 | ||
| # 들어가므로 별도 포인터 블록도, 심링크 변환도 필요 없다. | ||
| CK=agents_target | ||
| elif [ -L CLAUDE.md ]; then | ||
| CK=symlink | ||
| elif [ -f CLAUDE.md ]; then | ||
| sed -e '/<!-- BEGIN: llm-wiki/,/<!-- END: llm-wiki/d' CLAUDE.md > "$RUNNER_TEMP/CLAUDE.body.md" | ||
| # `|| echo 0` 금지 — 위 HUMAN_LINES 주석 참고(값이 "0\n0" 이 된다). | ||
| N=$(awk 'NF' "$RUNNER_TEMP/CLAUDE.body.md" 2>/dev/null | wc -l | tr -d ' ') | ||
| if [ "${N:-0}" -gt 5 ]; then CK=human; else CK=pointer; fi | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
CLAUDE.md → AGENTS.md 심링크 저장소에서 CK 가 agents_target 으로 오분류됩니다.
readlink -f 는 대상 경로가 없어도 정규화된 경로를 반환합니다. CLAUDE.md 가 AGENTS.md 를 가리키는 심링크이면 CLAUDE_REAL 과 AGENTS_FILE_REAL 이 모두 <repo>/AGENTS.md 로 같아집니다. 따라서 Line 307 조건이 먼저 참이 되고, Line 311 의 [ -L CLAUDE.md ] 분기에 도달하지 못합니다.
결과는 다음과 같습니다. Line 328-332 는 CK 와 무관하게 CLAUDE.md 심링크를 삭제합니다. 그러나 Handle 스텝의 agents_target 분기(Line 824-825)는 "추가 작업 없음"으로 끝납니다. 심링크가 복원되지 않고, CLAUDE.md 삭제가 그대로 커밋됩니다. 주석 Line 323-326 이 언급한 laas-one-frontend 가 정확히 이 형태입니다.
의도한 agents_target 케이스는 AGENTS.md 가 심링크이고 대상이 실파일 CLAUDE.md 인 경우(wanted-server)입니다. 그 경우 CLAUDE.md 는 심링크가 아니므로, [ ! -L CLAUDE.md ] 를 조건에 추가하면 두 형태가 정확히 분리됩니다.
🐛 제안 수정
AGENTS_FILE_REAL=$(readlink -f -- "$AGENTS_FILE" 2>/dev/null || echo "")
CLAUDE_REAL=$(readlink -f -- CLAUDE.md 2>/dev/null || echo "")
- if [ -n "$AGENTS_FILE_REAL" ] && [ "$AGENTS_FILE_REAL" = "$CLAUDE_REAL" ]; then
+ if [ ! -L CLAUDE.md ] && [ -n "$AGENTS_FILE_REAL" ] && [ "$AGENTS_FILE_REAL" = "$CLAUDE_REAL" ]; then
# AGENTS.md 심링크의 대상이 CLAUDE.md 인 경우. 마커 블록이 이 파일에
# 들어가므로 별도 포인터 블록도, 심링크 변환도 필요 없다.
CK=agents_target📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| AGENTS_FILE_REAL=$(readlink -f -- "$AGENTS_FILE" 2>/dev/null || echo "") | |
| CLAUDE_REAL=$(readlink -f -- CLAUDE.md 2>/dev/null || echo "") | |
| if [ -n "$AGENTS_FILE_REAL" ] && [ "$AGENTS_FILE_REAL" = "$CLAUDE_REAL" ]; then | |
| # AGENTS.md 심링크의 대상이 CLAUDE.md 인 경우. 마커 블록이 이 파일에 | |
| # 들어가므로 별도 포인터 블록도, 심링크 변환도 필요 없다. | |
| CK=agents_target | |
| elif [ -L CLAUDE.md ]; then | |
| CK=symlink | |
| elif [ -f CLAUDE.md ]; then | |
| sed -e '/<!-- BEGIN: llm-wiki/,/<!-- END: llm-wiki/d' CLAUDE.md > "$RUNNER_TEMP/CLAUDE.body.md" | |
| # `|| echo 0` 금지 — 위 HUMAN_LINES 주석 참고(값이 "0\n0" 이 된다). | |
| N=$(awk 'NF' "$RUNNER_TEMP/CLAUDE.body.md" 2>/dev/null | wc -l | tr -d ' ') | |
| if [ "${N:-0}" -gt 5 ]; then CK=human; else CK=pointer; fi | |
| fi | |
| AGENTS_FILE_REAL=$(readlink -f -- "$AGENTS_FILE" 2>/dev/null || echo "") | |
| CLAUDE_REAL=$(readlink -f -- CLAUDE.md 2>/dev/null || echo "") | |
| if [ ! -L CLAUDE.md ] && [ -n "$AGENTS_FILE_REAL" ] && [ "$AGENTS_FILE_REAL" = "$CLAUDE_REAL" ]; then | |
| # AGENTS.md 심링크의 대상이 CLAUDE.md 인 경우. 마커 블록이 이 파일에 | |
| # 들어가므로 별도 포인터 블록도, 심링크 변환도 필요 없다. | |
| CK=agents_target | |
| elif [ -L CLAUDE.md ]; then | |
| CK=symlink | |
| elif [ -f CLAUDE.md ]; then | |
| sed -e '/<!-- BEGIN: llm-wiki/,/<!-- END: llm-wiki/d' CLAUDE.md > "$RUNNER_TEMP/CLAUDE.body.md" | |
| # `|| echo 0` 금지 — 위 HUMAN_LINES 주석 참고(값이 "0\n0" 이 된다). | |
| N=$(awk 'NF' "$RUNNER_TEMP/CLAUDE.body.md" 2>/dev/null | wc -l | tr -d ' ') | |
| if [ "${N:-0}" -gt 5 ]; then CK=human; else CK=pointer; fi | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/llm-wiki-pipeline.yml around lines 305 - 318, Update the
classification condition preceding the CK=agents_target assignment to also
require that CLAUDE.md is not a symlink. This preserves agents_target only when
AGENTS.md points to the regular CLAUDE.md file, allowing CLAUDE.md → AGENTS.md
repositories to reach the existing symlink handling branch and be restored
correctly.
| if [ "$MODE" != "full" ]; then | ||
| git checkout -- "$DOCS_ROOT" 2>/dev/null || true | ||
| git checkout -- AGENTS.md 2>/dev/null || true | ||
| git clean -fdq "$DOCS_ROOT" 2>/dev/null || true | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
diff/skip 모드에서 사람이 작성한 AGENTS.md 가 두 번 삽입될 수 있습니다.
agents_state=human 인 저장소의 흐름을 추적하면 다음과 같습니다.
- Snapshot(Line 266, 280): 원본 전체를
$RUNNER_TEMP/AGENTS.human.md로 복사하고AGENTS.md를 제거합니다.SEED는 비어 있습니다. - Scaffold(Line 380):
MODE != full이므로git checkout -- AGENTS.md가 HEAD 의 사람 원본을 되살립니다. - Reduce(Line 452):
SEED가 비어 있으므로elif [ -f AGENTS.md ]분기를 타고, 되살아난 사람 원본을 그대로 Claude 시드로 사용합니다. Line 457-460 은 경고만 출력하고 진행합니다. - Reassemble(Line 764-769):
HUMAN(사람 원본) 위에 마커 블록으로 감싼AGENTS.pipe.md(같은 사람 원본)를 붙입니다.
결과적으로 사람 문서가 파일 안에 중복됩니다. full 모드는 Line 380 을 실행하지 않으므로 이 경로가 발생하지 않습니다.
Snapshot 이 AGENTS.md 를 의도적으로 치운 경우에는 되살리지 않도록, agents_state 를 조건에 반영하는 것이 안전합니다.
🐛 제안 수정
Scaffold 스텝 env 에 상태 값을 전달합니다.
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MODE: ${{ steps.scope.outputs.mode }}
AGENTS_FILE: ${{ steps.snapshot.outputs.agents_file }}
+ AGENTS_STATE: ${{ steps.snapshot.outputs.agents_state }}원복 조건에서 human 상태를 제외합니다.
if [ "$MODE" != "full" ]; then
git checkout -- "$DOCS_ROOT" 2>/dev/null || true
- git checkout -- AGENTS.md 2>/dev/null || true
+ # state=human 이면 Snapshot 이 원본을 HUMAN 에 보관하고 파일을 치웠다.
+ # 여기서 되살리면 Reduce 가 사람 원본을 시드로 집어 재조립 때 중복된다.
+ if [ "${AGENTS_STATE:-}" != "human" ]; then
+ git checkout -- AGENTS.md 2>/dev/null || true
+ fi
git clean -fdq "$DOCS_ROOT" 2>/dev/null || true
fi🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/llm-wiki-pipeline.yml around lines 378 - 382, Update the
Scaffold step’s environment to expose the existing agents_state value, then
adjust the AGENTS.md restoration condition in the non-full MODE branch to skip
checkout when agents_state is human. Preserve restoration for other states so
intentionally removed human-managed documents are not reintroduced.
| # [A] checkout(fetch-depth: 0)이 refs/remotes/origin/* 을 이미 모두 가져왔으므로 | ||
| # 추가 fetch 없이 존재 여부만 확인한다. fetch 실패가 "사람 커밋 보호" 가드를 | ||
| # 조용히 끈 채로 force push 가 진행되는 경로를 구조적으로 제거한다. | ||
| if git rev-parse --verify --quiet "refs/remotes/origin/${BRANCH}" >/dev/null; then | ||
| HUMAN=$(git log --format='%ae' "origin/${BASE_BRANCH}..origin/${BRANCH}" \ | ||
| | grep -v 'github-actions\[bot\]@users.noreply.github.com' | head -1 || true) | ||
| if [ -n "$HUMAN" ]; then | ||
| BRANCH="${DOCS_BRANCH}-${GITHUB_RUN_ID}" | ||
| echo "::notice::기존 브랜치에 사람 커밋($HUMAN)이 있어 ${BRANCH} 로 분기합니다." | ||
| fi | ||
| fi |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
사람 커밋 보호 가드가 git log 실패를 "사람 커밋 없음"으로 처리합니다.
Line 893-894 의 파이프라인은 || true 로 모든 실패를 흡수합니다. origin/${BASE_BRANCH} 가 없으면(기본 브랜치 개명·삭제) git log 가 실패하고 HUMAN 이 빈 문자열이 됩니다. 그러면 브랜치 분기가 일어나지 않고, Line 938 의 --force-with-lease push 가 기존 브랜치를 덮어씁니다. 이는 Line 890-891 주석이 제거하려던 경로와 같은 형태입니다.
git log 의 종료 코드를 분리해서 확인하면 이 경로가 닫힙니다.
🛡️ 제안 수정
if git rev-parse --verify --quiet "refs/remotes/origin/${BRANCH}" >/dev/null; then
- HUMAN=$(git log --format='%ae' "origin/${BASE_BRANCH}..origin/${BRANCH}" \
- | grep -v 'github-actions\[bot\]`@users.noreply.github.com`' | head -1 || true)
+ if ! git rev-parse --verify --quiet "refs/remotes/origin/${BASE_BRANCH}" >/dev/null; then
+ echo "::error::origin/${BASE_BRANCH} 가 없어 사람 커밋 여부를 판정할 수 없습니다 — force push 를 중단합니다."
+ exit 1
+ fi
+ AUTHORS="$RUNNER_TEMP/branch-authors.txt"
+ git log --format='%ae' "origin/${BASE_BRANCH}..origin/${BRANCH}" > "$AUTHORS"
+ HUMAN=$(grep -v 'github-actions\[bot\]`@users.noreply.github.com`' "$AUTHORS" | head -1 || true)
if [ -n "$HUMAN" ]; then
BRANCH="${DOCS_BRANCH}-${GITHUB_RUN_ID}"
echo "::notice::기존 브랜치에 사람 커밋($HUMAN)이 있어 ${BRANCH} 로 분기합니다."
fi
fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # [A] checkout(fetch-depth: 0)이 refs/remotes/origin/* 을 이미 모두 가져왔으므로 | |
| # 추가 fetch 없이 존재 여부만 확인한다. fetch 실패가 "사람 커밋 보호" 가드를 | |
| # 조용히 끈 채로 force push 가 진행되는 경로를 구조적으로 제거한다. | |
| if git rev-parse --verify --quiet "refs/remotes/origin/${BRANCH}" >/dev/null; then | |
| HUMAN=$(git log --format='%ae' "origin/${BASE_BRANCH}..origin/${BRANCH}" \ | |
| | grep -v 'github-actions\[bot\]@users.noreply.github.com' | head -1 || true) | |
| if [ -n "$HUMAN" ]; then | |
| BRANCH="${DOCS_BRANCH}-${GITHUB_RUN_ID}" | |
| echo "::notice::기존 브랜치에 사람 커밋($HUMAN)이 있어 ${BRANCH} 로 분기합니다." | |
| fi | |
| fi | |
| # [A] checkout(fetch-depth: 0)이 refs/remotes/origin/* 을 이미 모두 가져왔으므로 | |
| # 추가 fetch 없이 존재 여부만 확인한다. fetch 실패가 "사람 커밋 보호" 가드를 | |
| # 조용히 끈 채로 force push 가 진행되는 경로를 구조적으로 제거한다. | |
| if git rev-parse --verify --quiet "refs/remotes/origin/${BRANCH}" >/dev/null; then | |
| if ! git rev-parse --verify --quiet "refs/remotes/origin/${BASE_BRANCH}" >/dev/null; then | |
| echo "::error::origin/${BASE_BRANCH} 가 없어 사람 커밋 여부를 판정할 수 없습니다 — force push 를 중단합니다." | |
| exit 1 | |
| fi | |
| AUTHORS="$RUNNER_TEMP/branch-authors.txt" | |
| git log --format='%ae' "origin/${BASE_BRANCH}..origin/${BRANCH}" > "$AUTHORS" | |
| HUMAN=$(grep -v 'github-actions\[bot\]`@users.noreply.github.com`' "$AUTHORS" | head -1 || true) | |
| if [ -n "$HUMAN" ]; then | |
| BRANCH="${DOCS_BRANCH}-${GITHUB_RUN_ID}" | |
| echo "::notice::기존 브랜치에 사람 커밋($HUMAN)이 있어 ${BRANCH} 로 분기합니다." | |
| fi | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/llm-wiki-pipeline.yml around lines 889 - 899, Update the
human-commit detection block around HUMAN so git log failures are captured and
checked separately instead of being suppressed by `|| true`; abort the workflow
when `origin/${BASE_BRANCH}..origin/${BRANCH}` cannot be evaluated, and only
perform the existing HUMAN-based branch split after a successful git log.
23c44cb to
f34e72f
Compare
f34e72f to
508cca5
Compare
docs/ 자동 생성용 workflow_dispatch 트리거를 추가합니다. 실행은 수동 트리거로만 발생하며, 자동 배포되지 않습니다.
주의: workflow_dispatch 는 워크플로우 파일이 default branch(
main)에 있어야 Actions UI 에 나타납니다. 이 PR 을 머지한 뒤 실행할 수 있습니다.