feat: rewrite as a node20 TypeScript action with native PR surfaces#1
Merged
Conversation
aa27b22 to
63f3183
Compare
Full from-scratch rewrite from the v1 bash composite action. Surfaces: - Inline PR annotations + GitHub Security tab (SARIF via the Code Scanning API) - Sticky PR summary comment (update-in-place by marker) - Status-check gating (risk-score / severity thresholds; fail-closed) - Console panel + Step Summary (readiness, severity breakdown, headroom ladder) Review fixes folded in: - Single scan via engine --json-out/--sarif-out (two-scan fallback for old engines) - sha256-verified binary download (v1 ran it unverified) - Gates fail closed on a broken/empty scan (v1 failed open to a clean 100) - Inputs read via the toolkit, never spliced into a run: block via GitHub Actions expressions Headroom ladder is sourced from the engine's projected_scores (single source of truth) instead of an in-action jq reimplementation. upload-sarif and comment-on-pr default on (need security-events: write / pull-requests: write; degrade gracefully). Backward-compatible: all existing inputs and the eight existing outputs preserved. Bundled to dist/ with ncc (committed); 53 jest unit tests; build-check workflow guards dist/ freshness.
63f3183 to
734359b
Compare
…ne stderr
The selftest floated on `latest` engine + latest rules, so it broke when
trustabl-rules added an mcp/ pack the released engine v0.1.2 cannot load
("unknown category mcp"). Pin every selftest job to v0.1.2 + the `pre-mcp` rules
tag (a known-compatible pair) so CI tests the action, not upstream drift. The
remote-target job uses continue-on-error plus artifact/output assertions, since
that external target legitimately gates on findings (exit 1). Temporary until an
engine release with mcp-category support is `latest` (trustabl/trustabl#12).
runner.ts now includes the engine's exit code and a stderr tail in the
"produced no JSON output" error, so a failing scan is debuggable instead of opaque.
The engine marshals an empty findings slice as JSON null (Go nil-slice behavior), so a clean scan emits findings: null. parseScanResult threw "missing findings array" on that, failing the action on any repo with no findings (the selftest's scan-self-empty / scan-pr-surfaces jobs). Treat null/absent findings as an empty array; still reject non-object JSON.
Trustabl scan
Readiness now 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 Findings by severity
✅ Passed scanning |
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.
Full from-scratch rewrite of the v1 bash composite action as a node20 TypeScript action, making the action as seamless as possible.
Four surfaces
uses:codeql-action). Findings show on the changed lines and in the Security tab.Review fixes folded in
--json-out/--sarif-out(two-scan fallback for older engines).${{ }}injection — inputs read via the toolkit.projected_scores(single source of truth), not an in-action jq reimplementation (which was silently broken).Compatibility
sarif-uploaded).upload-sarifandcomment-on-prdefault on (needsecurity-events: write/pull-requests: write; degrade gracefully — never fail solely because a surface is unavailable). New inputs:comment-on-pr,annotations,max-annotations,github-token.Build / test
dist/with ncc (committed).npm run allgreen: typecheck + 53 jest unit tests + build.build-check.ymlfails PRs with a staledist/;selftest.ymlexercises remote-target, self-empty, and PR surfaces.Depends on / follow-ups
--json-out/--sarif-out,projected_scores). Until an engine release ships those aslatest, the action auto-uses the two-scan fallback and hides the ladder.MIN_ENGINE_VERSIONinsrc/install.ts(currently a no-warn0.0.0placeholder) and cutv0.2.0+ the movingv0tag.