Skip to content

feat(cli): add sarif output format#56

Merged
nozaq merged 10 commits into
mainfrom
claude/sarif-output-format-eakx6l
Jul 25, 2026
Merged

feat(cli): add sarif output format#56
nozaq merged 10 commits into
mainfrom
claude/sarif-output-format-eakx6l

Conversation

@nozaq

@nozaq nozaq commented Jul 24, 2026

Copy link
Copy Markdown
Member

Add -format=sarif, writing a SARIF 2.1.0 log for upload to GitHub Code
Scanning. The run's rule catalog lists the rules referenced by results
with their descriptions and category tags, and issue positions map to
%SRCROOT%-relative physical locations.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby

claude and others added 10 commits July 24, 2026 02:32
Add -format=sarif, writing a SARIF 2.1.0 log for upload to GitHub Code
Scanning. The run's rule catalog lists the rules referenced by results
with their descriptions and category tags, and issue positions map to
%SRCROOT%-relative physical locations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby
Build an expected SARIF log and compare it in one cmp.Diff instead of
asserting each field individually. Named struct types decode only the
structural subset so message texts and rule descriptions stay owned by
the rule and format package tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lint results are now named relative to the working directory, or
absolutely for a file outside it. A SARIF artifact location may only
carry a uriBaseId when its uri is a relative reference, so an absolute
path is written as a file URI with no base id; resolving it against the
source root would name a different file.

Paths are percent-encoded, since a SARIF artifact location is a URI
rather than a filesystem path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby
…l' into claude/sarif-output-format-eakx6l

# Conflicts:
#	cmd/decolint/main_test.go
…g directory

The choice between a relative path and an absolute one is made when the
lint target is resolved, not in the format package, so exercise it end to
end: a target outside the working directory must reach the SARIF log as
an absolute file URI carrying no base id.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby
A relative artifact location referenced a base id that the log never
declared, which is invalid SARIF. Declare it in originalUriBaseIds
without a URI: decolint does not know where its working directory sits
in the analyzed project, so the value is left to the consumer, which
resolves it to the root of the checkout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby
A base id is only useful to a consumer that can resolve it, and nothing
in the log gave %SRCROOT% a value: Code Scanning does not resolve base
ids at all, and a viewer that tries is left with an unresolvable
reference. Report a relative path on its own, as golangci-lint and
oxlint do, and let the consumer resolve it against the root of the
analyzed project.

Also write a UNC path's host as the file URI's authority rather than
folding it into the path, and name the sarif format in the config file
template written by -init.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby
Everything about the sarif format has been checked offline so far, which
cannot show that GitHub accepts the log or that the relative paths it
reports resolve to files in the repository.

Upload a real log for the violations fixture, assert the analysis was
ingested and its alerts landed on the linted file, then delete the
analysis and fail if anything is left behind. The upload gets a category
of its own so it forms an independent analysis set, and the cleanup
deletes only that category.

Manual only: a pull request from a fork never receives
security-events: write.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby
Nothing triggers this workflow automatically, so a change that breaks it
is only discovered the next time someone runs it by hand. Run it on a
pull request that touches the workflow itself.

An upload picks the ref its analysis lands on, and for a pull request
that is a refs/pull ref rather than GITHUB_REF, so read it back from the
analysis instead of assuming it, and sweep analyses by category across
every ref. A pull request from a fork is skipped: its token is read-only
however this workflow declares its permissions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUTAwRxUmzDnAPFyR3ESby
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@nozaq
nozaq merged commit 59a0e29 into main Jul 25, 2026
10 checks passed
@nozaq
nozaq deleted the claude/sarif-output-format-eakx6l branch July 25, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants