feat(ci-failures): enrich scan-failure issue bodies with parsed grype/trivy findings - #995
Merged
Merged
Conversation
…/trivy findings When a repeated default-branch failure is a scan/vulnerability gate, parse the scanner's findings table out of the job log and render it as a structured markdown list in the issue body — package, installed version, fixed-in version, severity, and the file/binary location when the scanner reports one — above the raw log excerpt, which is kept for context and non-scan failures. - Add parseScanFindings(): parses grype/trivy space-aligned findings tables out of a job log, handling GHA [grype]/[trivy] line prefixes, ─── separator rows, and summary lines; returns [] for logs without a table. - Add isScanFailure(): gates enrichment on a scan/vuln workflow or job name, or on the log itself carrying a findings table. - buildIssueDraft renders the findings table (capped at 50 rows) above the raw excerpt only for scan failures; non-scan bodies are byte-identical to before. - computeFailureSignature (dedup) and the recovery-close path are unchanged. Fixes #994 Signed-off-by: Saffron <263493777+itsmiso-ai@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
AI Automated Review
Full PR review.
Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — primary route
Review: PR PR 995 — Enrich scan-failure issue bodies with parsed grype/trivy findings
Recommendation: Approve.
This PR fully satisfies issue PR 994's acceptance criteria and implements the feature cleanly within the existing ci-failure-ingestion.ts module.
Change-by-change findings
src/lib/ci-failure-ingestion.ts (+136 / -2)
ScanFindinginterface — correctly capturespackage,installed,fixedIn,severity, and optionallocationfields, matching issue requirements.SCAN_COLUMN_ALIASES— maps grype and trivy header variants (name/package,version/installed,fix version/fixed version/fixed in,location/target/file/path) so the parser is robust across scanner output formats.splitScanRow— splits on two-or-more-space delimiters, handling space-aligned scanner tables correctly.stripLinePrefix— strips GHA wrapper tags ([grype],[trivy]) so the parser works on live job log excerpts, not just bare scanner output.isSeparatorRow— correctly skips─────────────separator lines under headers.parseScanFindings— walks lines looking for a header row (must have name/package + version/installed columns), then maps each data row. Filters out summary lines like"3 vulnerabilities found"(bare number in package column). Returns[]for non-scan logs, makingisScanFailurea simple two-step check.isScanFailure— matches on workflow/job name keywords (scan|vuln|trivy|grype|vulnerab|security, case-insensitive), and falls back to log-content detection viaparseScanFindings— so unnamed workflows that emit grype output are still caught.buildIssueDraft— now callsisScanFailure+parseScanFindingsand inserts a markdown table above the raw excerpt. Findings are capped at 50 rows with a "showing first 50" annotation when truncated, addressing the hard issue-body size limit.- No changes to
computeFailureSignatureor the close/recovery path, as required.
src/lib/ci-failure-ingestion.test.ts (+142 / -0)
- Real grype log fixture including the
[grype] NAME VERSION FIX VERSION ...header with box-drawing separators, embedded in a full GHA log with exit-code lines — reproduces the elixir-gate scenario from the issue. - Tests verify all four
ScanFindingfields including optionallocation. - Trivy-style table with
TARGETcolumn confirms the column-aliasing logic. isScanFailuretests cover: named scan workflows, log-content detection, and non-scan negatives.buildIssueDrafttests verify table ordering (findings before raw excerpt), raw excerpt preservation, non-scan unchanged, and the 50-row cap behavior.
Standards Compliance
Per AGENTS.md conventions, this change:
- ✅ Adds no agent-specific names in generic docs/code (
parseScanFindings,ScanFinding,isScanFailureare generic) - ✅ Validates inputs before processing (
parseScanFindingsreturns[]for empty/null log) - ✅ Uses appropriate TypeScript types (
ScanFindinginterface, column aliasing, null checks) - ✅ No secrets committed; only source code and tests modified
Linked Issue Fit
Issue PR 994 acceptance criteria are fully addressed:
| Criterion | Status |
|---|---|
| Scan-gate failure body contains findings table with package, installed, fixed-in, severity, location | ✅ Parsed and rendered |
| Non-scan failures unchanged | ✅ Tested explicitly |
| Unit test with real grype fixture | ✅ grypeLog fixture with authentic output |
No change to computeFailureSignature (dedup) |
✅ Not touched |
| No change to recovery-close path | ✅ Not touched |
CI Results
All checks passed: Lint, Typecheck, Tests, Build, Docker Build, npm audit, Coverage.
Unknowns / Needs Verification
None. The diff, tests, and linked issue all provide sufficient evidence that the implementation is correct, complete, and follows repository conventions.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Enriches scan-failure issue bodies with a structured markdown table of parsed grype/trivy findings.
Fixes #994
Opened by foreman on review GO (workload wl-misospace-dispatch-994).