Add GitHub Action to automate the creation of LLMs.txt and LLMs-full.txt #6
Workflow file for this run
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: Update llms.txt and llms-full.txt in subdirectories | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: 'PR number to update LLM files for' | |
| required: true | |
| type: number | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| auto-docs: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Determine trigger type and get PR info | |
| id: pr-info | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "=== Manual trigger - getting PR information ===" | |
| PR_NUMBER="${{ github.event.inputs.pr_number }}" | |
| pr_data=$(gh pr view $PR_NUMBER --json headRefName,baseRefName,state) | |
| head_ref=$(echo "$pr_data" | jq -r '.headRefName') | |
| base_ref=$(echo "$pr_data" | jq -r '.baseRefName') | |
| state=$(echo "$pr_data" | jq -r '.state') | |
| echo "PR #$PR_NUMBER:" | |
| echo " Head: $head_ref" | |
| echo " Base: $base_ref" | |
| echo " State: $state" | |
| if [ "$state" != "OPEN" ]; then | |
| echo "Error: PR #$PR_NUMBER is not open" | |
| exit 1 | |
| fi | |
| echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT | |
| echo "head_ref=$head_ref" >> $GITHUB_OUTPUT | |
| echo "base_ref=$base_ref" >> $GITHUB_OUTPUT | |
| echo "is_manual=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "=== PR trigger - using event data ===" | |
| echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT | |
| echo "head_ref=${{ github.head_ref }}" >> $GITHUB_OUTPUT | |
| echo "base_ref=${{ github.base_ref }}" >> $GITHUB_OUTPUT | |
| echo "is_manual=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ steps.pr-info.outputs.head_ref }} | |
| - name: Install Cursor CLI | |
| run: | | |
| curl https://cursor.com/install -fsS | bash | |
| echo "$HOME/.cursor/bin" >> $GITHUB_PATH | |
| - name: Configure git | |
| run: | | |
| git config user.name "Cursor Agent" | |
| git config user.email "[email protected]" | |
| - name: Check if should run and detect changes | |
| id: detect-changes | |
| run: | | |
| echo "=== Checking if should run ===" | |
| # For PR triggers, only run if not a docs/ branch and user opts in | |
| if [ "${{ steps.pr-info.outputs.is_manual }}" = "false" ]; then | |
| if [[ "${{ steps.pr-info.outputs.head_ref }}" == docs/* ]]; then | |
| echo "Skipping: PR branch starts with 'docs/'" | |
| echo "should_run=false" >> $GITHUB_OUTPUT | |
| echo "skip_reason=docs_branch" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "⏭️ **LLM Summary Files Update Available**" > /tmp/instruction.md | |
| echo "" >> /tmp/instruction.md | |
| echo "This PR can automatically update \`llms.txt\` and \`llms-full.txt\` files." >> /tmp/instruction.md | |
| echo "" >> /tmp/instruction.md | |
| echo "**To update:** Go to [Actions tab](https://github.com/${{ github.repository }}/actions/workflows/llms-txt-automation.yml) → 'Run workflow' → Enter PR #${{ steps.pr-info.outputs.pr_number }}" >> /tmp/instruction.md | |
| echo "" >> /tmp/instruction.md | |
| echo "_This is optional and doesn't block PR approval._" >> /tmp/instruction.md | |
| echo "should_run=false" >> $GITHUB_OUTPUT | |
| echo "skip_reason=instruction_only" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "=== Manual trigger - detecting changed subdirectories ===" | |
| changed_files=$(git diff --name-only origin/${{ steps.pr-info.outputs.base_ref }}...HEAD -- docs/) | |
| echo "Changed files in docs/:" | |
| echo "$changed_files" | |
| changed_subdirs="" | |
| for file in $changed_files; do | |
| subdir=$(echo "$file" | sed -n 's|^docs/\([^/]*\)/.*|\1|p') | |
| if [ -n "$subdir" ] && [ -f "docs/$subdir/llms.txt" ] && [ -f "docs/$subdir/llms-full.txt" ]; then | |
| if [[ ! "$changed_subdirs" =~ (^|[[:space:]])"$subdir"($|[[:space:]]) ]]; then | |
| changed_subdirs="$changed_subdirs $subdir" | |
| echo "Found subdirectory with llms files: $subdir" | |
| fi | |
| fi | |
| done | |
| changed_subdirs=$(echo "$changed_subdirs" | xargs) | |
| echo "changed_subdirs=$changed_subdirs" >> $GITHUB_OUTPUT | |
| echo "should_run=true" >> $GITHUB_OUTPUT | |
| echo "=== Final changed subdirectories: $changed_subdirs ===" | |
| - name: Post instruction comment | |
| if: steps.detect-changes.outputs.skip_reason == 'instruction_only' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ steps.pr-info.outputs.pr_number }} | |
| run: | | |
| echo "=== Posting instruction comment ===" | |
| gh pr comment "$PR_NUMBER" --body-file /tmp/instruction.md | |
| echo "=== Instruction comment posted ===" | |
| - name: Update LLM summary files | |
| if: steps.detect-changes.outputs.should_run == 'true' && steps.detect-changes.outputs.changed_subdirs != '' | |
| env: | |
| MODEL: gpt-5 | |
| CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| CHANGED_SUBDIRS: ${{ steps.detect-changes.outputs.changed_subdirs }} | |
| run: | | |
| echo "=== Starting LLM summary files update ===" | |
| echo "Processing subdirectories: $CHANGED_SUBDIRS" | |
| cursor-agent -p "You are updating documentation summary files in a GitHub Actions runner. | |
| IMPORTANT: Do NOT create branches, commit, push, or post PR comments. Only modify files in the working directory as needed. | |
| # Context: | |
| - Repo: ${{ github.repository }} | |
| - PR Number: ${{ steps.pr-info.outputs.pr_number }} | |
| - Base Ref: ${{ steps.pr-info.outputs.base_ref }} | |
| - Head Ref: ${{ steps.pr-info.outputs.head_ref }} | |
| - Changed Subdirectories: $CHANGED_SUBDIRS | |
| # Your Task: | |
| Update llms.txt and llms-full.txt files in the changed subdirectories based on documentation changes in this PR. | |
| # Step-by-Step Process (print each step): | |
| 1. Print 'STEP 1: Getting PR diff' | |
| 2. Get PR changes: \`gh pr diff ${{ steps.pr-info.outputs.pr_number }}\` | |
| 3. Print 'STEP 2: Processing subdirectories: $CHANGED_SUBDIRS' | |
| 4. For each subdirectory in CHANGED_SUBDIRS: | |
| a. Print 'STEP 3a: Reading docs/[subdirectory]/llms.txt' | |
| b. Print 'STEP 3b: Reading docs/[subdirectory]/llms-full.txt' | |
| c. Print 'STEP 3c: Analyzing changes for [subdirectory]' | |
| d. If updates needed: Print 'STEP 3d: Updating files for [subdirectory]' and modify files | |
| e. If no updates needed: Print 'STEP 3e: No updates needed for [subdirectory]' | |
| 5. Print 'STEP 4: File modifications complete' | |
| 6. Print 'TASK_FINISHED' | |
| # File Requirements: | |
| - Only modify docs/[subdirectory]/llms.txt and docs/[subdirectory]/llms-full.txt files | |
| - Do NOT modify root-level llms.txt or llms-full.txt files | |
| - llms.txt should be a concise summary/index of subdirectory documentation | |
| - llms-full.txt should be a comprehensive guide with code examples | |
| - Maintain existing format and style | |
| - Only update files that need changes based on PR content | |
| # Restrictions: | |
| - NO git operations (no commit, push, branch creation) | |
| - NO PR comments or API calls except gh pr diff | |
| - Only file modifications in working directory | |
| - Print progress steps as you go | |
| - End with 'TASK_FINISHED' | |
| Begin now and print each step clearly. | |
| " --force --model "$MODEL" --output-format=text | |
| echo "=== Cursor agent completed ===" | |
| - name: Commit changes to PR branch | |
| if: steps.detect-changes.outputs.should_run == 'true' && steps.detect-changes.outputs.changed_subdirs != '' | |
| id: commit_changes | |
| run: | | |
| echo "=== Checking for changes ===" | |
| git add -A | |
| if git diff --staged --quiet; then | |
| echo "No changes to commit" | |
| echo "changes_committed=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Changes detected:" | |
| git diff --staged --name-only | |
| COMMIT_MSG="docs: update llms summaries for subdirectories (${{ steps.detect-changes.outputs.changed_subdirs }})" | |
| git commit -m "$COMMIT_MSG" | |
| git push origin ${{ steps.pr-info.outputs.head_ref }} | |
| echo "changes_committed=true" >> "$GITHUB_OUTPUT" | |
| echo "=== Changes committed successfully ===" | |
| - name: Post PR comment about updates | |
| if: steps.commit_changes.outputs.changes_committed == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ steps.pr-info.outputs.pr_number }} | |
| run: | | |
| echo "=== Posting PR comment about updates ===" | |
| changed_files=$(git diff HEAD~1 --name-only | grep -E "llms(-full)?\.txt$" | head -10) | |
| COMMENT_FILE="${RUNNER_TEMP}/llms-update-comment.md" | |
| { | |
| echo "🤖 **LLM summary files updated**" | |
| echo "" | |
| echo "Updated documentation summary files based on changes in subdirectories: \`${{ steps.detect-changes.outputs.changed_subdirs }}\`" | |
| echo "" | |
| echo "**Files updated:**" | |
| for file in $changed_files; do | |
| echo "- \`$file\`" | |
| done | |
| echo "" | |
| echo "_These files help AI assistants provide better guidance about your documentation._" | |
| echo "" | |
| echo "<!-- auto-update-llms -->" | |
| } > "$COMMENT_FILE" | |
| gh pr comment "$PR_NUMBER" --body-file "$COMMENT_FILE" | |
| echo "=== PR comment posted successfully ===" |