* [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* [PATCH BlueZ v1 2/3] github: Make result posting robust against action failures
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 ` 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
2 siblings, 0 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>
Use always() conditions with file-existence checks so steps 1-4
results are posted even if the btsnoop-analyzer action fails
partway through. The error comment now only fires on actual action
failure (e.g. btmon build error), not LLM errors which are handled
gracefully by the analyzer.
---
.github/workflows/btsnoop-analyzer.yml | 34 +++++++++++++++++---------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/btsnoop-analyzer.yml b/.github/workflows/btsnoop-analyzer.yml
index 3bbd963004cb..9ecda193ceff 100644
--- a/.github/workflows/btsnoop-analyzer.yml
+++ b/.github/workflows/btsnoop-analyzer.yml
@@ -100,12 +100,14 @@ jobs:
GH_MODELS_TOKEN: ${{ secrets.GH_MODELS_TOKEN }}
- name: Post detection comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const detect = fs.readFileSync('${{ steps.analysis.outputs.detect }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.detect }}';
+ if (!fs.existsSync(path)) return;
+ const detect = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -114,12 +116,14 @@ jobs:
});
- name: Post filter comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const filter = fs.readFileSync('${{ steps.analysis.outputs.filter }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.filter }}';
+ if (!fs.existsSync(path)) return;
+ const filter = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -128,12 +132,14 @@ jobs:
});
- name: Post annotation comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const annotate = fs.readFileSync('${{ steps.analysis.outputs.annotate }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.annotate }}';
+ if (!fs.existsSync(path)) return;
+ const annotate = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -142,12 +148,14 @@ jobs:
});
- name: Post diagnostics comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const diagnose = fs.readFileSync('${{ steps.analysis.outputs.diagnose }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.diagnose }}';
+ if (!fs.existsSync(path)) return;
+ const diagnose = fs.readFileSync(path, 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -156,12 +164,14 @@ jobs:
});
- name: Post analysis comment
- if: steps.parse.outputs.found == 'true' && success()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome != 'skipped'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
- const analysis = fs.readFileSync('${{ steps.analysis.outputs.analyze }}', 'utf8');
+ const path = '${{ steps.analysis.outputs.analyze }}';
+ if (!fs.existsSync(path)) return;
+ const analysis = fs.readFileSync(path, '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'
@@ -177,7 +187,7 @@ jobs:
});
- name: Post error comment
- if: steps.parse.outputs.found == 'true' && failure()
+ if: always() && steps.parse.outputs.found == 'true' && steps.analysis.outcome == 'failure'
uses: actions/github-script@v7
with:
script: |
@@ -190,7 +200,7 @@ jobs:
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
+ - btmon build failure
A maintainer will review your trace manually.
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH BlueZ v1 3/3] github: Add btsnoop-analyzer slash command workflow
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 ` 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
2 siblings, 0 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>
Add caller workflow for the btsnoop-analyzer reusable workflow,
enabling trace analysis from any issue comment.
---
.github/workflows/btsnoop-analyze.yml | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 .github/workflows/btsnoop-analyze.yml
diff --git a/.github/workflows/btsnoop-analyze.yml b/.github/workflows/btsnoop-analyze.yml
new file mode 100644
index 000000000000..484288c0d9b6
--- /dev/null
+++ b/.github/workflows/btsnoop-analyze.yml
@@ -0,0 +1,13 @@
+name: Analyze on mention
+
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ analyze:
+ if: >-
+ github.event.issue.pull_request == null &&
+ contains(github.event.comment.body, '/analyze')
+ uses: Vudentz/btsnoop-analyzer/.github/workflows/analyze-on-mention.yml@master
+ secrets: inherit
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH BlueZ v1 1/3] github: Add YAML issue template and btsnoop-analyzer workflow
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 ` patchwork-bot+bluetooth
2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+bluetooth @ 2026-04-16 17:30 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Wed, 15 Apr 2026 14:22:07 -0400 you wrote:
> 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.
>
> [...]
Here is the summary with links:
- [BlueZ,v1,1/3] github: Add YAML issue template and btsnoop-analyzer workflow
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=b73ba12b0bd6
- [BlueZ,v1,2/3] github: Make result posting robust against action failures
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=ec6940c1a284
- [BlueZ,v1,3/3] github: Add btsnoop-analyzer slash command workflow
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=ce07e906e499
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [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