gsd-test-runner

module
v1.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2026 License: MIT

README

gsd-test

Run your Node test suite across Linux, Windows, and macOS in parallel — on hardware you already own — before pushing.

gsd-test is a local-dev harness, not a CI system. It runs on your Dev Workstation and ships work over SSH to remote Linux and Windows machines (Benches) you control. It catches platform-specific bugs — case-sensitive filesystems, missing system tools, different home directories, path-separator divergence — in your edit loop, while the diff is still hot.

Features

  • Cross-platform parity with zero CI lag. Push when you know it passes everywhere.
  • No shared infrastructure — your laptop orchestrates; your own remote machines execute.
  • Fail-loud diagnostics — every leg of the pipeline reports a distinct exit code with a diagnostics path.
  • Versioned Tester Images published to GHCR. Sentinel labels catch silent stale-image drift.
  • Failure-first output — failures surface loudly the instant they happen (✗ FAIL file:line · class · msg); quiet by default with a compact heartbeat, full firehose behind --verbose / GSD_TEST_VERBOSE=1.
  • Addressable artifacts — every run writes a small FAILURES.md + failures.json (+ junit.xml) under $XDG_STATE_HOME/gsd-test/runs/<run-id>/ and prints one machine-readable verdict line as the last line of stdout (ADR-0023).
  • Machine-readable output via --json-events (the full typed event stream) for CI integration or your own tooling.

Quick Start

# 1. Install (macOS arm64 example — see docs/installation.md for all platforms)
GSD_TEST_VERSION=v1.8.0
curl -L -o gsd-test \
  "https://github.com/open-gsd/gsd-test-runner/releases/download/${GSD_TEST_VERSION}/gsd-test-${GSD_TEST_VERSION}-darwin-arm64"
chmod +x gsd-test && mv gsd-test ~/.local/bin/
gsd-test --version   # → v1.8.0

# 2. Configure a Bench (a remote machine you SSH to with Docker installed)
mkdir -p ~/.config/gsd-test
cat > ~/.config/gsd-test/config.toml <<'EOF'
[defaults]
targets = ["linux"]

[[benches]]
name = "lab-rig-1"
host = "lab-rig-1.local"
os = "linux"

[versions]
linux = "v1.8.0"
EOF

# 3. Run your tests
cd ~/my-node-project
gsd-test

Documentation

Failure-first output (quiet-by-default stream, loud verdict, saved artifacts):

  • Failure-first Output — Why runs are quiet by default, what the verdict and artifacts are for
  • Output How-to Guides — Read a failed run, control verbosity, script the verdict, wire JUnit into CI
  • Output Reference — Verbosity levels, the verdict schema, and the artifact directory

Run-and-die (containerised node --test for coding agents):

Node version matrix (test every supported Node LTS line, fanned out across your Benches):

macOS via Tart (a real macOS-native guest, memory-capped, opt-in alongside Docker-on-macOS):

  • macOS via Tart — Why RuntimeTart exists and how it relates to Docker-on-macOS
  • macOS via Tart How-to Guides — Install Tart, configure a Bench, build/publish a Tester Image, diagnose a stuck run, clean up a leaked VM
  • macOS via Tart Reference — The runtime = "tart" value, the 8-leg sequence, DefaultMemoryMB, known limitations, the bake recipe, the publish-macos-tart CI job

How it Works (30-second version)

  1. You run gsd-test from inside your Node project's git repo.
  2. It loads ~/.config/gsd-test/config.toml — your list of remote machines (Benches), one per target OS.
  3. It constructs a PR-merged worktree (base branch merged with your current changes) in a scratch directory.
  4. For each target OS, it ensures the Tester Image is present on the corresponding Bench, then spawns a container, copies your worktree in, and runs npm ci + npm run build + node --test.
  5. Failures and a compact heartbeat stream back live (the full firehose is behind --verbose); at the end a per-OS summary prints, followed by a one-line machine verdict and a failure-first digest (FAILURES.md / failures.json / junit.xml) under $XDG_STATE_HOME/gsd-test/runs/<run-id>/.

