Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 256 additions & 0 deletions .github/workflows/agent-docusarus-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
name: Claude Code Documentation Review

on:
# Trigger on pull requests to main or dev branch
pull_request:
branches:
- main
- dev
paths-ignore:
- '**.md'
- '**.mdx'

# Trigger on issue comments (for tagging)
issue_comment:
types: [created]

# Trigger on PR review comments
pull_request_review_comment:
types: [created]

jobs:
claude-review:
# Only run if it's a PR or if the comment contains the trigger phrase
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude'))

runs-on: ubuntu-latest

permissions:
contents: read
pull-requests: write
issues: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Fetch system prompt from private repo
id: fetch-prompt
env:
GH_TOKEN: ${{ secrets.NETWRIX_PROMPT_REPO_TOKEN || secrets.GITHUB_TOKEN }}
run: |
# Fetch the system prompt file from the private repository
echo "Fetching system prompt from netwrix/action-agent-prompts..."

RESPONSE=$(curl -s -w "\n%{http_code}" \
-H "Authorization: token $GH_TOKEN" \
-H "Accept: application/vnd.github.v3.raw" \
https://api.github.com/repos/netwrix/action-agent-prompts/contents/docs-dev.md?ref=main)

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
CONTENT=$(echo "$RESPONSE" | head -n-1)

if [ "$HTTP_CODE" != "200" ]; then
echo "Failed to fetch system prompt file (HTTP $HTTP_CODE)"
echo "Response: $CONTENT"
exit 1
fi

# Save the content to a file
echo "$CONTENT" > /tmp/system-prompt.md

# Verify the file was created and has content
if [ ! -s /tmp/system-prompt.md ]; then
echo "System prompt file is empty"
exit 1
fi

echo "System prompt fetched successfully"
echo "File size: $(wc -c < /tmp/system-prompt.md) bytes"

- name: Determine trigger context
id: context
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "is_pr=true" >> $GITHUB_OUTPUT
echo "is_comment=false" >> $GITHUB_OUTPUT
echo "trigger_type=pull_request" >> $GITHUB_OUTPUT
else
echo "is_pr=false" >> $GITHUB_OUTPUT
echo "is_comment=true" >> $GITHUB_OUTPUT
echo "trigger_type=${{ github.event_name }}" >> $GITHUB_OUTPUT
fi

- name: Extract comment prompt (if triggered by comment)
id: extract-prompt
if: steps.context.outputs.is_comment == 'true'
run: |
# Extract the comment after the trigger phrase
COMMENT="${{ github.event.comment.body }}"
# Remove @claude and trim whitespace
PROMPT=$(echo "$COMMENT" | sed 's/@claude//' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

# If prompt is empty after removing trigger, provide a default
if [ -z "$PROMPT" ]; then
PROMPT="Please review the changes in this PR and provide feedback on documentation-related aspects."
fi

echo "comment_prompt<<EOF" >> $GITHUB_OUTPUT
echo "$PROMPT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Check for important file changes
id: check-files
if: steps.context.outputs.is_pr == 'true'
run: |
# Get list of changed files
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD || git diff --name-only HEAD~1)

# Check if docusaurus.config.js or sidebar files were modified
IMPORTANT_FILES=$(echo "$CHANGED_FILES" | grep -E "(docusaurus\.config\.js|.*sidebar.*\.js)" || true)

# Check for any non-markdown changes
NON_MD_FILES=$(echo "$CHANGED_FILES" | grep -v -E "\.(md|mdx)$" || true)

if [ -n "$IMPORTANT_FILES" ]; then
echo "has_important_changes=true" >> $GITHUB_OUTPUT
echo "### 🎯 Important Documentation Files Changed" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$IMPORTANT_FILES" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
else
echo "has_important_changes=false" >> $GITHUB_OUTPUT
fi

if [ -n "$NON_MD_FILES" ]; then
echo "### 📝 Non-Markdown Files Changed" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$NON_MD_FILES" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi

- name: Prepare review prompt
id: prepare-prompt
run: |
if [[ "${{ steps.context.outputs.is_pr }}" == "true" ]]; then
# For PRs, create a comprehensive review prompt
PROMPT="You are reviewing a pull request for a Docusaurus-based documentation site. "

if [[ "${{ steps.check-files.outputs.has_important_changes }}" == "true" ]]; then
PROMPT+="IMPORTANT: This PR includes changes to critical configuration files (docusaurus.config.js and/or sidebar files). Please pay special attention to these changes. "
fi

PROMPT+="Please review the changes and check for:

1. **Configuration Integrity**: Ensure docusaurus.config.js changes are valid and won't break the build
2. **Sidebar Structure**: Verify sidebar configurations are properly formatted and all referenced docs exist
3. **Build Impact**: Identify any changes that might affect the documentation build process
4. **Link Validity**: Check that internal links and references are correct
5. **Best Practices**: Ensure changes follow Docusaurus best practices
6. **Performance**: Flag any changes that might impact site performance

Focus primarily on non-markdown files that affect the documentation infrastructure.

Provide specific, actionable feedback with code suggestions where appropriate."
else
# For comments, use the extracted prompt
PROMPT="${{ steps.extract-prompt.outputs.comment_prompt }}"
fi

# Save prompt to file
echo "$PROMPT" > /tmp/review-prompt.txt
echo "Review prompt prepared successfully"

- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-base-action@beta
with:
prompt_file: /tmp/review-prompt.txt
system_prompt: $(cat /tmp/system-prompt.md)
allowed_tools: |
Bash(git:*),
View,
GlobTool,
GrepTool,
Write,
Edit,
Replace,
BatchTool
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
timeout_minutes: "15"
max_turns: "10"
model: "claude-4-0-sonnet-20250219"

- name: Generate GitHub App token (for commenting)
id: app-token
if: success() || failure()
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.CLAUDE_APP_ID || vars.CLAUDE_APP_ID }}
private-key: ${{ secrets.CLAUDE_APP_PRIVATE_KEY }}

