Skip to content

feat(action): SARIF → GitHub code scanning surface (dog-fooded in CI)#48

Merged
PhysShell merged 2 commits into
mainfrom
claude/sarif-code-scanning
Jun 20, 2026
Merged

feat(action): SARIF → GitHub code scanning surface (dog-fooded in CI)#48
PhysShell merged 2 commits into
mainfrom
claude/sarif-code-scanning

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 20, 2026

Copy link
Copy Markdown
Owner

What

Give the composite Action a fourth surface, format: sarif: it writes a SARIF 2.1.0 log to a file and exposes the path as the sarif-file output, so a consumer hands it straight to github/codeql-action/upload-sarif. Code scanning subsumes the github PR-annotation format — it renders inline PR annotations and the Security tab — so this stays a single own-check run, not two. An optional sarif-file input overrides the default $RUNNER_TEMP path.

Consumer wiring is three steps:

permissions:
  contents: read
  security-events: write
steps:
  - uses: actions/checkout@v4
  - uses: PhysShell/Own.NET@main   # pin to a tag/SHA in production
    id: ownnet
    with:
      path: src
      format: sarif
      fail-on-finding: "false"     # let code scanning be the gate, not the step
  - uses: github/codeql-action/upload-sarif@v4
    with:
      sarif_file: ${{ steps.ownnet.outputs.sarif-file }}
      category: own-net

This retires the need for our bespoke output on the consumer surface: code scanning draws both the inline PR annotations and the Security tab natively.

