public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v1 1/3] github: Add YAML issue template and btsnoop-analyzer workflow
@ 2026-04-15 18:22 Luiz Augusto von Dentz
  2026-04-15 18:22 ` [PATCH BlueZ v1 2/3] github: Make result posting robust against action failures Luiz Augusto von Dentz
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2026-04-15 18:22 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Replace the markdown issue template with a structured YAML form that
includes fields for description, reproduction steps, btmon trace upload,
analysis focus area selection, and privacy consent checkboxes.

Add a btsnoop-analyzer workflow that automatically analyzes btsnoop
traces attached to new issues using Vudentz/btsnoop-analyzer action,
posting results as issue comments.
---
 .github/ISSUE_TEMPLATE/issue.md        |  41 -----
 .github/ISSUE_TEMPLATE/issue.yml       | 108 +++++++++++++
 .github/workflows/btsnoop-analyzer.yml | 202 +++++++++++++++++++++++++
 3 files changed, 310 insertions(+), 41 deletions(-)
 delete mode 100644 .github/ISSUE_TEMPLATE/issue.md
 create mode 100644 .github/ISSUE_TEMPLATE/issue.yml
 create mode 100644 .github/workflows/btsnoop-analyzer.yml

diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md
deleted file mode 100644
index ba384e120bac..000000000000
--- a/.github/ISSUE_TEMPLATE/issue.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-name: New issue
-about: 'Report a bug or other problem'
-title: ''
-labels: ''
-assignees: ''
-
----
-
-### Description
-
-<!-- A clear and concise description of what the bug is -->
-
-<!-- A clear and concise description of what you expected to happen -->
-
-<!-- Include any other relevant details -->
-
-### To reproduce
-<!-- Steps to reproduce the issue, if possible -->
-1.
-2.
-3.
-4.
-
-### Logs
-- btmon log: <!-- Bluetooth traffic dump: (usually needed)
-                  0. Power off connected device
-                  1. Run: btmon -w btmon.log
-                  2. Connect device, reproduce the issue
-                  3. Ctrl-C btmon
-                  4. Attach btmon.log to the issue -->
-- bluetoothd log: <!-- Run: journalctl -u bluetooth --boot 0 > bluetoothd.log; if relevant for issue -->
-
-<!-- Any other logs etc. relevant for the issue -->
-
-### Versions
-- BlueZ version:  <!-- Run: bluetoothctl --version -->
-- Kernel version:  <!-- Run: uname -r -->
-- Problematic device: <!-- Device model etc information, if relevant -->
-
-<!-- Any other relevant information on platform / hardware here -->
diff --git a/.github/ISSUE_TEMPLATE/issue.yml b/.github/ISSUE_TEMPLATE/issue.yml
new file mode 100644
index 000000000000..0f069858eeaf
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/issue.yml
@@ -0,0 +1,108 @@
+name: New issue
+description: Report a bug or other problem
+labels: []
+body:
+  - type: textarea
+    id: description
+    attributes:
+      label: Description
+      description: |
+        A clear and concise description of the bug, what you expected
+        to happen, and any other relevant details.
+      placeholder: Describe the issue...
+    validations:
+      required: true
+
+  - type: textarea
+    id: reproduce
+    attributes:
+      label: To reproduce
+      description: Steps to reproduce the issue, if possible.
+      placeholder: |
+        1.
+        2.
+        3.
+        4.
+    validations:
+      required: false
+
+  - type: textarea
+    id: trace-file
+    attributes:
+      label: btmon trace
+      description: |
+        Drag and drop your btsnoop trace file here. If a trace is
+        attached and the privacy acknowledgment below is checked,
+        it will be automatically analyzed by
+        [btsnoop-analyzer](https://github.com/Vudentz/btsnoop-analyzer).
+
+        To capture a trace: power off the device, run `btmon -w btmon.log`,
+        reproduce the issue, then Ctrl-C btmon.
+      placeholder: Drag and drop your btmon.log file here...
+    validations:
+      required: false
+
+  - type: dropdown
+    id: focus-area
+    attributes:
+      label: Analysis focus
+      description: >
+        If you attached a btsnoop trace, what aspect should the
+        automated analysis focus on? Select "General" to auto-detect.
+      options:
+        - General (full analysis)
+        - Connection issues
+        - Controller enumeration
+        - Pairing / Security
+        - GATT discovery
+        - Audio
+        - Audio / LE Audio
+        - Audio / A2DP
+        - Audio / HFP
+        - L2CAP channel issues
+        - Advertising / Scanning
+        - Disconnection analysis
+        - Channel Sounding
+    validations:
+      required: false
+
+  - type: checkboxes
+    id: privacy
+    attributes:
+      label: Privacy
+      description: |
+        btsnoop traces contain Bluetooth MAC addresses and may contain
+        device names. By default, MAC addresses are anonymized before
+        being sent to an LLM for analysis.
+      options:
+        - label: >
+            **Skip anonymization** — Send the raw decoded trace to the
+            LLM without scrubbing MAC addresses or device names.
+          required: false
+        - label: >
+            I understand this trace will be processed by a third-party
+            LLM API and I have the right to share this data.
+          required: false
+
+  - type: textarea
+    id: logs
+    attributes:
+      label: Other logs
+      description: |
+        Attach bluetoothd or other relevant logs.
+        Run: `journalctl -u bluetooth --boot 0 > bluetoothd.log`
+      render: text
+    validations:
+      required: false
+
+  - type: textarea
+    id: versions
+    attributes:
+      label: Versions
+      description: BlueZ version, kernel version, and device information.
+      value: |
+        - BlueZ version:
+        - Kernel version:
+        - Problematic device:
+    validations:
+      required: false
diff --git a/.github/workflows/btsnoop-analyzer.yml b/.github/workflows/btsnoop-analyzer.yml
new file mode 100644
index 000000000000..3bbd963004cb
--- /dev/null
+++ b/.github/workflows/btsnoop-analyzer.yml
@@ -0,0 +1,202 @@
+name: btsnoop-analyzer
+
+on:
+  issues:
+    types: [opened, reopened]
+
+permissions:
+  issues: write
+  contents: read
+
+jobs:
+  analyze:
+    # Only run when the user acknowledged the privacy statement
+    if: contains(github.event.issue.body, 'I understand this trace will be processed')
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+
+    steps:
+      - name: Parse issue body
+        id: parse
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const body = context.payload.issue.body || '';
+
+            // Extract trace file URL from issue body
+            const urlPatterns = [
+              /https:\/\/github\.com\/[^\s)]+\.(?:log|snoop|btsnoop|cfa)/gi,
+              /https:\/\/github\.com\/user-attachments\/(?:files|assets)\/[^\s)]+/gi,
+            ];
+
+            let traceUrl = '';
+            for (const pattern of urlPatterns) {
+              const match = body.match(pattern);
+              if (match) {
+                traceUrl = match[0];
+                break;
+              }
+            }
+
+            if (!traceUrl) {
+              console.log('No trace file URL found — skipping analysis');
+              core.setOutput('found', 'false');
+              return;
+            }
+
+            // Extract description
+            const descMatch = body.match(
+              /### Description\s*\n([\s\S]*?)(?=\n###|\n\*\*|$)/i
+            );
+            const description = descMatch?.[1]?.trim() || 'No description provided';
+
+            // Extract focus area
+            const focusMatch = body.match(
+              /### Analysis focus\s*\n\s*(\S[^\n]*)/i
+            );
+            const focus = focusMatch?.[1]?.trim() || 'General (full analysis)';
+
+            // Check anonymization preference
+            const skipAnon = body.includes('[X] **Skip anonymization**') ||
+                             body.includes('[x] **Skip anonymization**');
+
+            core.setOutput('found', 'true');
+            core.setOutput('trace_url', traceUrl);
+            core.setOutput('description', description);
+            core.setOutput('focus', focus);
+            core.setOutput('anonymize', skipAnon ? 'false' : 'true');
+
+            console.log(`Trace URL: ${traceUrl}`);
+            console.log(`Focus: ${focus}`);
+            console.log(`Anonymize: ${!skipAnon}`);
+
+      - name: Post "analyzing" comment
+        if: steps.parse.outputs.found == 'true'
+        uses: actions/github-script@v7
+        with:
+          script: |
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: '**btsnoop Analyzer** is processing your trace. This typically takes 1-3 minutes.\n\n_Decoding with btmon, then sending to LLM for analysis..._'
+            });
+
+      - name: Run btsnoop-analyzer
+        if: steps.parse.outputs.found == 'true'
+        id: analysis
+        uses: Vudentz/btsnoop-analyzer@master
+        with:
+          trace-url: ${{ steps.parse.outputs.trace_url }}
+          description: ${{ steps.parse.outputs.description }}
+          focus: ${{ steps.parse.outputs.focus }}
+          anonymize: ${{ steps.parse.outputs.anonymize }}
+          provider: ${{ vars.LLM_PROVIDER || 'github' }}
+          model: ${{ vars.LLM_MODEL || '' }}
+        env:
+          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GH_MODELS_TOKEN: ${{ secrets.GH_MODELS_TOKEN }}
+
+      - name: Post detection comment
+        if: steps.parse.outputs.found == 'true' && success()
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require('fs');
+            const detect = fs.readFileSync('${{ steps.analysis.outputs.detect }}', 'utf8');
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: detect
+            });
+
+      - name: Post filter comment
+        if: steps.parse.outputs.found == 'true' && success()
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require('fs');
+            const filter = fs.readFileSync('${{ steps.analysis.outputs.filter }}', 'utf8');
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: filter
+            });
+
+      - name: Post annotation comment
+        if: steps.parse.outputs.found == 'true' && success()
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require('fs');
+            const annotate = fs.readFileSync('${{ steps.analysis.outputs.annotate }}', 'utf8');
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: annotate
+            });
+
+      - name: Post diagnostics comment
+        if: steps.parse.outputs.found == 'true' && success()
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require('fs');
+            const diagnose = fs.readFileSync('${{ steps.analysis.outputs.diagnose }}', 'utf8');
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: diagnose
+            });
+
+      - name: Post analysis comment
+        if: steps.parse.outputs.found == 'true' && success()
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require('fs');
+            const analysis = fs.readFileSync('${{ steps.analysis.outputs.analyze }}', 'utf8');
+
+            const footer = `\n\n---\n<sub>Analyzed by [btsnoop-analyzer](https://github.com/Vudentz/btsnoop-analyzer) using btmon from [BlueZ](https://github.com/bluez/bluez). MAC addresses ${
+              '${{ steps.parse.outputs.anonymize }}' === 'true'
+                ? 'were anonymized'
+                : 'were **not** anonymized (user opted out)'
+            } before LLM processing.</sub>`;
+
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: analysis + footer
+            });
+
+      - name: Post error comment
+        if: steps.parse.outputs.found == 'true' && failure()
+        uses: actions/github-script@v7
+        with:
+          script: |
+            await github.rest.issues.createComment({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: context.issue.number,
+              body: `## Analysis Failed
+
+            The automated analysis encountered an error. This could be due to:
+            - Unsupported trace file format
+            - Trace file too large to process
+            - LLM API rate limiting or downtime
+
+            A maintainer will review your trace manually.
+
+            <details>
+            <summary>Debug info</summary>
+
+            Workflow run: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}
+            </details>`
+            });
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-04-16 17:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-15 18:22 [PATCH BlueZ v1 1/3] github: Add YAML issue template and btsnoop-analyzer workflow Luiz Augusto von Dentz
2026-04-15 18:22 ` [PATCH BlueZ v1 2/3] github: Make result posting robust against action failures Luiz Augusto von Dentz
2026-04-15 18:22 ` [PATCH BlueZ v1 3/3] github: Add btsnoop-analyzer slash command workflow Luiz Augusto von Dentz
2026-04-16 17:30 ` [PATCH BlueZ v1 1/3] github: Add YAML issue template and btsnoop-analyzer workflow patchwork-bot+bluetooth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox