Skip to content

feat(ci): Add diff-aware scanning and GitHub PR commenting - #509

Merged
shivasurya merged 22 commits into
mainfrom
shiva/pr-01-github-pr-integ
Feb 8, 2026
Merged

shivasurya merged 22 commits into
mainfrom
shiva/pr-01-github-pr-integ

Conversation

@shivasurya

@shivasurya shivasurya commented Feb 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add diff/ package for computing changed files between git refs using git merge-base and git diff
  • Add diff-aware detection filtering so CI scans only report findings in files changed by the PR
  • Add github/ package with full GitHub REST API client for PR commenting
  • Post summary comments with severity badges, sorted findings table, and file links
  • Post inline review comments on critical/high findings using the pull request review API
  • Marker-based deduplication prevents duplicate comments on re-runs
  • Fix container rules execution in CI command (was missing from ci.go)

New CLI Flags

--base              Base git ref for diff-aware scanning (auto-detected in CI)
--head              Head git ref for diff-aware scanning (default: HEAD)
--no-diff           Disable diff-aware scanning
--github-token      GitHub API token for posting PR comments
--github-repo       GitHub repository in owner/repo format
--github-pr         Pull request number
--pr-comment        Post summary comment on the pull request
--pr-inline         Post inline review comments for critical/high findings

Test plan

  • Unit tests: 4300+ lines across 10 test files, all passing
  • gradle buildGo, testGo, lintGo all green
  • E2E: Summary comment posted with badges, findings table, file links
  • E2E: Inline review comments on critical/high lines only
  • E2E: Idempotency — re-runs update existing comments, no duplicates
  • E2E: Zero-findings PR shows green "Pass" badge
  • E2E: Diff-aware filtering excludes files not in the PR diff

Output

Screenshot 2026-02-07 at 9 53 55 PM Screenshot 2026-02-07 at 9 57 12 PM

🤖 Generated with Claude Code

shivasurya and others added 17 commits February 7, 2026 14:47
…f validation

Introduces the sast-engine/diff/ package with two ChangedFilesProvider
implementations (git merge-base and GitHub PR API) and git ref validation.
This is the foundation for diff-aware scanning and PR comment integration.

- ChangedFilesProvider interface with factory that prefers GitHub API
- GitDiffProvider: uses git merge-base + git diff --name-only
- GitHubAPIDiffProvider: uses GitHub PR files endpoint with pagination
- ValidateGitRef: validates refs via git rev-parse --verify
- 92.8% test coverage with real git repos and httptest mocks

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Adds output/filter.go with DiffFilter that filters EnrichedDetection
results to only include findings in changed files. This connects the
diff/ package (PR 1) to the detection pipeline — PR 3 will wire it
into ci.go and scan.go.

- NewDiffFilter: builds a changed-file set from path list
- Filter: keeps detections whose RelPath matches changed files
- FilteredCount: reports how many detections would be excluded
- ChangedFileCount: reports size of the changed-file set
- 100% test coverage on filter.go (27 test cases)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…i/scan commands

Wire diff-aware scanning into ci.go and scan.go via shared helpers in
diff_helpers.go. CI mode enables diff-aware by default (--no-diff to disable)
with auto-detection from GITHUB_BASE_REF, CI_MERGE_REQUEST_TARGET_BRANCH_NAME,
and PATHFINDER_BASELINE_REF. Scan mode is opt-in via --diff-aware flag.
Both commands support --base, --head, --github-token, --github-repo, --github-pr
flags for flexible diff computation. 100% test coverage on diff_helpers.go.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Strip the GitHub API-based changed files provider and all associated
CLI flags (--github-token, --github-repo, --github-pr). Git diff is
sufficient for computing changed files. GitHub API integration will be
re-introduced in a later PR specifically for PR comment posting, which
uses a different API endpoint entirely.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add the github/ package with a thin HTTP client wrapping the GitHub REST
API endpoints needed for posting PR comments and inline review comments.

- Client supports: GetPullRequest, ListComments, CreateComment,
  UpdateComment, CreateReview, ListReviewComments, DeleteReviewComment
- Uses net/http (no new dependencies), context support, 30s timeout
- Token auth via Authorization header, pagination for list endpoints
- Types for Comment, ReviewComment, PullRequest, ReviewCommentInput
- 91% test coverage using httptest mock servers

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add CommentManager for creating/updating PR summary comments with
marker-based deduplication (finds existing comment, updates in-place).

- PostOrUpdate: idempotent post-or-update using hidden HTML marker
- FormatSummaryComment: markdown with shields.io badges, findings table,
  collapsible details section, severity counts, scan metrics
- Severity badges turn green when count is zero, colored when > 0
- Critical findings trigger a warning callout
- 95% test coverage with httptest mock servers

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add ReviewManager for posting inline review comments on critical and
high severity findings with marker-based update-in-place.

- PostInlineComments: batches new comments into atomic review, updates
  existing comments individually via hidden HTML markers
- FormatInlineComment: severity emoji, description, taint flow
  (source->sink), CWE/OWASP references
- ShouldPostInline: only critical/high get inline comments
- filterEligible: validates severity + location before posting
- indexByMarker: matches existing comments for dedup
- 100% code coverage on review.go (every function)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add prCommentOptions struct with validation, parseGitHubRepo helper,
and postPRComments orchestrator that posts summary and/or inline review
comments on GitHub PRs. Register five new CLI flags (--github-token,
--github-repo, --github-pr, --pr-comment, --pr-inline) on the ci
command. PR commenting runs after output generation with soft failure
(warning + continue) so CI reports are always produced.