Exit codes: 0 all platforms pass · 1 at least one platform failed · 2 infrastructure problem (see Troubleshooting)

License

MIT. See LICENSE if present, or check the repository root.

Contributing

PRs welcome. See docs/architecture.md for the design context and ADRs in docs/adr/.

Directories

Path Synopsis
Package agentintegration embeds the agent-integration assets (the Claude Code PreToolUse hook, the Codex shim, and the run-and-die skill) into the gsd-test binary so the installer can write them onto a Dev Workstation regardless of where the binary runs (issue #71, ADR-0022).
Package agentintegration embeds the agent-integration assets (the Claude Code PreToolUse hook, the Codex shim, and the run-and-die skill) into the gsd-test binary so the installer can write them onto a Dev Workstation regardless of where the binary runs (issue #71, ADR-0022).
cmd
gsd-test command
Command gsd-test is the Dev Workstation entry point for the Local Engine.
Command gsd-test is the Dev Workstation entry point for the Local Engine.
internal
bench
Package bench models a Bench: a remote SSH-reachable machine that runs containerized test suites on behalf of a Dev Workstation.
Package bench models a Bench: a remote SSH-reachable machine that runs containerized test suites on behalf of a Dev Workstation.
config
Package config loads Local Engine configuration: target OSes, Benches registry, GHCR credentials, opt-in flags (--allow-skip-os, --sequential).
Package config loads Local Engine configuration: target OSes, Benches registry, GHCR credentials, opt-in flags (--allow-skip-os, --sequential).
digest
Package digest builds the failure-first run artifacts (issue #84, ADR-0023): a deterministic, capped FAILURES.md + failures.json (and optional per-failure files) written under the per-run XDG artifact dir, plus the loud last-line machine verdict.
Package digest builds the failure-first run artifacts (issue #84, ADR-0023): a deterministic, capped FAILURES.md + failures.json (and optional per-failure files) written under the per-run XDG artifact dir, plus the loud last-line machine verdict.
dispatch
Package dispatch builds pure command-line argument slices for run-and-die execution (ADR-0021).
Package dispatch builds pure command-line argument slices for run-and-die execution (ADR-0021).
images
Package images owns Tester Image acquisition on a Bench: GHCR pull primary, in-repo Dockerfile build fallback.
Package images owns Tester Image acquisition on a Bench: GHCR pull primary, in-repo Dockerfile build fallback.
installhooks
Package installhooks installs (and reverses) the gsd-test agent integration on a Dev Workstation: the Claude Code PreToolUse guard hook, the run-and-die skill, and the Codex shim (issue #71, ADR-0022 Decision 5).
Package installhooks installs (and reverses) the gsd-test agent integration on a Dev Workstation: the Claude Code PreToolUse guard hook, the run-and-die skill, and the Codex shim (issue #71, ADR-0022 Decision 5).
pipeline
Package pipeline implements the Per-OS Pipeline Executor: one instance per (Bench, OS) per Local Engine run.
Package pipeline implements the Per-OS Pipeline Executor: one instance per (Bench, OS) per Local Engine run.
plan
Package plan builds a per-run execution plan: which Benches will run which OSes, which targeted OSes are being skipped via --allow-skip-os, and any unreachable Benches that should abort the run before any Pipeline starts.
Package plan builds a per-run execution plan: which Benches will run which OSes, which targeted OSes are being skipped via --allow-skip-os, and any unreachable Benches that should abort the run before any Pipeline starts.
reaper
Package reaper implements the Tier-2 external reaper from ADR-0021 Decision 2.
Package reaper implements the Tier-2 external reaper from ADR-0021 Decision 2.
refs
Package refs resolves user-supplied git refs (branch names, tags, SHA prefixes, "HEAD") to full commit SHAs by shelling out to `git rev-parse <ref>^{commit}`.
Package refs resolves user-supplied git refs (branch names, tags, SHA prefixes, "HEAD") to full commit SHAs by shelling out to `git rev-parse <ref>^{commit}`.
renderer
Package renderer consumes the pipeline.Event channel and renders human-readable progress + final Per-OS Reports to a writer (typically os.Stdout for the report banners and os.Stderr for live progress).
Package renderer consumes the pipeline.Event channel and renders human-readable progress + final Per-OS Reports to a writer (typically os.Stdout for the report banners and os.Stderr for live progress).
report
Package report defines the per-OS Report shape (ADR-0013, schema_version=2).
Package report defines the per-OS Report shape (ADR-0013, schema_version=2).
runner
Package runner owns the multi-OS test-run orchestration: the full lifecycle from config loading through verdict emission (ADR-0018 as amended by the Node matrix enhancement #108, which collapsed the original 5-phase structure into 3: Load → Plan → Schedule, with EnsurePresent folded into each scheduler worker because bench assignment is now dynamic/capacity-aware).
Package runner owns the multi-OS test-run orchestration: the full lifecycle from config loading through verdict emission (ADR-0018 as amended by the Node matrix enhancement #108, which collapsed the original 5-phase structure into 3: Load → Plan → Schedule, with EnsurePresent folded into each scheduler worker because bench assignment is now dynamic/capacity-aware).
runrender
Package runrender turns a run-and-die report.Report into node:test-style output a coding agent recognises, plus the matching process exit code.
Package runrender turns a run-and-die report.Report into node:test-style output a coding agent recognises, plus the matching process exit code.
runspec
Package runspec parses and validates the JSON "run spec" an agent submits to the Local Engine in place of invoking node directly (see issue #60 and ADR-0021).
Package runspec parses and validates the JSON "run spec" an agent submits to the Local Engine in place of invoking node directly (see issue #60 and ADR-0021).
runstate
Package runstate persists per-run state for async dispatch (ADR-0022 Decision 3, issue #70).
Package runstate persists per-run state for async dispatch (ADR-0022 Decision 3, issue #70).
schedule
Package schedule runs a set of OS-routed work Units across a pool of Benches, honoring a per-Bench concurrency cap.
Package schedule runs a set of OS-routed work Units across a pool of Benches, honoring a per-Bench concurrency cap.
tartexec
Package tartexec runs Tart (Cirrus Labs' Virtualization.framework-based macOS VM CLI) commands against a remote Bench, and runs commands inside a booted Tart guest VM, both over SSH.
Package tartexec runs Tart (Cirrus Labs' Virtualization.framework-based macOS VM CLI) commands against a remote Bench, and runs commands inside a booted Tart guest VM, both over SSH.
tartpipeline
Package tartpipeline implements the Tart-backed macOS test pipeline (ADR-0030 Decision 6): a separate Pipeline type, not a bench.Runtime branch inside internal/pipeline's existing leg methods, because Tart composes the same 8 named legs in a materially different order (boot requires the worktree already copied in; the image-version sentinel requires a booted, reachable guest) than Docker does.
Package tartpipeline implements the Tart-backed macOS test pipeline (ADR-0030 Decision 6): a separate Pipeline type, not a bench.Runtime branch inside internal/pipeline's existing leg methods, because Tart composes the same 8 named legs in a materially different order (boot requires the worktree already copied in; the image-version sentinel requires a booted, reachable guest) than Docker does.
tartreaper
Package tartreaper implements the Tart-side analogue of internal/reaper's Tier-2 "reap on next contact" sweep (ADR-0021 Decision 2), for Tart VMs started by internal/tartpipeline instead of Docker containers.
Package tartreaper implements the Tart-side analogue of internal/reaper's Tier-2 "reap on next contact" sweep (ADR-0021 Decision 2), for Tart VMs started by internal/tartpipeline instead of Docker containers.
telemetry
Package telemetry implements per-repo telemetry aggregation for run-and-die execution (ADR-0021 Decision 3, §F).
Package telemetry implements per-repo telemetry aggregation for run-and-die execution (ADR-0021 Decision 3, §F).
worktree
Package worktree owns the PR-merged worktree: legs 2 and 3 of the pipeline (base-branch fetch, real git merge in a scratch clone).
Package worktree owns the PR-merged worktree: legs 2 and 3 of the pipeline (base-branch fetch, real git merge in a scratch clone).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL