diff --git a/.github/workflows/issue-triage.yml b/.github/workflows/issue-triage.yml index 634607e..cfd68e1 100644 --- a/.github/workflows/issue-triage.yml +++ b/.github/workflows/issue-triage.yml @@ -1,13 +1,15 @@ --- -name: Issue Triage +name: Issue and PR Triage 'on': issues: types: [opened] + pull_request: + types: [opened] workflow_dispatch: inputs: issue_number: - description: 'Issue number to triage (leave empty to process all)' + description: 'Issue/PR number to triage (leave empty to process all)' required: false type: string @@ -15,4 +17,10 @@ jobs: issue-triage: uses: wp-cli/.github/.github/workflows/reusable-issue-triage.yml@main with: - issue_number: ${{ github.event_name == 'workflow_dispatch' && inputs.issue_number || github.event.issue.number }} + issue_number: >- + ${{ + (github.event_name == 'workflow_dispatch' && inputs.issue_number) || + (github.event_name == 'pull_request' && github.event.pull_request.number) || + (github.event_name == 'issues' && github.event.issue.number) || + '' + }} diff --git a/.github/workflows/reusable-issue-triage.yml b/.github/workflows/reusable-issue-triage.yml index 6f255fb..8c040dd 100644 --- a/.github/workflows/reusable-issue-triage.yml +++ b/.github/workflows/reusable-issue-triage.yml @@ -1,23 +1,24 @@ --- -name: Issue Triage +name: Issue and PR Triage 'on': workflow_call: inputs: issue_number: - description: 'Issue number to triage (leave empty to process all)' + description: 'Issue/PR number to triage (leave empty to process all)' required: false type: string permissions: issues: write + pull-requests: write contents: read models: read jobs: - triage-new-issue: - name: Triage New Issue - if: github.event_name == 'issues' + triage-new-item: + name: Triage New Issue or PR + if: github.event_name == 'issues' || github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - name: Get available labels @@ -35,27 +36,29 @@ jobs: - name: Set environment variables env: - ISSUE_TITLE: ${{ github.event.issue.title }} - ISSUE_BODY: ${{ github.event.issue.body }} + ITEM_TITLE: ${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.event.issue.title }} + ITEM_BODY: ${{ github.event_name == 'pull_request' && github.event.pull_request.body || github.event.issue.body }} + ITEM_TYPE: ${{ github.event_name == 'pull_request' && 'pull request' || 'issue' }} LABELS_RESULT: ${{ steps.get-labels.outputs.result }} run: | { echo "AVAILABLE_LABELS=${LABELS_RESULT}" - echo "ISSUE_TITLE=${ISSUE_TITLE}" - echo "ISSUE_BODY<> "$GITHUB_ENV" - - name: Analyze issue with AI + - name: Analyze with AI id: ai-triage uses: actions/ai-inference@v2 with: prompt: | ## Role - You are an issue triage assistant. Analyze the current GitHub - issue and identify the most appropriate existing labels. Use the + You are an issue and pull request triage assistant. Analyze the current GitHub + ${{ env.ITEM_TYPE }} and identify the most appropriate existing labels. Use the available tools to gather information; do not ask for information to be provided. @@ -74,22 +77,22 @@ jobs: ${{ env.AVAILABLE_LABELS }} ``` - **Issue Title**: + **Title**: ``` - ${{ env.ISSUE_TITLE }} + ${{ env.ITEM_TITLE }} ``` - **Issue Body**: + **Body**: ``` - ${{ env.ISSUE_BODY }} + ${{ env.ITEM_BODY }} ``` ## Steps - 1. Review the issue title, issue body, and available labels + 1. Review the title, body, and available labels provided above. - 2. Based on the issue title and issue body, classify the issue + 2. Based on the title and body, classify the ${{ env.ITEM_TYPE }} and choose all appropriate labels from the list of available labels. @@ -128,18 +131,18 @@ jobs: console.log('No valid labels to apply'); } - triage-unlabeled-issues: - name: Triage Unlabeled Issues + triage-unlabeled-items: + name: Triage Unlabeled Issues and PRs if: | github.event_name == 'workflow_dispatch' && inputs.issue_number == '' runs-on: ubuntu-latest steps: - - name: Find and dispatch triage for unlabeled issues + - name: Find and dispatch triage for unlabeled items uses: actions/github-script@v8 with: script: | - // Get all open issues + // Get all open issues (includes PRs) const issues = await github.paginate( github.rest.issues.listForRepo, { @@ -150,27 +153,28 @@ jobs: } ); - console.log(`Found ${issues.length} open issues`); + console.log(`Found ${issues.length} open issues and PRs`); - // Filter issues without labels - const unlabeledIssues = issues.filter(issue => - !issue.pull_request && issue.labels.length === 0 + // Filter items without labels + const unlabeledItems = issues.filter(issue => + issue.labels.length === 0 ); console.log( - `Found ${unlabeledIssues.length} unlabeled issues` + `Found ${unlabeledItems.length} unlabeled items` ); - if (unlabeledIssues.length === 0) { - console.log('No unlabeled issues to process'); + if (unlabeledItems.length === 0) { + console.log('No unlabeled items to process'); return; } - // Dispatch triage workflow for each unlabeled issue - for (const issue of unlabeledIssues) { + // Dispatch triage workflow for each unlabeled item + for (const item of unlabeledItems) { + const itemType = item.pull_request ? 'PR' : 'issue'; console.log( - `Dispatching triage for issue #${issue.number}: ` + - `"${issue.title}"` + `Dispatching triage for ${itemType} #${item.number}: ` + + `"${item.title}"` ); try { @@ -180,12 +184,12 @@ jobs: workflow_id: 'issue-triage.yml', ref: context.ref || 'main', inputs: { - issue_number: issue.number.toString() + issue_number: item.number.toString() } }); } catch (error) { console.error( - `Failed to dispatch triage for issue #${issue.number}: ` + + `Failed to dispatch triage for ${itemType} #${item.number}: ` + `${error.message}` ); } @@ -196,8 +200,8 @@ jobs: console.log('Finished dispatching triage workflows'); - triage-single-issue: - name: Triage Single Issue + triage-single-item: + name: Triage Single Issue or PR if: | github.event_name == 'workflow_dispatch' && inputs.issue_number != '' @@ -216,44 +220,53 @@ jobs: const labelNames = labels.data.map(label => label.name); return labelNames.join(', '); - - name: Get issue details - id: get-issue + - name: Get item details + id: get-item uses: actions/github-script@v8 with: script: | + const itemNumber = parseInt('${{ inputs.issue_number }}'); + + // Try to get as an issue first (works for both issues and PRs) const issue = await github.rest.issues.get({ owner: context.repo.owner, repo: context.repo.repo, - issue_number: parseInt('${{ inputs.issue_number }}') + issue_number: itemNumber }); + + const itemType = issue.data.pull_request ? 'pull request' : 'issue'; + return { title: issue.data.title, - body: issue.data.body || '' + body: issue.data.body || '', + type: itemType }; - name: Set environment variables env: - ISSUE_TITLE: ${{ fromJSON(steps.get-issue.outputs.result).title }} - ISSUE_BODY: ${{ fromJSON(steps.get-issue.outputs.result).body }} + ITEM_TITLE: ${{ fromJSON(steps.get-item.outputs.result).title }} + ITEM_BODY: ${{ fromJSON(steps.get-item.outputs.result).body }} + ITEM_TYPE: ${{ fromJSON(steps.get-item.outputs.result).type }} LABELS_RESULT: ${{ steps.get-labels.outputs.result }} run: | { echo "AVAILABLE_LABELS=${LABELS_RESULT}" - echo "ISSUE_TITLE=${ISSUE_TITLE}" - echo "ISSUE_BODY<> "$GITHUB_ENV" - - name: Analyze issue with AI + - name: Analyze with AI id: ai-triage uses: actions/ai-inference@v2 with: prompt: | ## Role - You are an issue triage assistant. Analyze the current GitHub - issue and identify the most appropriate existing labels. Use the + You are an issue and pull request triage assistant. Analyze the current GitHub + ${{ env.ITEM_TYPE }} and identify the most appropriate existing labels. Use the available tools to gather information; do not ask for information to be provided. @@ -272,22 +285,22 @@ jobs: ${{ env.AVAILABLE_LABELS }} ``` - **Issue Title**: + **Title**: ``` - ${{ env.ISSUE_TITLE }} + ${{ env.ITEM_TITLE }} ``` - **Issue Body**: + **Body**: ``` - ${{ env.ISSUE_BODY }} + ${{ env.ITEM_BODY }} ``` ## Steps - 1. Review the issue title, issue body, and available labels + 1. Review the title, body, and available labels provided above. - 2. Based on the issue title and issue body, classify the issue + 2. Based on the title and body, classify the ${{ env.ITEM_TYPE }} and choose all appropriate labels from the list of available labels. @@ -302,11 +315,11 @@ jobs: uses: actions/github-script@v8 env: AI_RESPONSE: ${{ steps.ai-triage.outputs.response }} - ISSUE_NUMBER: ${{ inputs.issue_number }} + ITEM_NUMBER: ${{ inputs.issue_number }} with: script: | const response = process.env.AI_RESPONSE; - const issueNumber = parseInt(process.env.ISSUE_NUMBER); + const itemNumber = parseInt(process.env.ITEM_NUMBER); if (!response || response.trim() === '') { console.log('No labels selected by AI'); @@ -322,7 +335,7 @@ jobs: await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, - issue_number: issueNumber, + issue_number: itemNumber, labels: labels }); } else {