feat: auto-convert feature requests to discussions

Add GitHub Action to automatically move feature request issues to
Discussions, keeping Issues tab focused on bug reports.

Changes:
- Update feature request template to add 'feature-request' label
- Create workflow to auto-convert labeled issues to discussions
- Support manual conversion via workflow_dispatch
- Auto-close and lock converted issues with discussion link

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2025-12-13 18:41:42 -05:00
parent dd5e2e57dd
commit c2eefe3578
2 changed files with 148 additions and 1 deletions
@@ -0,0 +1,147 @@
name: Convert Feature Requests to Discussions
on:
issues:
types: [labeled]
workflow_dispatch:
inputs:
issue_number:
description: 'Issue number to convert to discussion'
required: true
type: number
jobs:
convert:
runs-on: ubuntu-latest
# Only run on labeled event if the label is 'feature-request', or always run on workflow_dispatch
if: |
(github.event_name == 'issues' && github.event.label.name == 'feature-request') ||
github.event_name == 'workflow_dispatch'
permissions:
issues: write
discussions: write
contents: read
steps:
- name: Get issue details
id: issue
uses: actions/github-script@v7
with:
script: |
let issue;
if (context.eventName === 'workflow_dispatch') {
const { data } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.inputs.issue_number
});
issue = data;
} else {
issue = context.payload.issue;
}
// Store issue details for next steps
core.setOutput('number', issue.number);
core.setOutput('title', issue.title);
core.setOutput('body', issue.body || 'No description provided.');
core.setOutput('author', issue.user.login);
core.setOutput('url', issue.html_url);
console.log(`Processing issue #${issue.number}: ${issue.title}`);
- name: Create discussion
id: discussion
uses: actions/github-script@v7
with:
script: |
const issueNumber = '${{ steps.issue.outputs.number }}';
const issueTitle = `${{ steps.issue.outputs.title }}`;
const issueBody = `${{ steps.issue.outputs.body }}`;
const issueAuthor = '${{ steps.issue.outputs.author }}';
const issueUrl = '${{ steps.issue.outputs.url }}';
// Format the discussion body with a reference to the original issue
const discussionBody = `> Originally posted as issue #${issueNumber} by @${issueAuthor}\n> ${issueUrl}\n\n${issueBody}`;
const mutation = `
mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
createDiscussion(input: {
repositoryId: $repositoryId
categoryId: $categoryId
title: $title
body: $body
}) {
discussion {
url
number
}
}
}
`;
const variables = {
repositoryId: 'R_kgDOPng1Jw',
categoryId: 'DIC_kwDOPng1J84Cw86z',
title: issueTitle,
body: discussionBody
};
try {
const result = await github.graphql(mutation, variables);
const discussionUrl = result.createDiscussion.discussion.url;
const discussionNumber = result.createDiscussion.discussion.number;
core.setOutput('url', discussionUrl);
core.setOutput('number', discussionNumber);
console.log(`Created discussion #${discussionNumber}: ${discussionUrl}`);
return discussionUrl;
} catch (error) {
core.setFailed(`Failed to create discussion: ${error.message}`);
throw error;
}
- name: Comment on issue
uses: actions/github-script@v7
with:
script: |
const issueNumber = '${{ steps.issue.outputs.number }}';
const discussionUrl = '${{ steps.discussion.outputs.url }}';
const comment = `This feature request has been moved to [Discussions](${discussionUrl}) to keep bug reports separate from feature ideas.\n\nPlease continue the conversation there - we'd love to hear your thoughts!`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: comment
});
console.log(`Added comment to issue #${issueNumber}`);
- name: Close and lock issue
uses: actions/github-script@v7
with:
script: |
const issueNumber = '${{ steps.issue.outputs.number }}';
// Close the issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
state: 'closed'
});
console.log(`Closed issue #${issueNumber}`);
// Lock the issue
await github.rest.issues.lock({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
lock_reason: 'resolved'
});
console.log(`Locked issue #${issueNumber}`);