-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaction.yml
More file actions
199 lines (188 loc) · 7.26 KB
/
Copy pathaction.yml
File metadata and controls
199 lines (188 loc) · 7.26 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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
name: 'Unicode Safety Check'
description: 'Detect adversarial Unicode in PRs: bidi attacks, invisible chars, homoglyphs, confusable collisions, and more.'
author: 'David Condrey'
branding:
icon: 'shield'
color: 'blue'
inputs:
scan-mode:
description: '"changed" (PR/push diff only) or "all" (entire repo).'
required: false
default: 'changed'
policy-file:
description: 'Path to a policy file (.yml, .yaml, .json). Omit for strict defaults.'
required: false
default: ''
exclude-patterns:
description: 'Newline-separated path patterns to exclude from scanning.'
required: false
default: ''
fail-on-warn:
description: 'Treat medium/low severity findings as errors.'
required: false
default: 'false'
disable-annotations:
description: 'Skip inline PR annotations.'
required: false
default: 'false'
sarif-file:
description: 'Path to write SARIF output for Code Scanning.'
required: false
default: ''
version:
description: 'Version of the unicode-safety-check binary to download.'
required: false
default: '3.0.0'
outputs:
findings:
description: 'Total number of findings.'
value: ${{ steps.scan.outputs.findings }}
files-scanned:
description: 'Number of files scanned.'
value: ${{ steps.scan.outputs.files_scanned }}
critical:
description: 'Number of critical findings.'
value: ${{ steps.scan.outputs.critical }}
high:
description: 'Number of high findings.'
value: ${{ steps.scan.outputs.high }}
sarif-file:
description: 'Path to SARIF file (if generated).'
value: ${{ steps.scan.outputs.sarif_file }}
runs:
using: 'composite'
steps:
- name: Determine scan parameters
id: params
shell: bash
env:
INPUT_SCAN_MODE: ${{ inputs.scan-mode }}
EVENT_NAME: ${{ github.event_name }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PUSH_BEFORE_SHA: ${{ github.event.before }}
run: |
if [ "$INPUT_SCAN_MODE" = "all" ]; then
echo "scan_mode=all" >> "$GITHUB_OUTPUT"
else
if [ "$EVENT_NAME" = "pull_request" ]; then
BASE_SHA="$PR_BASE_SHA"
else
BASE_SHA="$PUSH_BEFORE_SHA"
if [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then
BASE_SHA="4b825dc642cb6eb9a060e54bf8d69288fbee4904"
fi
fi
echo "base_sha=$BASE_SHA" >> "$GITHUB_OUTPUT"
echo "scan_mode=changed" >> "$GITHUB_OUTPUT"
if ! git diff --name-only --diff-filter=AMR "$BASE_SHA" HEAD \
> "$RUNNER_TEMP/unicode_check_files.txt" 2>&1; then
echo "::warning::git diff failed for base SHA $BASE_SHA; falling back to full scan."
echo "scan_mode=all" >> "$GITHUB_OUTPUT"
else
echo "file_list=$RUNNER_TEMP/unicode_check_files.txt" >> "$GITHUB_OUTPUT"
count=$(wc -l < "$RUNNER_TEMP/unicode_check_files.txt" 2>/dev/null | tr -d ' ')
echo "Found $count changed file(s) to scan."
fi
fi
- name: Download binary
shell: bash
env:
INPUT_VERSION: ${{ inputs.version }}
ACTION_PATH: ${{ github.action_path }}
run: |
VERSION="$INPUT_VERSION"
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then
echo "::error::Invalid version format: $VERSION (expected semver like 3.0.0)"
exit 1
fi
case "$RUNNER_OS-$RUNNER_ARCH" in
Linux-X64) TARGET="x86_64-unknown-linux-gnu" ;;
Linux-ARM64) TARGET="aarch64-unknown-linux-gnu" ;;
macOS-X64) TARGET="x86_64-apple-darwin" ;;
macOS-ARM64) TARGET="aarch64-apple-darwin" ;;
*)
echo "::error::Unsupported platform: $RUNNER_OS-$RUNNER_ARCH (Windows is not supported)"
exit 1
;;
esac
DOWNLOADED=false
if [ -n "$TARGET" ]; then
TARBALL="unicode-safety-check-${TARGET}.tar.gz"
BASE_URL="https://github.com/dcondrey/unicode-safety-check/releases/download/v${VERSION}"
URL="${BASE_URL}/${TARBALL}"
echo "Downloading $URL"
if curl -fsSL "$URL" -o "$RUNNER_TEMP/$TARBALL"; then
ACTUAL_SHA=$(shasum -a 256 "$RUNNER_TEMP/$TARBALL" | awk '{print $1}')
echo "Tarball SHA256: $ACTUAL_SHA"
SUMS_URL="${BASE_URL}/SHA256SUMS"
if curl -fsSL "$SUMS_URL" -o "$RUNNER_TEMP/SHA256SUMS"; then
EXPECTED_SHA=$(grep "$TARBALL" "$RUNNER_TEMP/SHA256SUMS" | awk '{print $1}')
if [ -z "$EXPECTED_SHA" ]; then
echo "::error::No checksum entry for $TARBALL in SHA256SUMS"
exit 1
elif [ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]; then
echo "::error::Checksum mismatch for $TARBALL (expected $EXPECTED_SHA, got $ACTUAL_SHA)"
exit 1
else
echo "Checksum verified."
fi
else
echo "::warning::SHA256SUMS not available for v${VERSION}; skipping checksum verification."
fi
tar -xzf "$RUNNER_TEMP/$TARBALL" -C "$RUNNER_TEMP"
chmod +x "$RUNNER_TEMP/unicode-safety-check"
DOWNLOADED=true
else
echo "::warning::Binary download failed, trying fallback."
fi
fi
if [ "$DOWNLOADED" != "true" ]; then
if [ -x "$ACTION_PATH/rust/target/release/unicode-safety-check" ]; then
cp "$ACTION_PATH/rust/target/release/unicode-safety-check" "$RUNNER_TEMP/unicode-safety-check"
echo "Using pre-built binary from action directory."
else
echo "::error::No binary available. Download failed and no local build found."
exit 1
fi
fi
- name: Run Unicode safety scan
id: scan
shell: bash
env:
INPUT_SCAN_MODE: ${{ inputs.scan-mode }}
INPUT_POLICY_FILE: ${{ inputs.policy-file }}
INPUT_EXCLUDE_PATTERNS: ${{ inputs.exclude-patterns }}
INPUT_FAIL_ON_WARN: ${{ inputs.fail-on-warn }}
INPUT_DISABLE_ANNOTATIONS: ${{ inputs.disable-annotations }}
INPUT_SARIF_FILE: ${{ inputs.sarif-file }}
INPUT_BASE_SHA: ${{ steps.params.outputs.base_sha }}
INPUT_FILE_LIST: ${{ steps.params.outputs.file_list }}
run: |
ARGS=()
if [ "$INPUT_SCAN_MODE" = "all" ]; then
ARGS+=(--all)
elif [ -f "$INPUT_FILE_LIST" ]; then
ARGS+=(--file-list "$INPUT_FILE_LIST")
fi
if [ -n "$INPUT_BASE_SHA" ]; then
ARGS+=(--base-sha "$INPUT_BASE_SHA")
fi
if [ -n "$INPUT_POLICY_FILE" ]; then
ARGS+=(--policy "$INPUT_POLICY_FILE")
fi
if [ -n "$INPUT_EXCLUDE_PATTERNS" ]; then
while IFS= read -r pat; do
[ -n "$pat" ] && ARGS+=(--exclude "$pat")
done <<< "$INPUT_EXCLUDE_PATTERNS"
fi
if [ "$INPUT_FAIL_ON_WARN" = "true" ]; then
ARGS+=(--fail-on-warn)
fi
if [ "$INPUT_DISABLE_ANNOTATIONS" = "true" ]; then
ARGS+=(--no-annotations)
fi
if [ -n "$INPUT_SARIF_FILE" ]; then
ARGS+=(--sarif-file "$INPUT_SARIF_FILE")
fi
ARGS+=(--no-color)
"$RUNNER_TEMP/unicode-safety-check" "${ARGS[@]}"