chore(triage): tighten bug-report template + add Area dropdown to cut invalid-issue load

170 issues have been closed with the `invalid` label (61 of them in
  the last 30 days alone — ~1 in 5 of all closed issues), almost always
  because the reporter hadn't run the in-app Connection Diagnostic or
  checked the documented troubleshooting page. The Connection Diagnostic
  shipped weeks ago but the bug-report form let people skip it: the
  "I ran it" checkbox was `required: false` and the Support Package
  field was optional. Tighten both.

  Form changes (.github/ISSUE_TEMPLATE/bug_report.yml):

  - Connection Diagnostic checkbox: required: false → true
  - Support Package field: required: false → true ("drag the .zip
    or explain why you cannot attach one")
  - New required textarea "Troubleshooting steps already taken" —
    forces the reporter to type WHAT they tried and WHICH wiki pages
    they checked before submitting. Empty answers can't submit.
  - Pre-form intro spells out the search → wiki → diagnostic →
    support package sequence and cites the 1-in-5 stat
  - Final-checks list grew from one to three required confirmations
    (searched issues + checked troubleshooting wiki + ran Connection
    Diagnostic for any connection/printing/camera issue)

  Bug categorization (the gap that motivated this):

  - Old `Component` dropdown was Bambuddy / SpoolBuddy / Both — no
    area triage signal
  - Replaced with two required dropdowns:
    - Product: Bambuddy / SpoolBuddy
    - Area: 15 options covering the actual feature surface +
      Other / not sure
  - Auto-label workflow (.github/workflows/auto-label-area.yml)
    reads the Area dropdown from the rendered issue body on
    open/edit and applies the matching area:* label. Tolerant of
    CRLF and the _No response_ placeholder, won't re-add on edit
    re-fires, warns on unknown Area values

  Maintainer hand-off — labels must exist BEFORE the workflow runs,
  since github-script's addLabels throws on missing labels. Create the
  16 labels (15 area:* + 1 area:unsorted) once via the `gh label create`
  commands captured in CHANGELOG / commit context.

  OS dropdown left untouched (Docker stays — per Martin).

  Printer Model dropdown verified against backend/app/utils/printer_models.py
  PRINTER_MODEL_MAP: all 13 current models present (X1 Carbon, X1, X1E,
  X2D, P1S, P1P, P2S, A1, A1 Mini, H2D, H2D Pro, H2C, H2S).
This commit is contained in:
maziggy
2026-05-24 16:20:14 +02:00
parent 1e734fb7c6
commit e5ebab7ab8
3 changed files with 165 additions and 19 deletions
+94
View File
@@ -0,0 +1,94 @@
# Auto-apply area:* label from the "Area" dropdown in bug_report.yml.
#
# The bug-report issue form renders dropdown values into the issue body as a
# section like:
#
# ### Area
#
# Printer connection / setup
#
# This workflow parses that section after issue creation/edit and adds the
# matching area:* label. Frees the maintainer from typing the same label on
# every new bug.
#
# Labels referenced here must already exist in the repo — see the
# `gh label create` commands in CHANGELOG for [0.2.5b1].
name: Auto-label Issue Area
on:
issues:
types: [opened, edited]
permissions:
issues: write
jobs:
apply-area-label:
runs-on: ubuntu-latest
if: github.event.issue.pull_request == null
steps:
- name: Apply area:* label from Area dropdown
uses: actions/github-script@v7
with:
script: |
const body = context.payload.issue.body || '';
// Map of Area dropdown value (lowercased, trimmed) → area:* label.
// Keep in lockstep with .github/ISSUE_TEMPLATE/bug_report.yml.
const areaMap = {
'printer connection / setup': 'area:connection',
'print start / dispatch': 'area:print-dispatch',
'filament / ams / spoolman': 'area:filament',
'slicer integration (bambu studio / orcaslicer)': 'area:slicer',
'virtual printer (vp)': 'area:vp',
'camera / live view / timelapse': 'area:camera',
'archives / library / files': 'area:archives',
'statistics': 'area:stats',
'print queue / scheduling': 'area:queue',
'notifications': 'area:notifications',
'authentication / users / permissions': 'area:auth',
'updates / firmware check': 'area:updates',
'ui / display / theme / i18n': 'area:ui',
'api / integrations (home assistant, mqtt export, obico, ...)': 'area:integrations',
'spoolbuddy kiosk / display': 'area:spoolbuddy',
'other / not sure': 'area:unsorted',
};
// GitHub issue forms render dropdown answers under a level-3 heading
// matching the field label. Capture the first non-blank line of the
// section. Tolerant of trailing whitespace and CRLF endings.
const match = body.match(/###\s+Area\s*\r?\n\s*\r?\n\s*([^\r\n]+)/i);
if (!match) {
core.info('No "Area" section found in issue body — skipping.');
return;
}
const picked = match[1].trim().toLowerCase();
// Strip any markdown bold the form might add (rare) and tolerate
// a "_No response_" placeholder some renderers insert for required-
// but-empty fields (shouldn't happen, the field is required).
if (picked === '_no response_' || picked === '') {
core.info('Area field empty — skipping.');
return;
}
const label = areaMap[picked];
if (!label) {
core.warning(`Unrecognised Area value: "${picked}". Update areaMap in auto-label-area.yml.`);
return;
}
// Don't re-add if already present (issue edit path).
const existing = (context.payload.issue.labels || []).map(l => l.name);
if (existing.includes(label)) {
core.info(`Label "${label}" already present — nothing to do.`);
return;
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: [label],
});
core.info(`Applied label "${label}" to issue #${context.payload.issue.number}.`);