From 7841bc3124e55ab3eaf18446415de43a983a39f4 Mon Sep 17 00:00:00 2001 From: Harshit Date: Tue, 9 Jun 2026 11:28:41 +0530 Subject: [PATCH] feat(workflow): introduce slash-command based issue triage --- .github/scripts/triageIssue.js | 151 ++++++++++++++++++++++++++++++ .github/workflows/triageIssue.yml | 27 ++++++ 2 files changed, 178 insertions(+) create mode 100644 .github/scripts/triageIssue.js create mode 100644 .github/workflows/triageIssue.yml diff --git a/.github/scripts/triageIssue.js b/.github/scripts/triageIssue.js new file mode 100644 index 00000000..b10f06e4 --- /dev/null +++ b/.github/scripts/triageIssue.js @@ -0,0 +1,151 @@ +module.exports = async({github, context}) => { + const owner = context.repo.owner; + const repo = context.repo.repo; + const issue = context.payload.issue; + const issueNumber = issue.number; + const issueDescription = issue.body; + const username = issue.user.login + + if(context.eventName === 'issues'){ + try { + if(!issueDescription || !issueDescription.trim()){ + return await github.rest.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: `Hi @${username}, + + Thanks for opening this issue. + + It looks like the issue description is currently missing. + + Please provide: + - A brief summary of the problem + - Expected behavior + - Actual behavior (if applicable) + - Any relevant screenshots, logs, or context + + This helps the team understand, prioritize, and route the issue correctly. + + Thank you! + + ` + }) + } + + return await github.rest.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: `Hi @${username}, + + Thanks for opening this issue. + + Please reply with one of the following areas so the issue can be routed to the appropriate team member: + + - /backend + - /web + - /mobile + - /devops + + Once an area is selected, the corresponding label will be added automatically.` + }) + + } catch (error) { + console.error(error) + } + }else if(context.eventName === 'issue_comment'){ + if (context.payload.comment.user.type === 'Bot' || context.payload.comment.user.login === 'github-actions[bot]') { + return; + } + + const comment = (context.payload.comment.body || '').trim().toLowerCase(); + const existingLabels = (issue.labels || []).map(label => label.name); + + if ( + existingLabels.includes('backend') || + existingLabels.includes('web') || + existingLabels.includes('mobile') || + existingLabels.includes('devops') + ) { + return; + } + + if (!['/backend', '/web', '/mobile', '/devops'].includes(comment)) { + return; + } + if(comment === '/backend'){ + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: ['backend'] + + }) + return await github.rest.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: `The issue has been classified as **backend**. + +@Harxhit, please review and triage this issue when available. + +The **backend** label has been applied and the issue has been routed accordingly.` + }) + }else if(comment === '/web'){ + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: ['web'] + + }) + return await github.rest.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: `The issue has been classified as **web**. + +@ShantKhatri, please review and triage this issue when available. + +The **web** label has been applied and the issue has been routed accordingly.` + }) + }else if(comment === '/mobile'){ + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: ['mobile'] + + }) + return await github.rest.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: `The issue has been classified as **mobile**. + +@blankirigaya, please review and triage this issue when available. + +The **mobile** label has been applied and the issue has been routed accordingly.` + }) + }else if(comment === '/devops'){ + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: ['devops'] + + }) + return await github.rest.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: `The issue has been classified as **devops**. + +@ShantKhatri, please review and triage this issue when available. + +The **devops** label has been applied and the issue has been routed accordingly.` + }) + } + } +} \ No newline at end of file diff --git a/.github/workflows/triageIssue.yml b/.github/workflows/triageIssue.yml new file mode 100644 index 00000000..98162d4c --- /dev/null +++ b/.github/workflows/triageIssue.yml @@ -0,0 +1,27 @@ +name: Issue triage + +on: + issues: + types: [opened] + issue_comment: + types: [created, edited] + + +permissions: + issues: write + +jobs: + assignLabel: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 + + - name: Triage issue + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 #v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const script = require('./.github/scripts/triageIssue.js'); + await script({ github, context });