146 lines
4.2 KiB
Bash
Executable file
146 lines
4.2 KiB
Bash
Executable file
#!/bin/sh
|
|
# write-test-build-status: run the project's build and test commands and
|
|
# persist their outcome as JSON for the structured /testreport.
|
|
#
|
|
# Usage:
|
|
# scripts/write-test-build-status.sh # run both
|
|
# scripts/write-test-build-status.sh build # run build only
|
|
# scripts/write-test-build-status.sh tests # run tests only
|
|
#
|
|
# Status dir resolves to $AGENT_STATUS_DIR, then the legacy $CLAWDIE_VAR_DIR,
|
|
# and otherwise defaults to the repo-local tmp/status directory, matching
|
|
# getDefaultStatusDir() in src/reports/test-report.ts.
|
|
|
|
set -u
|
|
|
|
REPO_ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
cd "$REPO_ROOT"
|
|
|
|
STATUS_DIR=${AGENT_STATUS_DIR:-${CLAWDIE_VAR_DIR:-"$REPO_ROOT/tmp/status"}}
|
|
mkdir -p "$STATUS_DIR"
|
|
TMP_DIR="$REPO_ROOT/tmp/test-build-status"
|
|
mkdir -p "$TMP_DIR"
|
|
|
|
BUILD_PATH="$STATUS_DIR/build-status.json"
|
|
TEST_PATH="$STATUS_DIR/test-status.json"
|
|
|
|
iso_now() {
|
|
# GNU date supports -Iseconds; BSD date does not. Fall back to printf.
|
|
date -u +"%Y-%m-%dT%H:%M:%SZ"
|
|
}
|
|
|
|
write_status() {
|
|
out_path=$1
|
|
status=$2
|
|
command=$3
|
|
exit_code=$4
|
|
duration_ms=$5
|
|
extra=$6
|
|
completed_at=$(iso_now)
|
|
# Use node to encode JSON safely.
|
|
node -e '
|
|
const fs = require("fs");
|
|
const [outPath, status, command, exitCode, durationMs, completedAt, extraJson] =
|
|
process.argv.slice(1);
|
|
let payload = {
|
|
status,
|
|
command,
|
|
exitCode: Number(exitCode),
|
|
completedAt,
|
|
durationMs: Number(durationMs),
|
|
};
|
|
if (extraJson) {
|
|
try { payload = { ...payload, ...JSON.parse(extraJson) }; } catch {}
|
|
}
|
|
fs.writeFileSync(outPath, JSON.stringify(payload, null, 2) + "\n");
|
|
' "$out_path" "$status" "$command" "$exit_code" "$duration_ms" "$completed_at" "$extra"
|
|
}
|
|
|
|
run_build() {
|
|
cmd="npm run build --silent"
|
|
start=$(date +%s)
|
|
log_file="$TMP_DIR/build-$$.log"
|
|
rm -f "$log_file"
|
|
# shellcheck disable=SC2086
|
|
$cmd >"$log_file" 2>&1
|
|
exit_code=$?
|
|
end=$(date +%s)
|
|
duration_ms=$(( (end - start) * 1000 ))
|
|
status="ok"
|
|
[ "$exit_code" -ne 0 ] && status="fail"
|
|
summary=$(tail -n 1 "$log_file" | tr -d '\r')
|
|
extra=$(node -e '
|
|
const summary = process.argv[1] || "";
|
|
process.stdout.write(JSON.stringify({ summary }));
|
|
' "$summary")
|
|
write_status "$BUILD_PATH" "$status" "$cmd" "$exit_code" "$duration_ms" "$extra"
|
|
rm -f "$log_file"
|
|
echo "build: $status (exit $exit_code, ${duration_ms}ms) -> $BUILD_PATH"
|
|
return "$exit_code"
|
|
}
|
|
|
|
run_tests() {
|
|
json_file="$TMP_DIR/tests-$$.json"
|
|
rm -f "$json_file"
|
|
cmd="npx vitest run"
|
|
start=$(date +%s)
|
|
npx vitest run --reporter=json --outputFile="$json_file" >/dev/null 2>&1
|
|
exit_code=$?
|
|
end=$(date +%s)
|
|
duration_ms=$(( (end - start) * 1000 ))
|
|
status="ok"
|
|
[ "$exit_code" -ne 0 ] && status="fail"
|
|
extra=$(node -e '
|
|
const fs = require("fs");
|
|
const path = process.argv[1];
|
|
let raw;
|
|
try { raw = fs.readFileSync(path, "utf8"); } catch { process.stdout.write("{}"); process.exit(0); }
|
|
let parsed;
|
|
try { parsed = JSON.parse(raw); } catch { process.stdout.write("{}"); process.exit(0); }
|
|
const total = parsed.numTotalTests ?? 0;
|
|
const totalFiles = parsed.testResults?.length ?? parsed.numTotalTestSuites ?? 0;
|
|
const failing = parsed.numFailedTests ?? 0;
|
|
const skipped = parsed.numPendingTests ?? 0;
|
|
const failingNames = [];
|
|
for (const file of parsed.testResults || []) {
|
|
for (const t of file.assertionResults || []) {
|
|
if (t.status === "failed") {
|
|
const ancestors = (t.ancestorTitles || []).join(" > ");
|
|
failingNames.push(ancestors ? `${ancestors} > ${t.title}` : t.title);
|
|
}
|
|
}
|
|
}
|
|
process.stdout.write(JSON.stringify({
|
|
totalTests: total,
|
|
totalFiles,
|
|
failingTests: failing,
|
|
skippedTests: skipped,
|
|
failingTestNames: failingNames,
|
|
}));
|
|
' "$json_file")
|
|
write_status "$TEST_PATH" "$status" "$cmd" "$exit_code" "$duration_ms" "$extra"
|
|
rm -f "$json_file"
|
|
echo "tests: $status (exit $exit_code, ${duration_ms}ms) -> $TEST_PATH"
|
|
return "$exit_code"
|
|
}
|
|
|
|
target=${1:-both}
|
|
rc=0
|
|
case "$target" in
|
|
build)
|
|
run_build || rc=$?
|
|
;;
|
|
tests|test)
|
|
run_tests || rc=$?
|
|
;;
|
|
both|"")
|
|
run_build || rc=$?
|
|
run_tests || rc=$?
|
|
;;
|
|
*)
|
|
echo "usage: $0 [build|tests|both]" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
exit "$rc"
|