Skip to content

Add SARIF and GitHub annotation output, and a GitHub Action - #5

Merged
devblac merged 2 commits into
mainfrom
feat/sarif-action
Oct 24, 2026
Merged

devblac merged 2 commits into
mainfrom
feat/sarif-action

Conversation

@devblac

@devblac devblac commented Oct 17, 2026

Copy link
Copy Markdown
Owner

Stacked on #4 (which is stacked on #3). Retarget to main once those merge;
the new Action workflow and release-check only run on PRs against main.

Makes findings show up where reviewers already look: on the pull request.

Output formats

  • --format text|json|sarif|github; --json stays as a shorthand.
  • sarif: SARIF 2.1.0 for GitHub code scanning (Security tab, PR alerts),
    with full rule metadata. Exit codes are unchanged.
  • github: workflow-command annotations on the PR diff. Code scanning needs
    GitHub Advanced Security on private repos; annotations work everywhere, so they
    are the action's default.

GitHub Action

- uses: devblac/docker-lint@v0.1.0
  with:
    dockerfile: Dockerfile
    upload-sarif: true   # optional; needs security-events: write
  • Installs the release binary for the runner, verified against
    checksums.txt
    ; version: source builds the checkout (used by its own tests).
  • Writes and uploads SARIF even when the lint fails, then fails with the original
    exit code. An unparseable Dockerfile yields no report instead of an empty one.
  • Inputs reach scripts only through env, never ${{ }} interpolation,
    so crafted inputs cannot inject commands.
  • New Action workflow runs it on Linux, macOS and Windows for clean, failing
    and unparseable Dockerfiles.

Verification

  • SARIF for all 72 analyzable fixtures (+ stdin, quiet, absolute paths) validates
    against the official SARIF 2.1.0 JSON schema.
  • The action's scripts were run locally through a harness. The release-download
    path, which CI can't reach before a release exists, was run against the
    GoReleaser snapshot with a stubbed gh: tag resolution, checksum verification,
    zip/tar.gz extraction, and failure on a tampered checksum or missing asset.

Note

PR #3's CI warns that actions/checkout@v4 and actions/setup-go@v5 target the
deprecated Node 20. New files here use v7/v7 (Node 24); bumping the existing
workflows is left for a separate change.

🤖 Generated with Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T20:24:45.322473Z 6fa2ae0 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 6fa2ae0acc

ℹ️ 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 Outdated

# Record the exit code instead of failing here, so the SARIF report is
# still written and uploaded when the lint finds errors.
docker-lint "${args[@]}" --format "$FORMAT" "$DOCKERFILE"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Capture nonzero lint exits before errexit aborts

In the Lint Dockerfile step, GitHub invokes shell: bash with errexit enabled, and set -uo pipefail does not disable -e. Whenever docker-lint returns 1 or 2—the exact cases this action is meant to report—the shell exits here before recording exit-code, generating or uploading SARIF, or reaching Report result; this also makes the failing and fatal cases in .github/workflows/action.yml fail their assertions. Run the command in an if/else or explicitly suspend errexit while capturing its status.

Useful? React with 👍 / 👎.

@devblac
devblac added this pull request to stack #7 October 17, 2026 22:25
@devblac
devblac force-pushed the feat/sarif-action branch 2 times, most recently from 93d11e7 to 9753750 Compare October 18, 2026 03:43
Base automatically changed from feat/release-pipeline to main October 18, 2026 05:17
Make findings show up where reviewers already look: on the pull request.

Output formats:
- --format selects text, json, sarif or github; --json stays as a
  shorthand for --format json and conflicts with any other format.
- sarif writes a SARIF 2.1.0 log for GitHub code scanning. It carries
  every rule's metadata (PascalCase name, descriptions, default level,
  a category tag from the ID's hundreds digit) and maps severities to
  error/warning/note. Relative paths stay relative, which code scanning
  resolves against the repository root; absolute ones become file://.
  The exit code is unchanged so CI still fails while the report uploads.
- github writes workflow commands that GitHub renders as annotations on
  the diff. Code scanning needs GitHub Advanced Security on private
  repositories; annotations work everywhere, so they are the action's
  default. Values are escaped exactly as @actions/core does.
The formatter package takes rule metadata as input instead of importing
the rules package, so it stays independent of it.

GitHub Action (action.yml, composite):
- Installs a release binary for the runner's OS and architecture with
  gh, verifies it against checksums.txt and puts it on PATH. "source"
  builds the checkout instead, so the action is testable before any
  release exists.
- Records docker-lint's exit code instead of failing at once, writes the
  SARIF report, optionally uploads it (codeql-action/upload-sarif@v4),
  then fails with the original code. A Dockerfile that cannot be parsed
  yields no report rather than an empty one an upload would reject.
- Inputs reach every script through env, never ${{ }} interpolation, so
  a crafted input cannot inject shell commands.
- .github/workflows/action.yml runs the action on Linux, macOS and
  Windows for a clean, a failing and an unparseable Dockerfile.

Verification:
- SARIF for all 72 analyzable fixtures, plus stdin, quiet and absolute
  path cases, validates against the official SARIF 2.1.0 JSON schema.
- The action's scripts were run locally through a harness for the same
  scenarios as the workflow. The release-download path, which CI cannot
  exercise before a release exists, was run against the GoReleaser
  snapshot with a stubbed gh: it resolves the tag, verifies and unpacks
  zip and tar.gz archives, and fails on a tampered checksum or a
  missing asset.
- New files use the current action majors (checkout v7, setup-go v7,
  codeql-action v4), which run on Node 24.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GitHub runs composite bash steps with -e, which "set -uo pipefail" does
not undo, so a lint failure ended the step before the exit code and the
SARIF report were recorded. Capture the exit code with "|| code=$?"
instead, and expand the optional arguments safely for bash 3.2 on macOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@devblac
devblac merged commit 4945030 into main Oct 24, 2026
5 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.

1 participant