-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaction.yml
More file actions
150 lines (124 loc) · 4.76 KB
/
Copy pathaction.yml
File metadata and controls
150 lines (124 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
name: 'Trace Check'
description: 'Static analyzer for AI-generated code. Detects 24 LLM-specific failure patterns.'
author: 'Lattice Node'
branding:
icon: 'eye'
color: 'red'
inputs:
path:
description: 'Directory or file to scan, relative to repo root.'
required: false
default: '.'
severity-threshold:
description: 'Minimum severity to report. One of: low, medium, high, critical.'
required: false
default: 'low'
fail-on-detection:
description: 'If "true", fail the action when detections at or above severity-threshold are found.'
required: false
default: 'false'
comment-on-pr:
description: 'Post a summary comment on the PR. Has no effect outside pull_request events.'
required: false
default: 'true'
upload-sarif:
description: 'Upload SARIF to GitHub Code Scanning. Requires security-events: write permission.'
required: false
default: 'true'
trace-version:
description: 'Trace-core npm version to use. Default "latest" pins to the most recent published version.'
required: false
default: 'latest'
github-token:
description: 'Token used for PR comments and SARIF upload. Defaults to GITHUB_TOKEN.'
required: false
default: ${{ github.token }}
outputs:
detection-count:
description: 'Total number of detections at or above severity-threshold.'
value: ${{ steps.compute.outputs.detection-count }}
critical-count:
description: 'Number of critical detections.'
value: ${{ steps.compute.outputs.critical-count }}
high-count:
description: 'Number of high detections.'
value: ${{ steps.compute.outputs.high-count }}
medium-count:
description: 'Number of medium detections.'
value: ${{ steps.compute.outputs.medium-count }}
low-count:
description: 'Number of low detections.'
value: ${{ steps.compute.outputs.low-count }}
grade:
description: 'Letter grade (A/B/C/D/F) based on detection count and severity mix.'
value: ${{ steps.compute.outputs.grade }}
summary-markdown:
description: 'Human-readable markdown summary of the scan.'
value: ${{ steps.compute.outputs.summary-markdown }}
sarif-path:
description: 'Path to the generated SARIF file (relative to workspace).'
value: ${{ steps.run.outputs.sarif-path }}
json-path:
description: 'Path to the raw Trace JSON output (relative to workspace).'
value: ${{ steps.run.outputs.json-path }}
runs:
using: 'composite'
steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Run Trace
id: run
shell: bash
env:
TRACE_PATH: ${{ inputs.path }}
TRACE_THRESHOLD: ${{ inputs.severity-threshold }}
TRACE_VERSION: ${{ inputs.trace-version }}
run: bash ${{ github.action_path }}/scripts/run-trace.sh
- name: Convert JSON to SARIF
id: sarif
shell: bash
env:
TRACE_JSON: ${{ steps.run.outputs.json-path }}
SARIF_OUT: ${{ steps.run.outputs.sarif-path }}
run: node ${{ github.action_path }}/scripts/json-to-sarif.mjs
- name: Compute outputs (grade, counts, summary)
id: compute
shell: bash
env:
TRACE_JSON: ${{ steps.run.outputs.json-path }}
TRACE_THRESHOLD: ${{ inputs.severity-threshold }}
TRACE_PATH: ${{ inputs.path }}
run: node ${{ github.action_path }}/scripts/compute-outputs.mjs
- name: Upload SARIF to Code Scanning
if: ${{ inputs.upload-sarif == 'true' && steps.run.outputs.json-path != '' }}
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ${{ steps.run.outputs.sarif-path }}
category: trace
- name: Comment on PR
if: ${{ inputs.comment-on-pr == 'true' && github.event_name == 'pull_request' }}
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
SUMMARY: ${{ steps.compute.outputs.summary-markdown }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
run: |
MARKER='<!-- trace-action-comment -->'
BODY="$MARKER
$SUMMARY"
EXISTING_ID=$(gh api "/repos/$REPO/issues/$PR_NUMBER/comments" \
--jq ".[] | select(.body | contains(\"$MARKER\")) | .id" | head -1)
if [ -n "$EXISTING_ID" ]; then
gh api -X PATCH "/repos/$REPO/issues/comments/$EXISTING_ID" -f body="$BODY"
else
gh api -X POST "/repos/$REPO/issues/$PR_NUMBER/comments" -f body="$BODY"
fi
- name: Fail if requested
if: ${{ inputs.fail-on-detection == 'true' && steps.compute.outputs.detection-count != '0' }}
shell: bash
run: |
echo "::error::Trace found ${{ steps.compute.outputs.detection-count }} detection(s) at or above ${{ inputs.severity-threshold }} severity."
exit 1