From 333375df93c165bd9365e4b32ed3613a085ad7f2 Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Thu, 10 Sep 2026 14:26:12 +0700 Subject: [PATCH 1/3] ci: install the published CLI and hold it to its documented exit codes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `install.yml` answered "does `cargo add termlens` work for a stranger?" and never asked the same of the binary. #310 was the cost: `termlens inspect --version` exited 2 in the published 0.10.0, exited 2 again in 0.10.1, and was found by a user of the published binary rather than by anything here. A `cli` job installs `termlens-cli` from crates.io on Linux and macOS -- every run, never from a cache, because a cached binary is evidence about whatever the registry served the day the cache was filled and this job exists to be evidence about what it serves now. It asserts every exit code `termlens --help` documents and STABILITY.md promises: `--version` in all four positions returning the same string, `inspect` printing a screen with its header and its trailer, `render` in all four formats with `--svg` actually starting ` file` is not a file `termlens render` will read -- the `--- exited:` trailer is a human line, not part of the snapshot format, and the parser says "line 26: e". The script strips it, and the round trip deserves its own issue. Closes #326 Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .github/scripts/check-cli-contract.sh | 115 ++++++++++++++++++++++++++ .github/workflows/ci.yml | 7 ++ .github/workflows/install.yml | 77 ++++++++++++++++- CHANGELOG.md | 21 +++++ CONTRIBUTING.md | 2 + 5 files changed, 220 insertions(+), 2 deletions(-) create mode 100755 .github/scripts/check-cli-contract.sh diff --git a/.github/scripts/check-cli-contract.sh b/.github/scripts/check-cli-contract.sh new file mode 100755 index 0000000..590e1eb --- /dev/null +++ b/.github/scripts/check-cli-contract.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +# The published CLI's documented contract, as exit-code assertions. +# +# `termlens --help` states three exit codes -- 0 ran, 1 diff found a +# difference, 2 termlens itself could not run -- and STABILITY.md promises +# them. Nothing checked them against an *installed* binary until #326: the +# `install` workflow verified `cargo add termlens` and never `cargo install +# termlens-cli`, so #310 (`termlens inspect --version` exiting 2) shipped in +# 0.10.0 and again in 0.10.1 and was found by a user of the published binary. +# +# Takes the binary to exercise, so the same assertions run against a release +# from crates.io in CI and against `target/debug/termlens` locally -- which +# is how you check that the assertions can fail at all: +# +# cargo build -p termlens-cli +# .github/scripts/check-cli-contract.sh target/debug/termlens +# +# Portability: macOS ships bash 3.2 and BSD sed. No `declare -A`, no GNU-only +# sed flags, no process substitution in the assertions. +set -euo pipefail + +BIN=${1:?usage: check-cli-contract.sh } +command -v "$BIN" >/dev/null 2>&1 || [ -x "$BIN" ] || { + echo "check-cli-contract: $BIN is not executable" >&2 + exit 2 +} + +WORK=$(mktemp -d 2>/dev/null || mktemp -d -t termlens-cli-contract) +trap 'rm -rf "$WORK"' EXIT +status=0 + +# `