diff --git a/.github/DISCUSSION_TEMPLATE/copilot.yml b/.github/DISCUSSION_TEMPLATE/copilot-conversations.yml similarity index 66% rename from .github/DISCUSSION_TEMPLATE/copilot.yml rename to .github/DISCUSSION_TEMPLATE/copilot-conversations.yml index 99fd3d009..c159a51a6 100644 --- a/.github/DISCUSSION_TEMPLATE/copilot.yml +++ b/.github/DISCUSSION_TEMPLATE/copilot-conversations.yml @@ -1,25 +1,42 @@ body: +- type: markdown + attributes: + value: | + #### Explore our [Copilot FAQs](https://github.com/orgs/community/discussions/144674) and [GitHub Docs](https://docs.github.com/en/copilot) for comprehensive guidance! + - 💡 **Quick Tip:** For general development questions or detailed code issues, try [Chat with Copilot](https://docs.github.com/en/enterprise-cloud@latest/copilot/using-github-copilot/copilot-chat/asking-github-copilot-questions-in-github) first, it might have the answer you need before posting here. + - 🛠️ For bugs and feature requests related to VS Code in Copilot, please open an issue in our [VS Code](https://github.com/microsoft/vscode-copilot-release/issues). + - 🔍 Are you a student/teacher looking to enable Copilot Pro? [Read our guide](https://gh.io/faq-nd-copilot) - type: dropdown attributes: - label: 🌟 Welcome to the GitHub Copilot category. + label: Select Topic Area description: What would you like to discuss about GitHub Copilot? Choose your topic area. options: - - 🤔 Question - - ☑️ Product Feedback - - 🐞 Bug Report - - 💬 General + - Question + - Product Feedback + - Bug + - General validations: required: true -- type: markdown +- type: dropdown + id: feature-area attributes: - value: | - #### Explore our [Copilot FAQs](https://github.com/orgs/community/discussions/144674) and [GitHub Docs](https://docs.github.com/en/copilot) for comprehensive guidance! - - 💡 **Quick Tip:** For general development questions or detailed code issues, try [Chat with Copilot](https://docs.github.com/en/enterprise-cloud@latest/copilot/using-github-copilot/copilot-chat/asking-github-copilot-questions-in-github) first, it might have the answer you need before posting here. - - 🛠️ For issues related to Visual Studio Code in Copilot, please open an issue in the [Visual Studio Code repo](https://github.com/microsoft/vscode-copilot-release/issues). - - 🔍 Are you a student/teacher looking to enable Copilot Pro? [Read our guide](https://gh.io/faq-nd-copilot) + label: Copilot Feature Area + description: Which Copilot feature or product area is your discussion related to? + options: + - General + - Copilot in GitHub + - Copilot Workspace + - Copilot Agent Mode + - Copilot Enterprise + - Account Related + - VS Code + - Visual Studio + - JetBrains & Xcode + validations: + required: true - type: textarea attributes: - label: 📝 Discussion Body + label: Body description: Start your discussion! placeholder: >- Provide a detailed description of your discussion (e.g., What issue are you facing? What feedback do you have? What question do you need answered?) diff --git a/.github/workflows/copilot_labeller.yml b/.github/workflows/copilot_labeller.yml new file mode 100644 index 000000000..afbdc536c --- /dev/null +++ b/.github/workflows/copilot_labeller.yml @@ -0,0 +1,149 @@ +name: Copilot Templated Discussions + +on: + discussion: + types: [created] + +jobs: + label-copilot-discussion: + runs-on: ubuntu-latest + if: ${{ contains(github.event.discussion.category.name, 'Copilot') }} + + steps: + - name: Get discussion body html + id: get_discussion_body_html + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + DISCUSSION_NUMBER: ${{ github.event.discussion.number }} + run: | + gh api graphql -F owner=$OWNER -F name=$REPO -F number=$DISCUSSION_NUMBER -f query=' + query($owner: String!, $name: String!, $number: Int!) { + repository(owner: $owner, name: $name){ + discussion(number: $number) { + bodyHTML + id + } + } + }' > discussion_data.json + + echo 'DISCUSSION_BODY_HTML='$(jq -r '.data.repository.discussion.bodyHTML' discussion_data.json) >> $GITHUB_ENV + echo 'DISCUSSION_ID='$(jq -r '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV + - run: npm install jsdom + + - name: Get selected Copilot feature area + id: get_selected_feature_area + uses: actions/github-script@v6 + with: + result-encoding: string + script: | + try { + const jsdom = require('jsdom'); + const { JSDOM } = jsdom; + const { DISCUSSION_BODY_HTML } = process.env + + const fragment = JSDOM.fragment(DISCUSSION_BODY_HTML); + const featureAreaHeaders = fragment.querySelectorAll("h3"); + const featureAreaHeader = Array.from(featureAreaHeaders).find(header => + header.textContent.trim().toLowerCase().includes('copilot feature area')); + if (!featureAreaHeader) { + return ""; + } + + const selectedAreaElement = featureAreaHeader.nextElementSibling; + if (!selectedAreaElement) { + return ""; + } + + const selectedArea = selectedAreaElement.textContent.trim(); + // Simplify area matching by converting to lowercase + const selectedAreaLower = selectedArea.toLowerCase(); + + // Valid Copilot feature areas (case insensitive matching) + const validAreas = { + "vs code": "VS Code", + "visual studio": "Visual Studio", + "jetbrains & xcode": "JetBrains & Xcode", + "copilot in github": "Copilot in GitHub", + "copilot workspace": "Copilot Workspace", + "copilot edits and code review": "Copilot Edits and Code Review", + "copilot agent mode": "Copilot Agent Mode", + "copilot enterprise": "Copilot Enterprise", + "copilot billing or account‑related": "Copilot Billing or Account‑Related", + "other copilot areas": "Other Copilot Areas" + }; + + // Try to find a matching area (case insensitive) + for (const [key, value] of Object.entries(validAreas)) { + if (selectedAreaLower.includes(key)) { + return value; // Return the properly cased label + } + } + + // If no match found, check if it's exactly one of our valid areas + // This helps with unexpected formatting or spacing + if (selectedArea && Object.values(validAreas).includes(selectedArea)) { + return selectedArea; + } + + // Default to "Other Copilot Areas" if we can't find a specific match + if (selectedArea) { + return "Other Copilot Areas"; + } + + return ""; + } catch (error) { + console.error(error); + return ""; + } + + - name: Fetch label id for selected area + id: fetch_label_id + if: ${{ steps.get_selected_feature_area.outputs.result != '' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + AREA: ${{ steps.get_selected_feature_area.outputs.result }} + run: | + gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$AREA" -f query=' + query($owner: String!, $name: String!, $topic: String) { + repository(owner: $owner, name: $name){ + labels(first: 1, query: $topic) { + edges { + node { + id + name + } + } + } + } + }' > repository_label_data.json + + LABEL_ID=$(jq -r '.data.repository.labels.edges[0]?.node?.id // empty' repository_label_data.json) + if [ -z "$LABEL_ID" ]; then + echo "No matching label found for the selected area. Skipping labeling step." + fi + echo "LABEL_ID=$LABEL_ID" >> $GITHUB_ENV + + - name: Label the discussion + if: ${{ steps.get_selected_feature_area.outputs.result != '' && env.LABEL_ID != '' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api graphql -f query=' + mutation($labelableId: ID!, $labelIds: [ID!]!) { + addLabelsToLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) { + labelable { + labels(first: 10) { + edges { + node { + id + name + } + } + } + } + } + }' -f labelableId=$DISCUSSION_ID -f labelIds[]=$LABEL_ID