mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery superseded: a newer head of the same pull request
powerlevel10k carries only data and a test that reads it; the part skipped it silently.
97 lines
4.6 KiB
Bash
97 lines
4.6 KiB
Bash
#!/bin/sh
|
|
# The catalogue's TypeScript part of its own check (novox/hq issue 302's `mesh-check-also`), declared in
|
|
# merge-check.sh's header and run by the build seat in the TypeScript toolchain, after the Go part. The media
|
|
# catalogue's twin is issue 311. Before this, a TypeScript module's change ran nothing of its own before it
|
|
# merged: the Go part said "NOT TESTED HERE", and a type error in the forge module would first have shown in
|
|
# its walk.
|
|
#
|
|
# For every touched module that has a package.json, in a copy of it outside the clone:
|
|
#
|
|
# 1. its dependencies are the toolchain's own (/app/node_modules: the mesh's SDK, Node's types and what the
|
|
# runtime carries), copied beside it, never fetched: the check holds no credential for the package
|
|
# registry. A module that depends on a package the toolchain does not hold is said NOT CHECKED, by name;
|
|
# 2. every source that is not a test is type-checked with the toolchain's compiler and the flags a build
|
|
# compiles with — the same check the build makes, before the merge rather than in the walk;
|
|
# 3. its tests (test/*.test.ts) run under Node's own runner with types stripped, as its own `npm test` does
|
|
# after its build: the sources are compiled to dist/ and beside themselves first, so a test that imports
|
|
# the compiled module, or a source that imports its sibling by its .js name, finds it.
|
|
#
|
|
# Said, never passed silently: a module with no tests is said NOT TESTED on every run that touches it.
|
|
#
|
|
# By hand: MESH_CHECK_MODULES=gitea sh merge-check-typescript.sh, in the toolchain image (it reads
|
|
# /app/node_modules), or with TOOLCHAIN_MODULES pointing at a node_modules that holds the same.
|
|
set -eu
|
|
|
|
deps="${TOOLCHAIN_MODULES:-/app/node_modules}"
|
|
tsc="$deps/typescript/bin/tsc"
|
|
if [ ! -f "$tsc" ]; then
|
|
echo "NOT CHECKED: no TypeScript compiler at $tsc — this part runs in the TypeScript toolchain"
|
|
exit 1
|
|
fi
|
|
|
|
# The modules the change reaches, as merge-check.sh reads them (hq ADR 0238).
|
|
if [ -n "${MESH_CHECK_MODULES:-}" ]; then
|
|
touched=$(printf '%s\n' "$MESH_CHECK_MODULES" | tr ',' '\n' | sed -e 's#^modules/##' -e '/\//d' | sort -u)
|
|
else
|
|
touched=$(printf '%s\n' "${MESH_CHECK_CHANGED:-}" | tr ',' '\n' | sed -n 's#^modules/\([^/]*\)/.*#\1#p' | sort -u)
|
|
fi
|
|
|
|
work=$(mktemp -d)
|
|
trap 'rm -rf "$work"' EXIT
|
|
failed=""
|
|
for m in $touched; do
|
|
d="modules/$m"
|
|
[ -f "$d/package.json" ] || continue
|
|
copy="$work/$m"
|
|
mkdir -p "$copy"
|
|
(cd "$d" && tar --exclude=./node_modules --exclude=./dist -cf - .) | (cd "$copy" && tar -xf -)
|
|
# What it depends on, against what the toolchain holds.
|
|
missing=$(node -e '
|
|
const p = require(process.argv[1]); const have = require("fs").readdirSync(process.argv[2]);
|
|
const scoped = (n) => n.startsWith("@") ? n.split("/")[0] : n;
|
|
const names = Object.keys({ ...(p.dependencies || {}), ...(p.devDependencies || {}) });
|
|
const held = (n) => have.includes(n) || (n.startsWith("@") && have.includes(scoped(n)) &&
|
|
require("fs").existsSync(process.argv[2] + "/" + n));
|
|
console.log(names.filter((n) => n !== "typescript" && !held(n)).join(" "));' "$copy/package.json" "$deps")
|
|
if [ -n "$missing" ]; then
|
|
echo "NOT CHECKED: $d depends on $missing, which the toolchain does not hold and the check cannot fetch"
|
|
continue
|
|
fi
|
|
mkdir -p "$copy/node_modules"
|
|
for p in "$deps"/*; do
|
|
case "$(basename "$p")" in typescript | esbuild | @esbuild) continue ;; esac
|
|
cp -r "$p" "$copy/node_modules/"
|
|
done
|
|
sources=$(cd "$copy" && find . -name '*.ts' ! -name '*.d.ts' ! -path './test/*' ! -path './node_modules/*' ! -path './dist/*' | sort)
|
|
if [ -n "$sources" ]; then
|
|
echo "type-checking $d (TypeScript)"
|
|
# shellcheck disable=SC2086 # the module's sources, none with a space in its name
|
|
if ! (cd "$copy" && node "$tsc" --noEmit --module NodeNext --moduleResolution NodeNext --target ES2022 \
|
|
--types node $sources); then
|
|
failed="$failed $m"
|
|
continue
|
|
fi
|
|
else
|
|
echo "$d has no TypeScript sources of its own to type-check: its tests read its files"
|
|
fi
|
|
if ! ls "$copy"/test/*.test.ts >/dev/null 2>&1; then
|
|
echo "NOT TESTED: $d is TypeScript and has no tests of its own"
|
|
continue
|
|
fi
|
|
if [ -n "$sources" ]; then
|
|
# shellcheck disable=SC2086
|
|
(cd "$copy" && node "$tsc" --module NodeNext --moduleResolution NodeNext --target ES2022 --types node \
|
|
--rootDir . --outDir dist $sources && node "$tsc" --module NodeNext --moduleResolution NodeNext \
|
|
--target ES2022 --types node --rootDir . --outDir . $sources)
|
|
fi
|
|
echo "testing $d (TypeScript)"
|
|
if ! (cd "$copy" && node --test --test-reporter=spec --experimental-strip-types \
|
|
--no-warnings=ExperimentalWarning test/*.test.ts); then
|
|
failed="$failed $m"
|
|
fi
|
|
done
|
|
if [ -n "$failed" ]; then
|
|
echo "TypeScript modules that failed:$failed"
|
|
exit 1
|
|
fi
|