From bab9b50643d1ec47fd6adb5d9efbb92752f5fc48 Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Tue, 6 Oct 2026 11:58:53 +0200 Subject: [PATCH] feat(qa): sonar triage --no-webhook (file issues now, deliver them with --drain) Co-Authored-By: Claude Sonnet 5.5 --- scripts/sonar_triage.mjs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/sonar_triage.mjs b/scripts/sonar_triage.mjs index 4f2b60c..6ea9988 100644 --- a/scripts/sonar_triage.mjs +++ b/scripts/sonar_triage.mjs @@ -147,7 +147,7 @@ export function postWebhook(url, payload) { return { ok: code >= 200 && code < 300, code }; } -function ghIssues(groups, apply, cap, log, lane = 'fix') { +function ghIssues(groups, apply, cap, log, lane = 'fix', noHook = false) { const agentLabel = lane === 'refactor' ? 'agent-refactor' : 'agent-fix'; if (run('gh', ['auth', 'status']).status !== 0) { log('gh unauthenticated: skipping GitHub issues (run `gh auth login`).'); return []; } const list = run('gh', ['issue', 'list', '--state', 'open', '--label', 'sonar', '--limit', '300', '--json', 'number,body']); @@ -167,7 +167,8 @@ function ghIssues(groups, apply, cap, log, lane = 'fix') { // Mechanism 1: a multica autopilot webhook (URL is a secret: env MULTICA_WEBHOOK_URL or ~/.config/multica-webhook). // Mechanism 2 (fallback): the multica CLI, which refuses to run in an agent context. const hook = webhookUrl(process.env, undefined, lane); - if (hook) { + if (noHook) { log(' webhook skipped (--no-webhook): use --drain to deliver it'); } + else if (hook) { const w = postWebhook(hook, { source: 'sonar-triage', rule: g.rule, title: g.title, github_issue_url: url, files: g.files, sonar_keys: g.keys, effort_min: g.effort, body: issueBody(g) }); log(w.ok ? ` multica autopilot fired (HTTP ${w.code})` : ` multica webhook failed (HTTP ${w.code || 'none'}): assign the issue manually`); } else { @@ -243,6 +244,7 @@ export async function main(argv, deps = {}) { else if (f === '--cap') { a.cap = +argv[++i]; a.capSet = true; } else if (f === '--lane') { a.lane = argv[++i]; if (!['fix', 'refactor'].includes(a.lane)) throw new Error('--lane must be fix or refactor'); } else if (f === '--drain') a.drain = true; + else if (f === '--no-webhook') a.noHook = true; else if (f === '--timeout') a.timeout = +argv[++i]; else if (f === '--resends') a.resends = +argv[++i]; else if (f === '--exclude-rules') a.exclude = (argv[++i] || '').split(',').filter(Boolean); @@ -274,7 +276,7 @@ export async function main(argv, deps = {}) { : groupIssues(all)).filter((g) => !(a.exclude || []).includes(g.rule)); const cap = lane === 'refactor' && !a.capSet ? 3 : a.cap; log(`\n${lane === 'refactor' ? 'Refactor' : 'Medium+'} groups (${lane === 'refactor' ? 'one per function' : 'per rule, max 40 locations'}): ${groups.length}`); - ghIssues(groups, a.apply, cap, log, lane); + ghIssues(groups, a.apply, cap, log, lane, !!a.noHook); if (a.fixSmall) { if (a.apply) fixSmall(res.small, log); else log('fix-small needs --apply (dry-run).'); } return res; }