-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheck-node-version.sh
More file actions
executable file
·121 lines (107 loc) · 4.72 KB
/
Copy pathcheck-node-version.sh
File metadata and controls
executable file
·121 lines (107 loc) · 4.72 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
#!/usr/bin/env bash
# Assert the fleet's default Node version is in sync across the workflows that
# declare it, and — when sibling OpenPhysics checkouts are present — that member
# package.json files track the same major (engines.node floor + @types/node).
# README.md ("Node version") says these "must stay in sync" — this turns that
# prose warning into an enforced check.
#
# scripts/check-node-version.sh
#
# Exits non-zero (and prints what disagrees) if the versions diverge.
# Per-repo CI enforcement of engines/@types/node lives in check-repo-compliance.sh
# (which derives the expected major from Baton's ci.yml).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
WF="$ROOT/.github/workflows"
FAIL=0
fail() { echo "FAIL: $1"; FAIL=1; }
# Each entry: "label|file|extractor" where extractor is a grep -oP that yields the version.
declare -A VERSIONS
extract() {
local file="$1" pattern="$2"
[ -f "$file" ] || { fail "missing workflow: ${file#"$ROOT/"}"; return 1; }
grep -oP "$pattern" "$file" | head -n1
}
# Quotes may be single or double across the workflows, so match either.
# ci.yml / deploy.yml declare it as the `node-version` input `default:`.
VERSIONS[ci.yml]="$(extract "$WF/ci.yml" $'default:\\s*["\']\\K[0-9]+(?=["\'])' || true)"
VERSIONS[deploy.yml]="$(extract "$WF/deploy.yml" $'default:\\s*["\']\\K[0-9]+(?=["\'])' || true)"
# Other workflows: node-version on the setup-node step.
for f in fleet-health.yml fleet-exec.yml optimize-assets.yml refresh-screenshots.yml; do
VERSIONS[$f]="$(extract "$WF/$f" $'node-version:\\s*["\']\\K[0-9]+(?=["\'])' || true)"
done
FILES=(ci.yml deploy.yml fleet-health.yml fleet-exec.yml optimize-assets.yml refresh-screenshots.yml)
echo "Declared Node versions:"
for f in "${FILES[@]}"; do
v="${VERSIONS[$f]:-}"
echo " $f: ${v:-<not found>}"
[ -n "$v" ] || fail "$f: could not extract a Node version"
done
# All present versions must be identical.
uniq_versions="$(printf '%s\n' "${VERSIONS[@]}" | grep -v '^$' | sort -u | tr '\n' ' ' | sed 's/ $//')"
if [ "$FAIL" -eq 0 ] && [ "$(printf '%s' "$uniq_versions" | wc -w)" -ne 1 ]; then
fail "Node versions diverge across workflows: $uniq_versions — bump all declared workflows together (see README 'Node version')"
fi
if [ "$FAIL" -ne 0 ]; then
echo "Node-version check failed."
exit 1
fi
FLEET_NODE_MAJOR="$uniq_versions"
echo "OK: all workflows agree on Node $FLEET_NODE_MAJOR"
echo "Expected member-repo pins: engines.node \">=${FLEET_NODE_MAJOR}\" and @types/node major ${FLEET_NODE_MAJOR}"
# Optional workspace scan: when Baton lives beside sibling checkouts (local
# OpenPhysics bootstrap layout), assert catalog member pins match. Limited to
# simulations, SceneryStackTemplate, and Almanach — not every sibling npm repo
# (jscd48 / pyro / … keep their own engine floors). Skipped in Baton-only CI.
PARENT="$(cd "$ROOT/.." && pwd)"
CATALOG="$ROOT/structure/repos.json"
checked=0
if [[ -d "$PARENT" && -f "$CATALOG" ]]; then
while IFS= read -r name; do
pkg="$PARENT/$name/package.json"
[[ -f "$pkg" ]] || continue
dir="$PARENT/$name"
meta="$(python3 -c "
import json, sys
p = json.load(open(sys.argv[1]))
engines = (p.get('engines') or {}).get('node') or ''
types = (p.get('devDependencies') or {}).get('@types/node') or (p.get('dependencies') or {}).get('@types/node') or ''
print(engines + '\t' + types)
" "$pkg")"
engines="${meta%%$'\t'*}"
types="${meta#*$'\t'}"
[[ -z "$engines" && -z "$types" ]] && continue
checked=$((checked + 1))
if [[ -n "$engines" && ! "$engines" =~ ^\>=${FLEET_NODE_MAJOR}(\.0\.0)?$ ]]; then
fail "$name: engines.node must be >=${FLEET_NODE_MAJOR} (found: $engines)"
fi
if [[ -n "$types" ]]; then
types_major="$(sed -E 's/^[^0-9]*([0-9]+).*/\1/' <<<"$types")"
if [[ "$types_major" != "$FLEET_NODE_MAJOR" ]]; then
fail "$name: @types/node major must be ${FLEET_NODE_MAJOR} (found: $types)"
fi
fi
for pinfile in .nvmrc .node-version; do
if [[ -f "$dir/$pinfile" ]]; then
pin="$(tr -d 'v[:space:]' <"$dir/$pinfile")"
pin_major="${pin%%.*}"
if [[ "$pin_major" != "$FLEET_NODE_MAJOR" ]]; then
fail "$name: $pinfile pins Node $pin but fleet major is $FLEET_NODE_MAJOR"
fi
fi
done
done < <(jq -r '.repos[] | select(.isSimulation == true or .type == "template" or .name == "Almanach") | .name' "$CATALOG")
fi
if [[ $checked -gt 0 ]]; then
if [[ $FAIL -eq 0 ]]; then
echo "OK: $checked sibling package.json pin(s) match Node $FLEET_NODE_MAJOR"
fi
else
echo "Note: no sibling member package.json pins found (workflow-only check)."
fi
if [ "$FAIL" -ne 0 ]; then
echo "Node-version check failed."
exit 1
fi
echo "Node-version check passed."