Repository navigation
Expand file tree
/
Copy pathaction.yml
More file actions
171 lines (168 loc) · 6.18 KB
/
Copy pathaction.yml
File metadata and controls
171 lines (168 loc) · 6.18 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
# Action GitHub réutilisable :
#
# - uses: chla28/CheckScript@v0.24.1
# with:
# paths: scripts .github
# fail-under: '7'
#
# check-script est compilé depuis les sources de l'action (Dart), ShellCheck
# et shfmt installés sur le runner ; les problèmes deviennent des annotations
# (visibles sur les lignes des pull requests), un résumé Markdown est ajouté
# au job et un fichier SARIF est produit pour GitHub Code Scanning.
name: CheckScript
description: >-
Scores shell and Python scripts out of 10 (and the shell in workflows,
Dockerfiles, Makefiles): security, robustness, maintainability,
portability, performance; annotations, summary and SARIF.
author: Christophe Lafaille
branding:
icon: check-circle
color: green
inputs:
paths:
description: Scripts or folders to analyze, separated by spaces.
default: '.'
fail-under:
description: >-
Failure threshold (e.g. 7, or security=8,global=6); empty: never fail
on the score.
default: ''
changed-since:
description: >-
Git reference: only analyze scripts modified since then (e.g.
origin/main; checkout with fetch-depth: 0); empty: analyze everything.
default: ''
args:
description: Additional check-script options (e.g. --profile strict).
default: ''
lang:
description: Message language (fr or en).
default: 'fr'
annotations:
description: Annotate the affected lines (true / false).
default: 'true'
summary:
description: Add the Markdown report to the job summary (true / false).
default: 'true'
sarif:
description: >-
SARIF file to produce (empty: none), to upload with
github/codeql-action/upload-sarif.
default: 'check-script.sarif'
install-tools:
description: Install ShellCheck and shfmt with apt (true / false).
default: 'true'
outputs:
score:
description: Average score of the analyzed scripts (out of 10).
value: ${{ steps.run.outputs.score }}
grade:
description: Grade of the lowest score (A to E).
value: ${{ steps.run.outputs.grade }}
scripts:
description: Number of analyzed scripts.
value: ${{ steps.run.outputs.scripts }}
sarif:
description: Path of the SARIF file (empty if none).
value: ${{ steps.run.outputs.sarif }}
runs:
using: composite
steps:
# SDK Dart installé ici plutôt que par dart-lang/setup-dart : dans une
# action composite, celle-ci cherche son fichier dart-analyzer.json dans
# le dossier de l'action appelante (erreur « add-matcher »).
- name: Dart SDK
shell: bash
run: | # zizmor: ignore[github-env] chemin fixe ajouté à GITHUB_PATH
set -euo pipefail
if command -v dart >/dev/null; then
exit 0
fi
case "$RUNNER_OS" in
Linux) os=linux ;;
macOS) os=macos ;;
*) echo "::error::CheckScript: unsupported operating system ($RUNNER_OS)"; exit 1 ;;
esac
case "$(uname -m)" in
x86_64 | amd64) arch=x64 ;;
aarch64 | arm64) arch=arm64 ;;
*) echo "::error::CheckScript: unsupported architecture"; exit 1 ;;
esac
base=https://storage.googleapis.com/dart-archive/channels/stable/release
version=$(curl -fsSL "$base/latest/VERSION" | jq -r .version)
zip="dartsdk-$os-$arch-release.zip"
cd "$RUNNER_TEMP"
curl -fsSLO "$base/$version/sdk/$zip"
curl -fsSLO "$base/$version/sdk/$zip.sha256sum"
if command -v sha256sum >/dev/null; then
sha256sum -c "$zip.sha256sum"
else
shasum -a 256 -c "$zip.sha256sum"
fi
unzip -q "$zip"
echo "$RUNNER_TEMP/dart-sdk/bin" >>"$GITHUB_PATH"
echo "Dart $version"
- name: Build check-script
shell: bash
working-directory: ${{ github.action_path }}
run: |
dart pub get
dart compile exe bin/check_script.dart -o "$RUNNER_TEMP/check-script"
- name: Analysis tools
if: inputs.install-tools == 'true'
shell: bash
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq shellcheck shfmt >/dev/null ||
echo "::warning::ShellCheck / shfmt not installed: built-in rules only."
- id: run
name: Analyze
shell: bash
# Les paramètres passent par l'environnement, jamais interpolés dans le
# script (injection).
env:
CS_PATHS: ${{ inputs.paths }}
CS_FAIL_UNDER: ${{ inputs.fail-under }}
CS_SINCE: ${{ inputs.changed-since }}
CS_ARGS: ${{ inputs.args }}
CS_LANG: ${{ inputs.lang }}
CS_ANNOTATIONS: ${{ inputs.annotations }}
CS_SUMMARY: ${{ inputs.summary }}
CS_SARIF: ${{ inputs.sarif }}
run: |
set -uo pipefail
exe="$RUNNER_TEMP/check-script"
json="$RUNNER_TEMP/check-script.json"
md="$RUNNER_TEMP/check-script.md"
read -r -a paths <<<"$CS_PATHS"
read -r -a extra <<<"$CS_ARGS"
# --recursive : un dossier est parcouru en entier (comportement attendu en CI).
args=(--lang "$CS_LANG" --no-cache --recursive -o "$json" -o "$md")
[ -n "$CS_SARIF" ] && args+=(-o "$CS_SARIF")
[ -n "$CS_FAIL_UNDER" ] && args+=(--fail-under "$CS_FAIL_UNDER")
[ -n "$CS_SINCE" ] && args+=(--changed-since "$CS_SINCE")
if [ "$CS_ANNOTATIONS" = true ]; then
args+=(--format github)
else
args+=(--quiet)
fi
"$exe" "${args[@]}" "${extra[@]}" "${paths[@]}"
code=$?
if [ -s "$json" ]; then
jq -r '"scripts=\(.reports | length)",
"score=\(if (.reports | length) > 0
then ([.reports[].global.score] | add / length * 10 | round / 10)
else "" end)",
"grade=\([.reports[].global.grade] | max // "")"' \
"$json" >>"$GITHUB_OUTPUT"
jq -r '.reports[] | "\(.global.grade) \(.global.score) \(.file)"' "$json"
else
echo "scripts=0" >>"$GITHUB_OUTPUT"
fi
if [ -n "$CS_SARIF" ] && [ -s "$CS_SARIF" ]; then
echo "sarif=$CS_SARIF" >>"$GITHUB_OUTPUT"
fi
if [ "$CS_SUMMARY" = true ] && [ -s "$md" ]; then
cat "$md" >>"$GITHUB_STEP_SUMMARY"
fi
exit "$code"