🐛 fix(ci): la guardia Dockerfile dice quando non riesce a leggere le ARG

- l'analisi delle ARG diventa la funzione arg_scope, e all'avvio gira su
  un Dockerfile di prova con una ARG fuori scope nota: se l'awk del runner
  non la riconosce, un ::warning lo dice, il controllo delle ARG salta e
  quello del registry resta, invece di dichiarare in regola ciò che non ha
  potuto leggere
- regex portabile: [$][{]? al posto di \$\{?, che gawk --posix segnalava
  come escape sconosciuto
- collaudo su gawk e gawk --posix (Dockerfile sintetico, pzeta-king prima
  della correzione, vue-pzportal, node-xmlvalidation) e con un awk rotto;
  stesso step, identico, nelle due varianti quality-gates

Fixes #12 @25m
refs PZeta_Touch/flux-repo#133
This commit is contained in:
LucaZanni
2026-09-11 21:38:14 +02:00
parent 9b5159d89e
commit 715860c357
2 changed files with 182 additions and 138 deletions
+36 -14
View File
@@ -78,22 +78,13 @@ jobs:
exit 0
fi
findings=""
for f in $files; do
# (a) registry: npm confronta l'URL del lockfile come stringa, e i lockfile
# risolvono tutti su PZeta_Touch.
reg=$(grep -nE 'packages/(pzeta_touch|pzeta)/' "$f" 2>/dev/null | cut -d: -f1 | tr '\n' ' ' | sed 's/ *$//')
if [ -n "$reg" ]; then
findings="${findings}${f} ${reg%% *} registry $(echo "$reg" | sed 's/ /, /g') -
"
fi
# (b) ARG fuori scope: una ARG vale nello stage che la dichiara e in
# quelli che ne derivano (FROM <stage>), come le ENV; quelle dichiarate
# prima del primo FROM valgono solo nelle righe FROM. Verificato sul
# log di BuildKit di nuxt-vue-components-docs v1.0.13: `FROM base AS
# deps` vede la NPM_VERSION dichiarata in `base`.
args=$(${AWK:-awk} '
arg_scope() {
${AWK:-awk} '
function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s }
# Nomi dichiarati da ARG/ENV: "A", "A=1", "A=1 B=2", "A valore".
function declared(rest, out, n, i, t) {
@@ -124,8 +115,8 @@ jobs:
if (stage == "") return
if (kw == "ARG") { declared(rest, d); for (k in d) { scope[k] = 1; varof[stage, k] = 1 }; return }
s = rest
while (match(s, /\$\{?[A-Za-z_][A-Za-z0-9_]*/)) {
v = substr(s, RSTART, RLENGTH); sub(/^\$\{?/, "", v)
while (match(s, /[$][{]?[A-Za-z_][A-Za-z0-9_]*/)) {
v = substr(s, RSTART, RLENGTH); sub(/^[$][{]?/, "", v)
s = substr(s, RSTART + RLENGTH)
if ((v in allargs) && !(v in scope) && !(v in predefined) && !((ln, v) in seen)) {
seen[ln, v] = 1
@@ -155,7 +146,34 @@ jobs:
buf = buf line
flush()
}
' "$f" "$f" 2>/dev/null)
' "$1" "$1"
}
# Caso di prova: se l'awk di questo runner non riconosce una ARG fuori
# scope nota, il controllo (b) non e' affidabile e lo si dice, invece di
# dichiarare in regola un Dockerfile che non si e' potuto leggere.
argcheck=1
prova=$(mktemp)
printf 'ARG X=1\nFROM scratch AS a\nRUN echo ${X}\n' > "$prova"
if [ "$(arg_scope "$prova" 2>/dev/null | cut -f2)" != "X" ]; then
argcheck=0
echo "::warning::Guardia Dockerfile: l'analisi delle ARG non funziona con l'awk di questo runner ($(${AWK:-awk} -W version 2>&1 | head -1)). Il controllo (b) e' saltato, il (a) resta."
fi
rm -f "$prova"
findings=""
for f in $files; do
# (a) registry: npm confronta l'URL del lockfile come stringa, e i lockfile
# risolvono tutti su PZeta_Touch.
reg=$(grep -nE 'packages/(pzeta_touch|pzeta)/' "$f" 2>/dev/null | cut -d: -f1 | tr '\n' ' ' | sed 's/ *$//')
if [ -n "$reg" ]; then
findings="${findings}${f} ${reg%% *} registry $(echo "$reg" | sed 's/ /, /g') -
"
fi
# (b) ARG fuori scope, con arg_scope definita sopra.
args=""
[ "$argcheck" = "1" ] && args=$(arg_scope "$f" 2>/dev/null)
while IFS=' ' read -r n v st; do
[ -n "$n" ] || continue
findings="${findings}${f} ${n} arg ${v} ${st}
@@ -166,7 +184,11 @@ jobs:
done
if [ -z "$findings" ]; then
if [ "$argcheck" = "1" ]; then
echo "Dockerfile: registry @pzeta e ARG per stage in regola."
else
echo "Dockerfile: registry @pzeta in regola; ARG per stage non verificate (vedi l'avviso sopra)."
fi
exit 0
fi
+36 -14
View File
@@ -157,22 +157,13 @@ jobs:
exit 0
fi
findings=""
for f in $files; do
# (a) registry: npm confronta l'URL del lockfile come stringa, e i lockfile
# risolvono tutti su PZeta_Touch.
reg=$(grep -nE 'packages/(pzeta_touch|pzeta)/' "$f" 2>/dev/null | cut -d: -f1 | tr '\n' ' ' | sed 's/ *$//')
if [ -n "$reg" ]; then
findings="${findings}${f} ${reg%% *} registry $(echo "$reg" | sed 's/ /, /g') -
"
fi
# (b) ARG fuori scope: una ARG vale nello stage che la dichiara e in
# quelli che ne derivano (FROM <stage>), come le ENV; quelle dichiarate
# prima del primo FROM valgono solo nelle righe FROM. Verificato sul
# log di BuildKit di nuxt-vue-components-docs v1.0.13: `FROM base AS
# deps` vede la NPM_VERSION dichiarata in `base`.
args=$(${AWK:-awk} '
arg_scope() {
${AWK:-awk} '
function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s }
# Nomi dichiarati da ARG/ENV: "A", "A=1", "A=1 B=2", "A valore".
function declared(rest, out, n, i, t) {
@@ -203,8 +194,8 @@ jobs:
if (stage == "") return
if (kw == "ARG") { declared(rest, d); for (k in d) { scope[k] = 1; varof[stage, k] = 1 }; return }
s = rest
while (match(s, /\$\{?[A-Za-z_][A-Za-z0-9_]*/)) {
v = substr(s, RSTART, RLENGTH); sub(/^\$\{?/, "", v)
while (match(s, /[$][{]?[A-Za-z_][A-Za-z0-9_]*/)) {
v = substr(s, RSTART, RLENGTH); sub(/^[$][{]?/, "", v)
s = substr(s, RSTART + RLENGTH)
if ((v in allargs) && !(v in scope) && !(v in predefined) && !((ln, v) in seen)) {
seen[ln, v] = 1
@@ -234,7 +225,34 @@ jobs:
buf = buf line
flush()
}
' "$f" "$f" 2>/dev/null)
' "$1" "$1"
}
# Caso di prova: se l'awk di questo runner non riconosce una ARG fuori
# scope nota, il controllo (b) non e' affidabile e lo si dice, invece di
# dichiarare in regola un Dockerfile che non si e' potuto leggere.
argcheck=1
prova=$(mktemp)
printf 'ARG X=1\nFROM scratch AS a\nRUN echo ${X}\n' > "$prova"
if [ "$(arg_scope "$prova" 2>/dev/null | cut -f2)" != "X" ]; then
argcheck=0
echo "::warning::Guardia Dockerfile: l'analisi delle ARG non funziona con l'awk di questo runner ($(${AWK:-awk} -W version 2>&1 | head -1)). Il controllo (b) e' saltato, il (a) resta."
fi
rm -f "$prova"
findings=""
for f in $files; do
# (a) registry: npm confronta l'URL del lockfile come stringa, e i lockfile
# risolvono tutti su PZeta_Touch.
reg=$(grep -nE 'packages/(pzeta_touch|pzeta)/' "$f" 2>/dev/null | cut -d: -f1 | tr '\n' ' ' | sed 's/ *$//')
if [ -n "$reg" ]; then
findings="${findings}${f} ${reg%% *} registry $(echo "$reg" | sed 's/ /, /g') -
"
fi
# (b) ARG fuori scope, con arg_scope definita sopra.
args=""
[ "$argcheck" = "1" ] && args=$(arg_scope "$f" 2>/dev/null)
while IFS=' ' read -r n v st; do
[ -n "$n" ] || continue
findings="${findings}${f} ${n} arg ${v} ${st}
@@ -245,7 +263,11 @@ jobs:
done
if [ -z "$findings" ]; then
if [ "$argcheck" = "1" ]; then
echo "Dockerfile: registry @pzeta e ARG per stage in regola."
else
echo "Dockerfile: registry @pzeta in regola; ARG per stage non verificate (vedi l'avviso sopra)."
fi
exit 0
fi