-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathverify.sh
More file actions
executable file
·125 lines (112 loc) · 3.87 KB
/
Copy pathverify.sh
File metadata and controls
executable file
·125 lines (112 loc) · 3.87 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
#!/usr/bin/env bash
#
# The single gate. "Verified" in any doc, commit, or status message means
# exactly one thing: ./verify.sh exited 0.
#
# Two rules this script exists to enforce:
# 1. All gates run in one command, so none can be quietly skipped.
# 2. A step that prints a runtime error but still exits 0 is a failure.
# Output is captured and scanned for the markers below; harness errors
# are never dismissed as noise. A hang is a failure, not a wait.
#
# Usage: ./verify.sh [--build] [--e2e]
set -uo pipefail
cd "$(dirname "$0")" || exit 1
WITH_BUILD=0
WITH_E2E=0
for arg in "$@"; do
case "$arg" in
--build) WITH_BUILD=1 ;;
--e2e) WITH_E2E=1 ;;
*)
echo "unknown flag: $arg" >&2
echo "usage: ./verify.sh [--build] [--e2e]" >&2
exit 2
;;
esac
done
# Deliberately narrow. A gate that cries wolf gets ignored.
ERROR_MARKERS='SyntaxError|ReferenceError|TypeError:|ERR_MODULE_NOT_FOUND|Cannot find module|Unhandled [Ee]rror|Unhandled [Rr]ejection|FATAL ERROR|node-gyp rebuild failed'
STEP_TIMEOUT="${VERIFY_STEP_TIMEOUT:-900}"
FAILED=()
run() {
local name="$1"
shift
echo
echo "--- ${name} ---"
local output status
output=$(timeout "$STEP_TIMEOUT" "$@" 2>&1)
status=$?
printf '%s\n' "$output"
if [ "$status" -eq 124 ]; then
echo "GATE FAILED: ${name} timed out after ${STEP_TIMEOUT}s (a hang is a failure)"
FAILED+=("$name (timeout)")
return
fi
if [ "$status" -ne 0 ]; then
echo "GATE FAILED: ${name} exited ${status}"
FAILED+=("$name (exit ${status})")
return
fi
if printf '%s' "$output" | grep -Eq "$ERROR_MARKERS"; then
echo "GATE FAILED: ${name} exited 0 but printed a runtime error marker"
FAILED+=("$name (error in output despite exit 0)")
return
fi
echo "ok: ${name}"
}
require_tool() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "GATE FAILED: required tool '$1' is not on PATH"
FAILED+=("missing tool: $1")
return 1
fi
}
# A missing tool must fail loudly. `rg` is deliberately not used anywhere in
# this gate: it is a shell function from an editor integration on this
# machine, not a binary, so it does not exist in a non-interactive script.
require_tool node
require_tool npm
# The git layer's tests, the seeded fixture, and the e2e setup all shell out
# to git. Without this, a missing git surfaces as an opaque test failure, and
# the nothing-hidden gate skips itself rather than failing.
require_tool git
run "Lint" npm run --silent lint
run "Format check" npm run --silent format:check
run "Type check" npm run --silent typecheck
run "House style" node scripts/check-style.mjs
run "No private material" node scripts/check-no-private.mjs
run "Nothing hidden from git" node scripts/check-nothing-hidden.mjs
run "Unit tests" npm run --silent test
# The browser suite starts its server with `npm run start`, which serves
# whatever was last built. Without a build first, --e2e passes against stale
# output: green, and blind to the change being verified. That is the false
# positive this project refuses, so asking for e2e asks for the build.
if [ "$WITH_E2E" -eq 1 ] && [ "$WITH_BUILD" -eq 0 ]; then
echo "note: --e2e builds first, because the browser suite serves the built output."
WITH_BUILD=1
fi
if [ "$WITH_BUILD" -eq 1 ]; then
run "Production build" npm run --silent build
fi
if [ "$WITH_E2E" -eq 1 ]; then
run "End to end" npm run --silent e2e
fi
echo
if [ ${#FAILED[@]} -ne 0 ]; then
echo "FAILED: ${#FAILED[@]} gate(s)"
for f in "${FAILED[@]}"; do
echo " - $f"
done
exit 1
fi
# The pass message states what it did not prove.
SKIPPED=""
[ "$WITH_BUILD" -eq 0 ] && SKIPPED="${SKIPPED} no production build;"
[ "$WITH_E2E" -eq 0 ] && SKIPPED="${SKIPPED} no e2e;"
if [ -n "$SKIPPED" ]; then
echo "VERIFIED: all gates passed (${SKIPPED% } run ./verify.sh --build --e2e before shipping)."
else
echo "VERIFIED: all gates passed, including build and e2e."
fi
exit 0