Validated in CI — two levels, no "trust me bro"

  • structure (own-check-surface): a jq contract over a freshly-emitted log — version 2.1.0, the Own.NET driver, and every result carrying a catalogue ruleId + a located file (the shape GitHub's ingest enforces). Read-only, no permissions. Locally cross-checked against 9 real core SARIF outputs (incl. unresolved → OWN001+OWN050 and di → DI001).
  • end-to-end (own-check-codescan): the action format: sarif over the sample tree, then upload-sarif under a scoped security-events: write (the only non-contents:read job). upload-sarif waits for processing and fails the job if GitHub rejects the log — so a green run is live proof GitHub accepts our SARIF. The sample alerts ride a dedicated own-net-samples category. ✅ green on this branch's run (the Security tab is now lit with the sample findings).

Why dog-food here (the deferral reversed)

The earlier sarif-export.md note deferred this as "low-value — the repo's C# is test fixtures." That weighed the findings; it mis-weighed the integration. The repo is public, so code scanning is free, and a live upload is the one thing a local schema check cannot give — proof of acceptance. The note is updated accordingly.

Files

  • action.ymlformat: sarif branch (write SARIF to file, expose sarif-file output; capture the true exit code after writing so the upload can still run); new sarif-file input.
  • .github/workflows/ci.yml — the jq contract step + the own-check-codescan dog-food job (scoped security-events: write).
  • docs/notes/sarif-export.md — deferred → shipped, with the consumer snippet + the public-repo reasoning.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added sarif format output to generate SARIF 2.1.0 logs suitable for GitHub code scanning.
    • Composite action now exports a sarif-file path for direct SARIF upload usage.
  • Tests / CI

    • CI now performs explicit SARIF schema/contract validation (including tool driver, rule references, and artifact/region data) before end-to-end execution.
    • Added a code-scanning ingestion dog-food job that uploads generated SARIF when write-capable permissions are available.
  • Documentation

    • Updated SARIF export notes to describe the shipped upload consumer workflow and revised open items.

Give the composite Action a fourth surface, `format: sarif`: it writes a
SARIF 2.1.0 log to a file and exposes the path as the `sarif-file` output, so
a consumer hands it straight to github/codeql-action/upload-sarif. Code
scanning subsumes the `github` PR-annotation format (it renders inline PR
annotations *and* the Security tab), so this stays a single own-check run.
An optional `sarif-file` input overrides the default $RUNNER_TEMP path. With
fail-on-finding the true exit code is captured *after* the file is written, so
the upload can still run (code scanning is the gate).

Validate the exporter on two levels — no "trust me bro":
  - structure (own-check-surface): a jq contract over a freshly-emitted log —
    version 2.1.0, the Own.NET driver, and every result carrying a catalogue
    ruleId + a located file (the shape GitHub's ingest enforces). Read-only.
  - end-to-end (own-check-codescan): the action `format: sarif` over the sample
    tree, then upload-sarif under a *scoped* security-events:write (the only
    non-contents:read job). upload-sarif waits for processing and fails the job
    if GitHub rejects the log — live proof the SARIF is accepted, and it lights
    up the Security tab on this public repo (the consumer payoff). Samples are
    intentional fixtures, namespaced under the own-net-samples category.

docs/notes/sarif-export.md: flip the deferred code-scanning item to shipped
(the public-repo reasoning that reverses the earlier deferral) + the consumer
wiring snippet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED
@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.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a3dd2d0e-6eb0-472e-9947-5bba555ec037

📥 Commits

Reviewing files that changed from the base of the PR and between 36bedbd and 3a49acb.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • action.yml
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/ci.yml
  • action.yml

📝 Walkthrough

Walkthrough

Adds format: sarif support to the composite action by introducing a sarif-file input/output and reworking the run script to write a SARIF 2.1.0 file and capture exit codes. CI gains a jq-based SARIF structure validation step and a new own-check-codescan job that uploads findings to GitHub code scanning. Documentation is updated to reflect the shipped surface.

Changes

SARIF Export Surface

Layer / File(s) Summary
action.yml SARIF interface and run script
action.yml
Adds sarif-file input (default "") and sarif-file output, updates the format input description to document SARIF 2.1.0 output for code scanning, assigns id: own to the leak-check step, and rewrites the run: script with an explicit sarif branch: resolves the output path, invokes own-check.sh --format sarif, captures the exit code after the file is written, emits the path via GITHUB_OUTPUT, and distinguishes rc >= 2 (hard error) from rc == 1 (findings gated on fail-on-finding). The non-SARIF path invokes the script via a shared check variable.
CI SARIF validation step and codescan upload job
.github/workflows/ci.yml
Adds a jq-driven SARIF conformance step to own-check-surface (asserts single run, SARIF version 2.1.0, tool driver name Own.NET, and per-result ruleId/region presence). Keeps the existing composite action end-to-end step after validation. Introduces a new own-check-codescan job with security-events: write that runs the local action in sarif mode, asserts the sarif-file output is set and non-empty, then uploads to GitHub code scanning via github/codeql-action/upload-sarif@v4 under the own-net-samples category.
SARIF export documentation update
docs/notes/sarif-export.md
Adds a section describing the format: sarif consumer surface with required permissions and a sample workflow snippet. Replaces the prior "deferred upload" rationale with a description of the two CI validation layers (structural jq check + end-to-end upload), and removes the now-resolved "Still open" bullet about deferring code-scanning upload.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller Workflow
    participant Action as Own.NET composite action
    participant Script as own-check.sh
    participant GHOUT as GITHUB_OUTPUT
    participant Upload as codeql-action/upload-sarif

    Caller->>Action: format=sarif, severity=warning
    Action->>Script: own-check.sh --format sarif --output <path>
    Script-->>Action: writes SARIF file, returns rc
    Action->>GHOUT: sarif-file=<path>
    Action-->>Caller: outputs.sarif-file
    Caller->>Caller: assert file non-empty
    Caller->>Upload: sarif_file=<path>, category=own-net-samples
    Upload-->>Caller: SARIF accepted by GitHub code scanning
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PhysShell/Own.NET#10: Establishes the format-driven output wiring and surface tests in action.yml and scripts/own-check.sh that this PR extends with the sarif branch.
  • PhysShell/Own.NET#43: Switches the pipeline to emit SARIF logs and wires downstream consumers, directly enabling the upload surface this PR now validates and ships.

Poem

🐇 Hoppity-hop through the SARIF lanes,
findings now flow through code-scanning chains.
ruleId and region — each result declared,
upload-sarif confirms every detail is shared.
The "deferred" bullet? Gone with a hop!
Own.NET scans proudly — never a stop. 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding SARIF format support to the GitHub Action with dog-fooding validation in CI, which matches the PR's core objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/sarif-code-scanning

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36bedbd738

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread action.yml
cat "$sarif" >&2 || true
exit "$rc"
fi
if [ "$OWN_FAIL_ON_FINDING" = "true" ] && [ "$rc" -eq 1 ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve non-check failures in SARIF mode

When format: sarif is used with the recommended fail-on-finding: false, this wrapper treats every exit status 1 as “findings only” and exits successfully. Failures outside own-check.sh's exit-code contract can also produce 1 here—for example, if the configured sarif-file parent directory does not exist, the shell redirection fails before own-check.sh runs—so consumers can get a successful action with an empty or missing SARIF output, and any later upload either fails elsewhere or is skipped. Check that the SARIF file was actually written, or fail redirection/setup errors separately, before applying the finding gate.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 513-520: The `own-check-codescan` job requests security-events
write permission but runs unconditionally on pull_request events from forks,
where GitHub automatically downgrades permissions to read-only, causing the
upload-sarif step to fail. Add an `if` conditional guard to the
`own-check-codescan` job that prevents execution on fork pull requests by
checking that the event is not a pull_request OR that the pull request head
repository matches the target repository. This will prevent unnecessary failures
for external contributors while allowing the job to run on push events and pull
requests from the same repository.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6c5af319-41c3-41d6-8d92-0aa9d016b607

📥 Commits

Reviewing files that changed from the base of the PR and between a24fecf and 36bedbd.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • action.yml
  • docs/notes/sarif-export.md

Comment thread .github/workflows/ci.yml
…review)

Two review findings:

- Codex (action.yml): in the sarif branch, exit 1 was treated as "findings,
  gated off -> exit 0", but a redirection/setup failure (e.g. a custom
  sarif-file whose parent dir is absent fails the `> "$sarif"` redirection
  before own-check.sh runs) also exits 1 — so the action could "succeed" with
  no SARIF. Add a non-empty-file guard below the hard-error tier: a missing or
  empty log with rc<2 is surfaced as an error, never gated as a finding. (Also
  make the byte-count echo tolerate an absent file under set -e.) Verified the
  five paths locally: clean/findings(gate off|on)/hard-error/missing-parent-dir.

- CodeRabbit (ci.yml): own-check-codescan requests security-events:write but ran
  on fork PRs too, where GitHub downgrades the token to read-only -> upload-sarif
  fails -> persistent red CI for external contributors. Guard the job to
  same-repo events (push or non-fork PR) with the canonical
  `head.repo.full_name == github.repository` if-condition.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED
@PhysShell PhysShell merged commit 882a3a3 into main Jun 20, 2026
20 checks passed
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