Create agent-docusarus-dev.yml #1
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 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 |