- name: Post review summary
if: (success() || failure()) && steps.context.outputs.is_pr == 'true'
uses: actions/github-script@v7
with:
github-token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const executionFile = '${{ steps.claude-review.outputs.execution_file }}';

let reviewContent = '';
let status = '${{ steps.claude-review.outputs.conclusion }}';

if (status === 'success' && fs.existsSync(executionFile)) {
try {
const executionLog = JSON.parse(fs.readFileSync(executionFile, 'utf8'));

// Find the last assistant message which should contain the review
for (let i = executionLog.length - 1; i >= 0; i--) {
if (executionLog[i].role === 'assistant' && executionLog[i].content) {
reviewContent = executionLog[i].content;
break;
}
}
} catch (error) {
console.error('Error parsing execution log:', error);
reviewContent = 'Error: Could not parse Claude\'s response.';
}
} else if (status === 'failure') {
reviewContent = '⚠️ The review could not be completed. Please check the action logs for details.';
}

const summary = `## 🤖 Claude Documentation Review

${reviewContent || 'No review content was generated.'}

---
<sub>Generated by Claude Code Documentation Review Action</sub>`;

await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: summary
});

- name: Add workflow summary
if: always()
run: |
echo "## 📊 Claude Review Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Trigger Type**: ${{ steps.context.outputs.trigger_type }}" >> $GITHUB_STEP_SUMMARY
echo "- **Review Status**: ${{ steps.claude-review.outputs.conclusion || 'Not completed' }}" >> $GITHUB_STEP_SUMMARY
echo "- **Important Files Changed**: ${{ steps.check-files.outputs.has_important_changes || 'N/A' }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if [ -f "${{ steps.claude-review.outputs.execution_file }}" ]; then
echo "✅ Review completed. Check the PR comments for Claude's feedback." >> $GITHUB_STEP_SUMMARY
else
echo "❌ Review did not complete successfully." >> $GITHUB_STEP_SUMMARY
fi
Loading