@@ -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