auto-label-area.yml 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # Auto-apply area:* label from the "Area" dropdown in bug_report.yml.
  2. #
  3. # The bug-report issue form renders dropdown values into the issue body as a
  4. # section like:
  5. #
  6. # ### Area
  7. #
  8. # Printer connection / setup
  9. #
  10. # This workflow parses that section after issue creation/edit and adds the
  11. # matching area:* label. Frees the maintainer from typing the same label on
  12. # every new bug.
  13. #
  14. # Labels referenced here must already exist in the repo — see the
  15. # `gh label create` commands in CHANGELOG for [0.2.5b1].
  16. name: Auto-label Issue Area
  17. on:
  18. issues:
  19. types: [opened, edited]
  20. permissions:
  21. issues: write
  22. jobs:
  23. apply-area-label:
  24. runs-on: ubuntu-latest
  25. if: github.event.issue.pull_request == null
  26. steps:
  27. - name: Apply area:* label from Area dropdown
  28. uses: actions/github-script@v7
  29. with:
  30. script: |
  31. const body = context.payload.issue.body || '';
  32. // Map of Area dropdown value (lowercased, trimmed) → area:* label.
  33. // Keep in lockstep with .github/ISSUE_TEMPLATE/bug_report.yml.
  34. const areaMap = {
  35. 'printer connection / setup': 'area:connection',
  36. 'print start / dispatch': 'area:print-dispatch',
  37. 'filament / ams / spoolman': 'area:filament',
  38. 'slicer integration (bambu studio / orcaslicer)': 'area:slicer',
  39. 'virtual printer (vp)': 'area:vp',
  40. 'camera / live view / timelapse': 'area:camera',
  41. 'archives / library / files': 'area:archives',
  42. 'statistics': 'area:stats',
  43. 'print queue / scheduling': 'area:queue',
  44. 'notifications': 'area:notifications',
  45. 'authentication / users / permissions': 'area:auth',
  46. 'updates / firmware check': 'area:updates',
  47. 'ui / display / theme / i18n': 'area:ui',
  48. 'api / integrations (home assistant, mqtt export, obico, ...)': 'area:integrations',
  49. 'spoolbuddy kiosk / display': 'area:spoolbuddy',
  50. 'other / not sure': 'area:unsorted',
  51. };
  52. // GitHub issue forms render dropdown answers under a level-3 heading
  53. // matching the field label. Capture the first non-blank line of the
  54. // section. Tolerant of trailing whitespace and CRLF endings.
  55. const match = body.match(/###\s+Area\s*\r?\n\s*\r?\n\s*([^\r\n]+)/i);
  56. if (!match) {
  57. core.info('No "Area" section found in issue body — skipping.');
  58. return;
  59. }
  60. const picked = match[1].trim().toLowerCase();
  61. // Strip any markdown bold the form might add (rare) and tolerate
  62. // a "_No response_" placeholder some renderers insert for required-
  63. // but-empty fields (shouldn't happen, the field is required).
  64. if (picked === '_no response_' || picked === '') {
  65. core.info('Area field empty — skipping.');
  66. return;
  67. }
  68. const label = areaMap[picked];
  69. if (!label) {
  70. core.warning(`Unrecognised Area value: "${picked}". Update areaMap in auto-label-area.yml.`);
  71. return;
  72. }
  73. // Don't re-add if already present (issue edit path).
  74. const existing = (context.payload.issue.labels || []).map(l => l.name);
  75. if (existing.includes(label)) {
  76. core.info(`Label "${label}" already present — nothing to do.`);
  77. return;
  78. }
  79. await github.rest.issues.addLabels({
  80. owner: context.repo.owner,
  81. repo: context.repo.repo,
  82. issue_number: context.payload.issue.number,
  83. labels: [label],
  84. });
  85. core.info(`Applied label "${label}" to issue #${context.payload.issue.number}.`);