1- name : Claude Code Documentation Review
1+ name : Claude Documentation Review
22
33on :
4- # Trigger on pull requests to main or dev branch
54 pull_request :
6- branches :
7- - main
8- - dev
5+ branches : [main, dev]
96 paths-ignore :
107 - ' **.md'
118 - ' **.mdx'
129
13- # Trigger on issue comments (for tagging)
1410 issue_comment :
1511 types : [created]
1612
17- # Trigger on PR review comments
1813 pull_request_review_comment :
1914 types : [created]
2015
2116jobs :
2217 claude-review :
23- # Only run if it's a PR or if the comment contains the trigger phrase
18+ # Only run if it's a PR or if the comment contains @claude
2419 if : |
2520 github.event_name == 'pull_request' ||
2621 (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
@@ -39,218 +34,128 @@ jobs:
3934 with :
4035 fetch-depth : 0
4136
42- - name : Fetch system prompt from private repo
43- id : fetch-prompt
37+ # Optional: Fetch custom system prompt
38+ - name : Fetch custom system prompt
39+ id : custom-prompt
40+ continue-on-error : true
4441 env :
45- GH_TOKEN : ${{ secrets.NETWRIX_PROMPT_REPO_TOKEN || secrets.GITHUB_TOKEN }}
42+ TOKEN : ${{ secrets.NETWRIX_PROMPT_REPO_TOKEN }}
4643 run : |
47- # Fetch the system prompt file from the private repository
48- echo "Fetching system prompt from netwrix/action-agent-prompts..."
49-
50- RESPONSE=$(curl -s -w "\n%{http_code}" \
51- -H "Authorization: token $GH_TOKEN" \
52- -H "Accept: application/vnd.github.v3.raw" \
53- https://api.github.com/repos/netwrix/action-agent-prompts/contents/docs-dev.md?ref=main)
54-
55- HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
56- CONTENT=$(echo "$RESPONSE" | head -n-1)
57-
58- if [ "$HTTP_CODE" != "200" ]; then
59- echo "Failed to fetch system prompt file (HTTP $HTTP_CODE)"
60- echo "Response: $CONTENT"
61- exit 1
62- fi
63-
64- # Save the content to a file
65- echo "$CONTENT" > /tmp/system-prompt.md
66-
67- # Verify the file was created and has content
68- if [ ! -s /tmp/system-prompt.md ]; then
69- echo "System prompt file is empty"
70- exit 1
44+ if [ -n "$TOKEN" ]; then
45+ echo "Attempting to fetch custom prompt..."
46+ curl -s -H "Authorization: token $TOKEN" \
47+ -H "Accept: application/vnd.github.v3.raw" \
48+ -o /tmp/system-prompt.txt \
49+ https://api.github.com/repos/netwrix/action-agent-prompts/contents/docs-dev.md?ref=main
50+
51+ if [ -s /tmp/system-prompt.txt ]; then
52+ echo "has_custom=true" >> $GITHUB_OUTPUT
53+ echo "✅ Custom prompt fetched"
54+ fi
7155 fi
72-
73- echo "System prompt fetched successfully"
74- echo "File size: $(wc -c < /tmp/system-prompt.md) bytes"
7556
76- - name : Determine trigger context
77- id : context
57+ # Prepare the review prompt
58+ - name : Prepare review prompt
59+ id : prepare-prompt
7860 run : |
7961 if [[ "${{ github.event_name }}" == "pull_request" ]]; then
80- echo "is_pr=true" >> $GITHUB_OUTPUT
81- echo "is_comment=false" >> $GITHUB_OUTPUT
82- echo "trigger_type=pull_request" >> $GITHUB_OUTPUT
83- else
84- echo "is_pr=false" >> $GITHUB_OUTPUT
85- echo "is_comment=true" >> $GITHUB_OUTPUT
86- echo "trigger_type=${{ github.event_name }}" >> $GITHUB_OUTPUT
87- fi
88-
89- - name : Extract comment prompt (if triggered by comment)
90- id : extract-prompt
91- if : steps.context.outputs.is_comment == 'true'
92- run : |
93- # Extract the comment after the trigger phrase
94- COMMENT="${{ github.event.comment.body }}"
95- # Remove @claude and trim whitespace
96- PROMPT=$(echo "$COMMENT" | sed 's/@claude//' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
97-
98- # If prompt is empty after removing trigger, provide a default
99- if [ -z "$PROMPT" ]; then
100- PROMPT="Please review the changes in this PR and provide feedback on documentation-related aspects."
101- fi
102-
103- echo "comment_prompt<<EOF" >> $GITHUB_OUTPUT
104- echo "$PROMPT" >> $GITHUB_OUTPUT
105- echo "EOF" >> $GITHUB_OUTPUT
106-
107- - name : Check for important file changes
108- id : check-files
109- if : steps.context.outputs.is_pr == 'true'
110- run : |
111- # Get list of changed files
112- CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD || git diff --name-only HEAD~1)
113-
114- # Check if docusaurus.config.js or sidebar files were modified
115- IMPORTANT_FILES=$(echo "$CHANGED_FILES" | grep -E "(docusaurus\.config\.js|.*sidebar.*\.js)" || true)
62+ # For PRs, create a comprehensive review prompt
63+ cat > /tmp/review-prompt.txt << 'EOF'
64+ You are reviewing a pull request for a Docusaurus-based documentation site.
11665
117- # Check for any non-markdown changes
118- NON_MD_FILES=$(echo "$CHANGED_FILES" | grep -v -E "\.(md|mdx)$" || true)
66+ Please review the changes and check for:
67+ 1. Configuration Integrity: Ensure docusaurus.config.js changes are valid
68+ 2. Sidebar Structure: Verify sidebar configurations are properly formatted
69+ 3. Build Impact: Identify any changes that might affect the documentation build
70+ 4. Link Validity: Check that internal links and references are correct
71+ 5. Best Practices: Ensure changes follow Docusaurus best practices
11972
120- if [ -n "$IMPORTANT_FILES" ]; then
121- echo "has_important_changes=true" >> $GITHUB_OUTPUT
122- echo "### 🎯 Important Documentation Files Changed" >> $GITHUB_STEP_SUMMARY
123- echo '```' >> $GITHUB_STEP_SUMMARY
124- echo "$IMPORTANT_FILES" >> $GITHUB_STEP_SUMMARY
125- echo '```' >> $GITHUB_STEP_SUMMARY
73+ Focus on non-markdown files that affect documentation infrastructure.
74+ Provide specific, actionable feedback with code suggestions where appropriate.
75+ EOF
12676 else
127- echo "has_important_changes=false" >> $GITHUB_OUTPUT
128- fi
129-
130- if [ -n "$NON_MD_FILES" ]; then
131- echo "### 📝 Non-Markdown Files Changed" >> $GITHUB_STEP_SUMMARY
132- echo '```' >> $GITHUB_STEP_SUMMARY
133- echo "$NON_MD_FILES" >> $GITHUB_STEP_SUMMARY
134- echo '```' >> $GITHUB_STEP_SUMMARY
77+ # For comments, extract the user's request
78+ COMMENT="${{ github.event.comment.body }}"
79+ echo "${COMMENT//@claude/}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' > /tmp/review-prompt.txt
13580 fi
13681
137- - name : Prepare review prompt
138- id : prepare-prompt
82+ # Load system prompt if available
83+ - name : Prepare system prompt
84+ id : system-prompt
13985 run : |
140- if [[ "${{ steps.context.outputs.is_pr }}" == "true" ]]; then
141- # For PRs, create a comprehensive review prompt
142- PROMPT="You are reviewing a pull request for a Docusaurus-based documentation site. "
143-
144- if [[ "${{ steps.check-files.outputs.has_important_changes }}" == "true" ]]; then
145- PROMPT+="IMPORTANT: This PR includes changes to critical configuration files (docusaurus.config.js and/or sidebar files). Please pay special attention to these changes. "
146- fi
147-
148- PROMPT+="Please review the changes and check for:
149-
150- 1. **Configuration Integrity**: Ensure docusaurus.config.js changes are valid and won't break the build
151- 2. **Sidebar Structure**: Verify sidebar configurations are properly formatted and all referenced docs exist
152- 3. **Build Impact**: Identify any changes that might affect the documentation build process
153- 4. **Link Validity**: Check that internal links and references are correct
154- 5. **Best Practices**: Ensure changes follow Docusaurus best practices
155- 6. **Performance**: Flag any changes that might impact site performance
156-
157- Focus primarily on non-markdown files that affect the documentation infrastructure.
158-
159- Provide specific, actionable feedback with code suggestions where appropriate."
86+ if [ -f /tmp/system-prompt.txt ]; then
87+ PROMPT=$(cat /tmp/system-prompt.txt)
16088 else
161- # For comments, use the extracted prompt
162- PROMPT="${{ steps.extract-prompt.outputs.comment_prompt }}"
89+ PROMPT="You are a documentation expert specializing in Docusaurus sites. Focus on infrastructure, configuration, and build-related changes."
16390 fi
16491
165- # Save prompt to file
166- echo "$PROMPT" > /tmp/review-prompt.txt
167- echo "Review prompt prepared successfully"
92+ # GitHub Actions multiline output
93+ echo "content<<EOF" >> $GITHUB_OUTPUT
94+ echo "$PROMPT" >> $GITHUB_OUTPUT
95+ echo "EOF" >> $GITHUB_OUTPUT
16896
97+ # Run Claude with the correct model
16998 - name : Run Claude Code Review
17099 id : claude-review
171100 uses : anthropics/claude-code-base-action@beta
172101 with :
173102 prompt_file : /tmp/review-prompt.txt
174- system_prompt : $(cat /tmp/ system-prompt.md)
103+ system_prompt : ${{ steps. system-prompt.outputs.content }}
175104 allowed_tools : |
176- Bash(git:*),
177- View,
178- GlobTool,
179- GrepTool,
180- Write,
181- Edit,
182- Replace,
183- BatchTool
105+ View
106+ Glob
107+ Grep
108+ Read
184109 anthropic_api_key : ${{ secrets.ANTHROPIC_API_KEY }}
185110 timeout_minutes : " 15"
186111 max_turns : " 10"
187- model : " claude-opus-4-20250514"
188-
189- - name : Generate GitHub App token (for commenting)
190- id : app-token
191- if : success() || failure()
192- uses : actions/create-github-app-token@v2
193- with :
194- app-id : ${{ secrets.CLAUDE_APP_ID || vars.CLAUDE_APP_ID }}
195- private-key : ${{ secrets.CLAUDE_APP_PRIVATE_KEY }}
112+ model : " claude-opus-4-20250514" # Fixed model name
196113
197- - name : Post review summary
198- if : (success() || failure()) && steps.context.outputs.is_pr == 'true'
114+ # Post results without needing GitHub App
115+ - name : Post review results
116+ if : always() && github.event_name == 'pull_request'
199117 uses : actions/github-script@v7
200118 with :
201- github-token : ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
119+ github-token : ${{ secrets.GITHUB_TOKEN }}
202120 script : |
203121 const fs = require('fs');
204122 const executionFile = '${{ steps.claude-review.outputs.execution_file }}';
205123
206- let reviewContent = '';
207- let status = '${{ steps.claude-review.outputs.conclusion }}';
124+ let reviewContent = '⚠️ Review could not be completed.';
208125
209- if (status === 'success' && fs.existsSync(executionFile)) {
126+ if (fs.existsSync(executionFile)) {
210127 try {
211- const executionLog = JSON.parse(fs.readFileSync(executionFile, 'utf8'));
128+ const content = fs.readFileSync(executionFile, 'utf8');
129+ const data = JSON.parse(content);
212130
213- // Find the last assistant message which should contain the review
214- for (let i = executionLog .length - 1; i >= 0; i--) {
215- if (executionLog [i].role === 'assistant' && executionLog [i].content) {
216- reviewContent = executionLog [i].content;
131+ // Extract the last assistant message
132+ for (let i = data .length - 1; i >= 0; i--) {
133+ if (data [i].role === 'assistant' && data [i].content) {
134+ reviewContent = data [i].content;
217135 break;
218136 }
219137 }
220- } catch (error) {
221- console.error('Error parsing execution log:', error);
222- reviewContent = 'Error: Could not parse Claude\'s response.';
138+ } catch (e) {
139+ console.error('Error reading results:', e);
223140 }
224- } else if (status === 'failure') {
225- reviewContent = '⚠️ The review could not be completed. Please check the action logs for details.';
226141 }
227142
228- const summary = `## 🤖 Claude Documentation Review
229-
230- ${reviewContent || 'No review content was generated.'}
231-
232- ---
233- <sub>Generated by Claude Code Documentation Review Action</sub>`;
234-
235143 await github.rest.issues.createComment({
236144 issue_number: context.issue.number,
237145 owner: context.repo.owner,
238146 repo: context.repo.repo,
239- body: summary
147+ body: `## 🤖 Claude Documentation Review\n\n${reviewContent}\n\n---\n<sub>Generated by Claude Documentation Review</sub>`
240148 });
241149
242- - name : Add workflow summary
150+ # Summary
151+ - name : Job Summary
243152 if : always()
244153 run : |
245- echo "## 📊 Claude Review Summary" >> $GITHUB_STEP_SUMMARY
246- echo "" >> $GITHUB_STEP_SUMMARY
247- echo "- **Trigger Type**: ${{ steps.context.outputs.trigger_type }}" >> $GITHUB_STEP_SUMMARY
248- echo "- **Review Status**: ${{ steps.claude-review.outputs.conclusion || 'Not completed' }}" >> $GITHUB_STEP_SUMMARY
249- echo "- **Important Files Changed**: ${{ steps.check-files.outputs.has_important_changes || 'N/A' }}" >> $GITHUB_STEP_SUMMARY
250- echo "" >> $GITHUB_STEP_SUMMARY
251-
252- if [ -f "${{ steps.claude-review.outputs.execution_file }}" ]; then
253- echo "✅ Review completed. Check the PR comments for Claude's feedback." >> $GITHUB_STEP_SUMMARY
154+ echo "## Claude Review Summary" >> $GITHUB_STEP_SUMMARY
155+ echo "- Status: ${{ steps.claude-review.outputs.conclusion || 'Unknown' }}" >> $GITHUB_STEP_SUMMARY
156+ echo "- Trigger: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
157+ if [ -f /tmp/system-prompt.txt ]; then
158+ echo "- Custom Prompt: ✅ Loaded" >> $GITHUB_STEP_SUMMARY
254159 else
255- echo "❌ Review did not complete successfully. " >> $GITHUB_STEP_SUMMARY
160+ echo "- Custom Prompt: ❌ Using default " >> $GITHUB_STEP_SUMMARY
256161 fi
0 commit comments