name: Issue Triage and Auto-Fix on: issues: types: [opened, labeled] permissions: contents: write issues: write pull-requests: write jobs: triage-issue: name: Triage and Label Issues runs-on: ubuntu-latest if: github.event.action == 'opened' steps: - name: Analyze and label issue uses: actions/github-script@v7 with: script: | const issue = context.payload.issue; const title = issue.title.toLowerCase(); const body = (issue.body || '').toLowerCase(); const text = title + ' ' + body; let labels = []; // Categorize by type if (text.match(/bug|error|crash|broken|fail/)) { labels.push('bug'); } if (text.match(/feature|enhancement|add|new|implement/)) { labels.push('enhancement'); } if (text.match(/document|readme|docs|guide/)) { labels.push('documentation'); } if (text.match(/test|testing|spec|e2e/)) { labels.push('testing'); } if (text.match(/security|vulnerability|exploit|xss|sql/)) { labels.push('security'); } if (text.match(/performance|slow|optimize|speed/)) { labels.push('performance'); } // Categorize by priority if (text.match(/critical|urgent|asap|blocker/)) { labels.push('priority: high'); } else if (text.match(/minor|low|nice to have/)) { labels.push('priority: low'); } else { labels.push('priority: medium'); } // Check if it's a good first issue if (text.match(/beginner|easy|simple|starter/) || labels.length <= 2) { labels.push('good first issue'); } // Check if AI can help if (labels.includes('bug') || labels.includes('documentation') || labels.includes('testing')) { labels.push('ai-fixable'); } // Add labels if (labels.length > 0) { try { await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, labels: labels }); } catch (e) { console.log('Some labels may not exist:', e.message); } } // Post welcome comment const aiHelpText = labels.includes('ai-fixable') ? '\n\nšŸ¤– This issue appears to be something AI can help with! A fix may be automatically attempted.' : ''; const comment = 'šŸ‘‹ Thank you for opening this issue!\n\n' + 'This issue has been automatically labeled as: ' + labels.join(', ') + aiHelpText + '\n\n' + 'A maintainer will review this issue soon. In the meantime, please make sure you have provided:\n' + '- A clear description of the issue\n' + '- Steps to reproduce (for bugs)\n' + '- Expected vs actual behavior\n' + '- Any relevant error messages or screenshots\n\n' + 'Copilot may be able to help with this issue.'; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, body: comment }); attempt-auto-fix: name: Attempt Automated Fix runs-on: ubuntu-latest if: | (github.event.action == 'labeled' && github.event.label.name == 'ai-fixable') || (github.event.action == 'labeled' && github.event.label.name == 'auto-fix') steps: - name: Checkout code uses: actions/checkout@v4 - name: Analyze issue and suggest fix uses: actions/github-script@v7 with: script: | const issue = context.payload.issue; const labelList = issue.labels.map(l => l.name).join(', '); const comment = 'šŸ¤– **AI-Assisted Fix Attempt**\n\n' + 'I have analyzed this issue and here are my suggestions:\n\n' + '**Issue Type:** ' + labelList + '\n\n' + '**Suggested Actions:**\n' + '1. Review the issue description carefully\n' + '2. Check for similar issues in the repository history\n' + '3. Consider using Copilot to help implement the fix\n\n' + '**To request an automated fix:**\n' + '- Add the auto-fix label to this issue\n' + '- Ensure the issue description clearly explains:\n' + ' - What needs to be fixed\n' + ' - Where the issue is located (file/line if known)\n' + ' - Expected behavior\n\n' + '**Note:** Complex issues may require human review before implementation.\n\n' + 'Would you like me to attempt an automated fix? If so, please confirm by commenting "Copilot fix this issue".'; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, body: comment }); create-fix-pr: name: Create Fix PR runs-on: ubuntu-latest if: github.event.action == 'labeled' && github.event.label.name == 'create-pr' steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: Create fix branch and PR uses: actions/github-script@v7 with: script: | const issue = context.payload.issue; const branchName = 'auto-fix/issue-' + issue.number; const comment = 'šŸ¤– **Automated Fix PR Creation**\n\n' + 'I have created a branch ' + branchName + ' for this fix.\n\n' + '**Next Steps:**\n' + '1. A developer or Copilot will work on the fix in this branch\n' + '2. A pull request will be created automatically\n' + '3. The PR will be linked to this issue\n\n' + '**Branch:** ' + branchName + '\n\n' + 'To work on this fix:\n' + 'git fetch origin\n' + 'git checkout ' + branchName + '\n\n' + 'This issue will be automatically closed when the PR is merged.'; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, body: comment });