From 26383c03ab0b25420638cce6460eae0daee32207 Mon Sep 17 00:00:00 2001 From: Andrea Grandi Date: Sun, 14 Jun 2026 21:26:36 +0200 Subject: [PATCH] Add install smoke tests for release artifacts and Homebrew - Add scripts/smoke-test-release.sh to verify built binaries run --help, --version, doctor, metadata, and feature list in an isolated HOME without touching user MCP config. - Add make smoke-test target that builds and smoke-tests bin/mcp-wire. - Run smoke tests in CI and release workflows before GoReleaser. - Document verification steps in README.md, including optional Homebrew-installed copy checks. Closes #11 --- .github/workflows/ci.yml | 3 + .github/workflows/release.yml | 3 + CHANGELOG.md | 4 +- Makefile | 7 ++- README.md | 20 ++++++ scripts/smoke-test-release.sh | 115 ++++++++++++++++++++++++++++++++++ 6 files changed, 150 insertions(+), 2 deletions(-) create mode 100755 scripts/smoke-test-release.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ed573a..531b05a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -89,6 +89,9 @@ jobs: - name: Build run: make build + - name: Smoke test built binary + run: ./scripts/smoke-test-release.sh ./bin/mcp-wire + - name: Upload build artifact uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a9dd74a..cd462c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,6 +40,9 @@ jobs: - name: Run integration tests run: make test-integration + - name: Smoke test built binary + run: make smoke-test + - name: Run GoReleaser uses: goreleaser/goreleaser-action@v7 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 2af2ed1..72e6c5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ ## [Unreleased] ### Added -- New `docs/tui-walkthrough.md` with animated SVG recordings of the install and uninstall TUI flows. +- New `make smoke-test` target and `scripts/smoke-test-release.sh` to verify built release artifacts run `--help`, `--version`, `doctor`, `metadata`, and `feature list` in an isolated `HOME` without writing to user MCP config. +- Release workflow now runs smoke tests before GoReleaser publishes artifacts. +- README documents how to verify an install or built binary, including optional Homebrew-installed copy checks. - New `docs/troubleshooting.md` covering common setup problems: missing targets, stale registry cache, credential resolution, OAuth follow-up, `--no-prompt` failures, and scope behavior. - Recording scripts in `docs/assets/` so TUI visuals can be re-generated from real `mcp-wire` runs. - Curated `github`, `notion`, and `linear` services — official OAuth-remote (streamable HTTP) MCP servers that install out of the box. diff --git a/Makefile b/Makefile index c47890a..8f8c304 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build test test-integration clean fmt vet lint +.PHONY: build test test-integration smoke-test clean fmt vet lint # Build the binary build: @@ -13,6 +13,10 @@ test: test-integration: go test -tags=integration ./internal/integration/... +# Smoke-test the built binary in an isolated HOME +smoke-test: build + @./scripts/smoke-test-release.sh ./bin/mcp-wire + # Run tests with verbose output test-verbose: go test -v ./... @@ -53,6 +57,7 @@ help: @echo " build - Build the binary" @echo " test - Run tests" @echo " test-integration - Run integration tests" + @echo " smoke-test - Run smoke tests on the built binary" @echo " test-verbose - Run tests with verbose output" @echo " fmt - Format code" @echo " vet - Run static analysis" diff --git a/README.md b/README.md index d6b2fe2..db68335 100644 --- a/README.md +++ b/README.md @@ -237,6 +237,26 @@ brew tap andreagrandi/tap brew install mcp-wire ``` +### Verify an install + +Run the built-in smoke tests to confirm the binary starts and non-mutating commands work. The tests use an isolated temporary `HOME` so they never touch your real MCP config or credentials: + +```bash +make smoke-test +``` + +Or point the script at any already-built binary: + +```bash +./scripts/smoke-test-release.sh ./bin/mcp-wire +``` + +To also verify a Homebrew-installed copy when `mcp-wire` is present in your Cellar: + +```bash +SMOKE_TEST_HOMEBREW=true ./scripts/smoke-test-release.sh "$(brew --prefix mcp-wire)/bin/mcp-wire" +``` + ### Build from source ```bash diff --git a/scripts/smoke-test-release.sh b/scripts/smoke-test-release.sh new file mode 100755 index 0000000..c234f6c --- /dev/null +++ b/scripts/smoke-test-release.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +set -euo pipefail + +resolve_binary() { + if [[ $# -gt 0 && -n "${1:-}" ]]; then + printf '%s\n' "$1" + return 0 + fi + + if [[ -x "bin/mcp-wire" ]]; then + printf '%s\n' "bin/mcp-wire" + return 0 + fi + + if command -v mcp-wire >/dev/null 2>&1; then + command -v mcp-wire + return 0 + fi + + echo "error: no mcp-wire binary found (pass a path or build bin/mcp-wire)" >&2 + return 1 +} + +binary=$(resolve_binary "${1:-}") +homebrew_verify="${SMOKE_TEST_HOMEBREW:-false}" + +if [[ ! -x "$binary" ]]; then + echo "error: binary not found or not executable: $binary" >&2 + exit 1 +fi + +isolated_home=$(mktemp -d /tmp/mcp-wire-smoke.XXXXXX) +trap 'rm -rf "$isolated_home"' EXIT + +export HOME="$isolated_home" +export PATH="/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:$PATH" + +echo "==> Smoke testing $binary with isolated HOME=$isolated_home" + +version_output=$("$binary" --version) +echo "version: $version_output" +if [[ -z "$version_output" ]]; then + echo "error: --version produced empty output" >&2 + exit 1 +fi + +help_output=$("$binary" --help) +if [[ "$help_output" != *"install and configure"* ]]; then + echo "error: --help missing expected content" >&2 + exit 1 +fi + +doctor_output=$("$binary" doctor) +if [[ "$doctor_output" != *"Targets:"* ]]; then + echo "error: doctor missing expected content" >&2 + exit 1 +fi + +metadata_output=$("$binary" metadata) +if [[ "$metadata_output" != *"\"schema_version\""* ]]; then + echo "error: metadata missing expected content" >&2 + exit 1 +fi + +feature_list_output=$("$binary" feature list) +if [[ "$feature_list_output" != *"registry"* ]]; then + echo "error: feature list missing expected content" >&2 + exit 1 +fi + +config_files=( + "$isolated_home/.claude.json" + "$isolated_home/.claude/settings.json" + "$isolated_home/.codex/config.toml" + "$isolated_home/.config/opencode/opencode.json" + "$isolated_home/.config/mcp-wire/credentials" + "$isolated_home/.config/mcp-wire/config.json" +) + +for config in "${config_files[@]}"; do + if [[ -e "$config" ]]; then + echo "error: smoke test wrote unexpected config file: $config" >&2 + exit 1 + fi +done + +echo "==> Basic smoke tests passed" + +if [[ "$homebrew_verify" != "true" ]]; then + exit 0 +fi + +if ! command -v brew >/dev/null 2>&1; then + echo "warning: brew not found, skipping Homebrew verification" >&2 + exit 0 +fi + +if ! brew list mcp-wire >/dev/null 2>&1; then + echo "warning: mcp-wire not installed via Homebrew, skipping Homebrew verification" >&2 + exit 0 +fi + +brew_prefix=$(brew --prefix mcp-wire) +brew_binary="$brew_prefix/bin/mcp-wire" +if [[ ! -x "$brew_binary" ]]; then + echo "error: Homebrew-installed binary not found at $brew_binary" >&2 + exit 1 +fi + +"$brew_binary" --version +"$brew_binary" doctor >/dev/null +"$brew_binary" metadata >/dev/null +brew test mcp-wire + +echo "==> Homebrew smoke tests passed"