Also adds SetBaseURL to github.Client for test server injection and a
newGitHubClient factory variable (matching osExit pattern) for full
httptest coverage of postPRComments success and error paths.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Fix three issues found by reviewing GitHub REST API documentation:

1. UpdateComment used issues/comments endpoint for review comments,
   which would 404. Add UpdateReviewComment using pulls/comments
   endpoint and call it from ReviewManager.PostInlineComments.

2. Add side:"RIGHT" to ReviewCommentInput so inline comments
   explicitly target the new file version in the diff.

3. Change auth header from "token" to "Bearer" prefix per current
   GitHub API recommendations.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
The CI command was missing the container rules execution path that
scan.go already had. Docker/docker-compose rules use @dockerfile_rule
and @compose_rule decorators which are loaded via LoadContainerRules,
not LoadRules. Without this, CI mode with --rules pointing to Docker
rule directories would find 0 rules and post empty comments.

Add extractContainerFiles + LoadContainerRules + executeContainerRules
flow to ci.go, matching the existing pattern in scan.go. Container
detections are merged with code analysis detections before diff
filtering and PR commenting.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
FilesScanned incorrectly used len(codeGraph.Nodes) which counts AST
nodes, not unique files. RulesExecuted only counted code analysis rules,
missing container rules entirely. Now deduplicates files by path and
counts unique rule IDs from all detections (matching scan.go pattern).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Findings in the summary comment table and details section are now
sorted critical > high > medium > low > info using a stable sort
that preserves original order within the same severity level.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace the heading-per-finding layout with a compact table showing
severity, rule, file, line, CWE, and description in columns. Renders
much cleaner on GitHub PR comments.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…gs table

Remove the redundant View Details collapsible section. Add a link column
to the findings table with a clickable emoji linking to the exact file
and line in the PR head commit (blob URL). PR metadata is now fetched
once at the start of postPRComments for both summary links and inline
comments.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Previously the CI command returned a hard error when the project had no
recognized source files, preventing PR summary comments from being
posted. Now it logs a message and continues, so zero-finding summaries
are posted correctly.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Rules metric showed 0 when no findings existed because it counted unique
rule IDs from detections. Now counts actually loaded rules: code analysis
rules from LoadRules plus container rules parsed from the JSON IR.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Files Scanned metric counted all files in the code graph including ones
not in the PR diff. Now uses len(changedFiles) when diff-aware scanning
is active, so only files actually in the PR are counted.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@shivasurya shivasurya added enhancement New feature or request go Pull requests that update go code labels Feb 8, 2026
@shivasurya shivasurya self-assigned this Feb 8, 2026
@safedep

safedep Bot commented Feb 8, 2026 •

Copy link
Copy Markdown

SafeDep Report Summary

Green Malicious Packages Badge Green Vulnerable Packages Badge Green Risky License Badge

No dependency changes detected. Nothing to scan.

This report is generated by SafeDep Github App

@codecov

codecov Bot commented Feb 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.09742% with 111 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.94%. Comparing base (40197de) to head (8b67a1d).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
sast-engine/cmd/ci.go 25.24% 77 Missing ⚠️
sast-engine/cmd/scan.go 35.29% 22 Missing ⚠️
sast-engine/diff/git_provider.go 83.33% 4 Missing and 2 partials ⚠️
sast-engine/github/client.go 97.33% 2 Missing and 2 partials ⚠️
sast-engine/diff/validate.go 85.71% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #509      +/-   ##
==========================================
+ Coverage   81.13%   81.94%   +0.80%     
==========================================
  Files         113      122       +9     
  Lines       13302    13984     +682     
==========================================
+ Hits        10793    11459     +666     
+ Misses       2107     2105       -2     
- Partials      402      420      +18     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

shivasurya and others added 5 commits February 7, 2026 21:52
Move domain logic out of cmd/ into their respective packages:

- cmd/pr_comment.go → github/pr.go: PRCommentOptions, ParseRepo,
  PostPRComments (takes *Client param + ProgressFunc callback)
- cmd/diff_helpers.go → diff/resolve.go: ResolveBaseRef,
  ComputeChangedFiles (drop logger param)
- Inline applyDiffFilter in ci.go and scan.go (4 lines each)
- Add prFlags struct in ci.go for CLI flag storage
- Migrate tests to github/pr_test.go and diff/resolve_test.go
- Move flag registration tests to ci_test.go and scan_test.go

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add TestCICmdValidation (10 subtests) covering all RunE validation
  paths in ci.go: missing rules/project, invalid output format, PR flag
  validation (token, repo, PR number, repo format) for both --pr-comment
  and --pr-inline
- Add TestScanCmdValidation (5 subtests) covering RunE validation paths
  in scan.go: missing rules/project, invalid output format, diff-aware
  without base ref, diff-aware with invalid base ref
- Add TestSetBaseURL for github/client.go
- Add network error tests for all 8 client methods covering doRequest
  failure branches
- Fix prealloc lint in review.go

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add Low (blue) and Info (informational) badges to the severity badge
  row in PR summary comments
- Add info emoji and label support for findings table
- Update severityCounts to include Info field
- Update countBySeverity to count "info" severity findings
- Update status badge condition to include Info count
- Found 1 existing INFO rule: maintainer_deprecated.py (Docker)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@shivasurya
shivasurya merged commit 8fba34f into main Feb 8, 2026
7 checks passed
@shivasurya
shivasurya deleted the shiva/pr-01-github-pr-integ branch February 8, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant