diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..d630a311 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: '' -labels: '' +labels: 'feature-request' assignees: '' --- diff --git a/.github/workflows/convert-feature-requests.yml b/.github/workflows/convert-feature-requests.yml new file mode 100644 index 00000000..360b2f04 --- /dev/null +++ b/.github/workflows/convert-feature-requests.yml @@ -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}`);