Skip to content

Commit 6a47b7b

Browse files
msukkariclaude
andcommitted
fix: unique CodeQL IDs, richer descriptions, exclude cancelled Linear issues
- CodeQL alert IDs now include alert number (codeql:rule#N) so each alert gets its own Linear issue instead of being grouped by rule - Enhanced Claude prompt for CodeQL: explicit per-alert treatment, detailed description requirements (file, lines, code, remediation) - Linear dedup query now filters out cancelled issues so rejected findings can be re-triaged Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0ad24b0 commit 6a47b7b

1 file changed

Lines changed: 18 additions & 9 deletions

File tree

.github/workflows/trivy-vulnerability-triage.yml

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ jobs:
344344
fi
345345
346346
EXTRACTED=$(echo "$BODY" | jq '[.[] | {
347-
id: ("codeql:" + (.rule.id // "")),
347+
id: ("codeql:" + (.rule.id // "") + "#" + ((.number // 0) | tostring)),
348348
number: .number,
349349
rule_id: (.rule.id // ""),
350350
rule_description: (.rule.description // ""),
@@ -405,7 +405,7 @@ jobs:
405405
406406
1. **Trivy scan results** in `trivy-alerts.json` — each entry has `id` (CVE ID, e.g., `CVE-2024-1234`)
407407
2. **Dependabot alerts** in `dependabot-alerts.json` — each entry has `id` (CVE ID or GHSA ID)
408-
3. **CodeQL alerts** in `codeql-alerts.json` — each entry has `id` (prefixed, e.g., `codeql:js/sql-injection`)
408+
3. **CodeQL alerts** in `codeql-alerts.json` — each entry has `id` (prefixed, e.g., `codeql:js/sql-injection#33`)
409409
410410
## Your Task
411411
@@ -422,12 +422,19 @@ jobs:
422422
- Include the affected package, severity, remediation steps, and whether it is direct or transitive.
423423
424424
4. For **CodeQL findings**:
425-
- Use the `id` field as `cveId` (already prefixed with `codeql:`).
425+
- Each CodeQL alert is a **separate finding** — do NOT group alerts by rule ID. Two alerts with the
426+
same rule but different files/locations must be separate entries.
427+
- Use the `id` field as `cveId` (e.g., `codeql:js/path-injection#18`).
426428
- Set `source` to `"codeql"`.
427-
- Include the file location (path and line numbers) and rule description in the `description`.
428-
- Include the alert URL for reference.
429-
- Use `affectedPackage` to indicate the file path where the issue was found.
429+
- Set `affectedPackage` to the file path from `location_path`.
430430
- Normalize `security_severity_level` to uppercase (CRITICAL/HIGH/MEDIUM/LOW).
431+
- The `description` should include:
432+
- The rule ID and what it detects
433+
- The exact file path and line number(s) from the alert
434+
- A link to the alert URL (`html_url`)
435+
- An explanation of the specific code at that location and why it's flagged
436+
- Concrete remediation steps with code examples where possible
437+
- A link to the CodeQL rule documentation
431438
432439
5. For each finding, determine:
433440
- A short `title` suitable for a Linear issue title.
@@ -438,14 +445,16 @@ jobs:
438445
dependencies. Use `yarn why <package> --recursive` to determine why an npm package is included.
439446
440447
7. **Check Linear for existing issues** for each finding:
441-
- For each `cveId` (whether CVE ID, GHSA ID, or `codeql:<rule_id>`), run a GraphQL query
442-
against the Linear API to search for issues whose title contains that ID.
448+
- For each `cveId`, run a GraphQL query against the Linear API to search for issues
449+
whose title contains that ID.
450+
- **Important**: Exclude cancelled issues so that previously cancelled/rejected findings
451+
can be re-created. Use a state type filter to only match active issues.
443452
- Use the following curl command pattern:
444453
```
445454
curl -s -X POST https://api.linear.app/graphql \
446455
-H "Content-Type: application/json" \
447456
-H "Authorization: $LINEAR_API_KEY" \
448-
-d '{"query": "query { issues(filter: { team: { id: { eq: \"'$LINEAR_TEAM_ID'\" } }, title: { contains: \"<ID>\" } }) { nodes { id title } } }"}'
457+
-d '{"query": "query { issues(filter: { team: { id: { eq: \"'$LINEAR_TEAM_ID'\" } }, title: { contains: \"<ID>\" }, state: { type: { nin: [\"canceled\"] } } }) { nodes { id title } } }"}'
449458
```
450459
- Set `linearIssueExists` to `true` if any matching issue is found, `false` otherwise.
451460

0 commit comments

Comments
 (0)