mirror of
https://github.com/rtk-ai/rtk.git
synced 2026-09-19 07:33:17 +08:00
fix(cicd-docs): add agent reviewer + some contribute guidelines
This commit is contained in:
@@ -22,9 +22,9 @@ Trigger: pull_request to develop or master
|
||||
▼ ▼ ▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐ ┌───────────┐ ┌──────────┐
|
||||
│ test │ │Security Scan │ │ benchmark │ │ validate │
|
||||
│ ubuntu │ │ cargo audit │ │ >=80% │ │ docs │
|
||||
│ windows │ │ (blocking) │ │ savings │ │ hooks │
|
||||
│ macos │ │ │ │ │ │ modules │
|
||||
│ ubuntu │ │ cargo audit │ │ >=80% │ │ ai agent │
|
||||
│ windows │ │ (advisory) │ │ savings │ │ doc │
|
||||
│ macos │ │ │ │ │ │ │
|
||||
└──────┬───────┘ └──────┬───────┘ └─────┬─────┘ └────┬─────┘
|
||||
│ │ │ │
|
||||
└────────────────┴───────┬───────┴─────────────┘
|
||||
|
||||
+132
-61
@@ -6,6 +6,7 @@ on:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -200,67 +201,6 @@ jobs:
|
||||
- name: Run benchmark
|
||||
run: ./scripts/benchmark.sh
|
||||
|
||||
validate:
|
||||
name: validate
|
||||
needs: clippy
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Validate documentation consistency
|
||||
run: bash scripts/validate-docs.sh
|
||||
|
||||
- name: Check module count consistency
|
||||
run: |
|
||||
MAIN_MODULES=$(grep -c '^mod ' src/main.rs)
|
||||
|
||||
if [ -f "ARCHITECTURE.md" ]; then
|
||||
ARCH_MODULES=$(grep 'Total:.*modules' ARCHITECTURE.md | grep -o '[0-9]\+' | head -1)
|
||||
if [ -n "$ARCH_MODULES" ] && [ "$MAIN_MODULES" != "$ARCH_MODULES" ]; then
|
||||
echo "Module count mismatch"
|
||||
echo "main.rs: $MAIN_MODULES modules"
|
||||
echo "ARCHITECTURE.md: $ARCH_MODULES modules"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Module count consistent: $MAIN_MODULES modules"
|
||||
|
||||
- name: Verify Python/Go commands documented
|
||||
run: |
|
||||
for cmd in ruff pytest pip go golangci; do
|
||||
if ! grep -q "$cmd" README.md; then
|
||||
echo "README.md missing Python/Go command: $cmd"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "$cmd" CLAUDE.md; then
|
||||
echo "CLAUDE.md missing Python/Go command: $cmd"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "All Python/Go commands documented"
|
||||
|
||||
- name: Verify hook coverage
|
||||
run: |
|
||||
HOOK_FILE=".claude/hooks/rtk-rewrite.sh"
|
||||
if [ ! -f "$HOOK_FILE" ]; then
|
||||
echo "Hook file not found: $HOOK_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -q "rtk rewrite" "$HOOK_FILE"; then
|
||||
echo "Hook does not delegate to 'rtk rewrite'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for cmd in ruff pytest pip golangci; do
|
||||
if ! grep -qr "\"$cmd\"" src/discover/; then
|
||||
echo "Registry missing rewrite_prefixes for: $cmd"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "Hook delegates to rtk rewrite, registry covers all Python/Go commands"
|
||||
|
||||
# ─── DCO: develop PRs only ───
|
||||
|
||||
check:
|
||||
@@ -269,3 +209,134 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: KineticCafe/actions-dco@v1
|
||||
|
||||
# ─── AI Doc Review: develop PRs only ───
|
||||
|
||||
doc-review:
|
||||
name: doc review
|
||||
if: github.base_ref == 'develop'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Gather PR context
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
PR_NUM=${{ github.event.pull_request.number }}
|
||||
gh pr diff "$PR_NUM" --name-only > changed_files.txt
|
||||
gh pr diff "$PR_NUM" | head -c 12000 > diff.txt
|
||||
gh pr view "$PR_NUM" --json title,body --jq '"PR Title: \(.title)\nPR Description: \(.body)"' > pr_info.txt
|
||||
|
||||
- name: AI documentation review
|
||||
env:
|
||||
ANTHROPIC_API_KEY: ${{ secrets.RTK_DOCS_ANTHROPIC_KEY }}
|
||||
run: |
|
||||
echo "## Documentation Review (AI)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [ -z "$ANTHROPIC_API_KEY" ]; then
|
||||
echo "::warning::ANTHROPIC_API_KEY not configured — skipping AI doc review"
|
||||
echo "Skipped: ANTHROPIC_API_KEY secret not configured." >> $GITHUB_STEP_SUMMARY
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CONTRIBUTING=$(cat CONTRIBUTING.md)
|
||||
CHANGED_FILES=$(cat changed_files.txt)
|
||||
DIFF=$(cat diff.txt)
|
||||
PR_INFO=$(cat pr_info.txt)
|
||||
|
||||
SYSTEM_PROMPT=$(cat <<'SYSTEM'
|
||||
You are a documentation reviewer for the RTK project.
|
||||
You will receive the project's CONTRIBUTING.md (which contains the documentation rules), the PR info, changed files, and diff.
|
||||
Your job: based ONLY on the documentation rules in CONTRIBUTING.md, decide if the PR includes the required documentation updates.
|
||||
|
||||
IMPORTANT:
|
||||
- CI/CD changes, test-only changes, and refactors with no user-facing impact do NOT require doc updates.
|
||||
- Be practical, not pedantic. Small obvious fixes don't need CHANGELOG entries.
|
||||
- Only flag missing docs when there is a clear user-facing change.
|
||||
SYSTEM
|
||||
)
|
||||
|
||||
USER_PROMPT=$(printf '%s\n\n---\nCONTRIBUTING.md:\n%s\n\n---\nChanged files:\n%s\n\n---\nDiff (may be truncated):\n%s' \
|
||||
"$PR_INFO" "$CONTRIBUTING" "$CHANGED_FILES" "$DIFF")
|
||||
|
||||
SYSTEM_JSON=$(echo "$SYSTEM_PROMPT" | jq -Rs .)
|
||||
USER_JSON=$(echo "$USER_PROMPT" | jq -Rs .)
|
||||
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" https://api.anthropic.com/v1/messages \
|
||||
-H "content-type: application/json" \
|
||||
-H "x-api-key: $ANTHROPIC_API_KEY" \
|
||||
-H "anthropic-version: 2023-06-01" \
|
||||
-d "{
|
||||
\"model\": \"claude-sonnet-4-6\",
|
||||
\"max_tokens\": 1024,
|
||||
\"messages\": [{\"role\": \"user\", \"content\": $USER_JSON}],
|
||||
\"system\": $SYSTEM_JSON,
|
||||
\"output_config\": {
|
||||
\"format\": {
|
||||
\"type\": \"json_schema\",
|
||||
\"schema\": {
|
||||
\"type\": \"object\",
|
||||
\"properties\": {
|
||||
\"status\": {\"type\": \"string\", \"enum\": [\"PASS\", \"FAIL\"]},
|
||||
\"reasoning\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}},
|
||||
\"files_to_update\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}}
|
||||
},
|
||||
\"required\": [\"status\", \"reasoning\", \"files_to_update\"],
|
||||
\"additionalProperties\": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}")
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||||
BODY=$(echo "$RESPONSE" | sed '$d')
|
||||
|
||||
if [ "$HTTP_CODE" != "200" ]; then
|
||||
echo "::warning::Claude API returned HTTP $HTTP_CODE — skipping doc review"
|
||||
echo "Skipped: API error (HTTP $HTTP_CODE)" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "$BODY" | head -5 >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Parse structured JSON response
|
||||
REVIEW_JSON=$(echo "$BODY" | jq -r '.content[0].text // empty')
|
||||
|
||||
if [ -z "$REVIEW_JSON" ]; then
|
||||
echo "::warning::Empty response from Claude API — skipping doc review"
|
||||
echo "Skipped: empty API response" >> $GITHUB_STEP_SUMMARY
|
||||
exit 0
|
||||
fi
|
||||
|
||||
STATUS=$(echo "$REVIEW_JSON" | jq -r '.status')
|
||||
REASONING=$(echo "$REVIEW_JSON" | jq -r '.reasoning[]' 2>/dev/null)
|
||||
FILES=$(echo "$REVIEW_JSON" | jq -r '.files_to_update[]' 2>/dev/null)
|
||||
|
||||
echo "### Verdict: ${STATUS}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [ -n "$REASONING" ]; then
|
||||
echo "**Reasoning:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "$REASONING" | while IFS= read -r line; do
|
||||
echo "- $line" >> $GITHUB_STEP_SUMMARY
|
||||
done
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [ "$STATUS" = "FAIL" ] && [ -n "$FILES" ]; then
|
||||
echo "**Files to update:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "$FILES" | while IFS= read -r f; do
|
||||
echo "- \`$f\`" >> $GITHUB_STEP_SUMMARY
|
||||
done
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [ "$STATUS" = "FAIL" ]; then
|
||||
echo "::error::Documentation review failed — see summary for details"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -52,6 +52,17 @@ chore(proxy): remove-deprecated-flags
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
### Scope Rules
|
||||
|
||||
**Each PR must focus on a single feature, fix, or change.** The diff must stay in-scope with the description written by the author in the PR title and body. Out-of-scope changes (unrelated refactors, drive-by fixes, formatting of untouched files) must go in a separate PR.
|
||||
|
||||
**For large features or refactors**, prefer multi-part PRs over one enormous PR. Split the work into logical, reviewable chunks that can each be merged independently. Examples:
|
||||
- Part 1: Add data model and tests
|
||||
- Part 2: Add CLI command and integration
|
||||
- Part 3: Update documentation and CHANGELOG
|
||||
|
||||
**Why**: Small, focused PRs are easier to review, safer to merge, and faster to ship. Large PRs slow down review, hide bugs, and increase merge conflict risk.
|
||||
|
||||
### 1. Create Your Branch
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user