🎯 v1.0.0 readiness: exit-status fix, shellcheck, bats suite, manual release, extra commands#5
Merged
Conversation
Two exit-code defects in the setup runner: - Post-install validation used `command -v brew >/dev/null && success ...`. Under `set -e`, a missing tool made that line return non-zero and aborted an otherwise successful install, skipping the remaining checks and the success message. Replace it with a check_tool helper that warns instead of failing. - Output went through `exec > >(tee ...)`, a process substitution whose completion (and thus the final log lines) races with shell exit. Run the work in a function piped to tee and propagate the real status via PIPESTATUS, so the captured transcript is complete and the exit code is the setup work's, not tee's.
The project is shell-heavy but shellcheck (though installed) ran in no gate. Add the pinned shellcheck-py pre-commit hook with `-x` so sourced libraries are followed (enabled via .shellcheckrc external-sources), and scope it to scripts/ and install.sh. The hook ships its own binary, so it runs in CI through the existing `pre-commit run --all-files` step with no extra setup. All current scripts pass cleanly.
Replace the single smoke script with a real bats-core suite (run via "npm test"): - profiles: validation, discovery, safe-charset/traversal rejection - path_manager: PATH block install idempotency, removal, content safety - command_registry: discovery, metadata/@name/@description parsing - cli: help, --help/-h, unknown-command suggestion, usage - setup: dry-run safety and absolute log path - doctor: non-zero exit on a missing tool - uninstall: identical-only --remove-config behavior - completion: committed file matches the generator - update: fast-forward, dry-run, dirty-tree refusal against a local remote - install: symlink/PATH creation, idempotency, uninstall (macOS only) The git-using tests clear inherited GIT_DIR/GIT_INDEX_FILE so they are robust when the suite runs inside a git hook. bats is a dev dependency so it is available wherever npm ci runs. scripts/test-cli.sh is removed; its checks are covered above.
Run `npm test` (the bats suite) in both gates: the Ubuntu quality job (libs, CLI, update lifecycle — install tests skip off macOS) and the macOS job (adds real install.sh coverage via Node + npm ci). Drop the standalone "Verify generated Zsh completion" step, now covered by completion.bats.
release-please was configured but unreliable: the project's gitmoji-first commits (e.g. "🐛 fix:") are not parsed as conventional types by release-please, so it would rarely detect releasable changes — a false sense of automation that also contradicted the fully manual flow already described in release-process.md. Remove the workflow, make the manual-release choice explicit in release-process.md, and update the 1.0.0 criterion accordingly.
apply-macos-defaults.sh, install-keyboard-layout.sh and install-vscode-extensions.sh existed but were not reachable from the CLI. Add discoverable `mac defaults`, `mac keyboard` and `mac vscode` (passing through --with-optional) wrappers with --help, regenerate the zsh completion, cover them in the bats suite, and document the commands in the README and the relevant tool docs. They remain opt-in and are not run by `mac setup`.
Note the new opt-in commands, the bats suite, shellcheck gating, the manual release process, and the setup exit-status fix in the Unreleased section.
The update lifecycle test created the throwaway bare remote with the runner's default branch (master on CI) while pushing main, leaving the clone with a dangling HEAD and no files. Initialise the bare remote with `-b main` so the test is deterministic regardless of init.defaultBranch.
The install idempotency test cloned the working checkout, whose HEAD can be detached on CI (a PR merge ref), breaking the second run's `git pull --ff-only`. Build a seed repo on a real main branch and install from it, making the test independent of how the runner checked the repo out.
The full Brewfile duplicated configs/vscode/extensions(.optional).txt as `vscode` entries, so `brew bundle` pulled them from the VS Code marketplace during macOS CI — a flaky dependency that failed on anthropic.claude-code. Remove the vscode entries; extensions are now managed solely through `mac vscode` (and `--with-optional`), and the macOS gate no longer depends on the marketplace.
4be51cb to
f03ebe6
Compare
Labault
added a commit
that referenced
this pull request
Jun 18, 2026
🎯 v1.0.0 readiness: exit-status fix, shellcheck, bats suite, manual release, extra commands
Labault
added a commit
that referenced
this pull request
Jun 21, 2026
🎯 v1.0.0 readiness: exit-status fix, shellcheck, bats suite, manual release, extra commands
Labault
added a commit
that referenced
this pull request
Jun 22, 2026
🎯 v1.0.0 readiness: exit-status fix, shellcheck, bats suite, manual release, extra commands
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses the remaining gaps toward a viable, high-quality 1.0.0, in the agreed lot order. Atomic commits;
npm test(bats),pre-commit run --all-files(incl. shellcheck) andcommitlintpass across the branch.Lot A — blockers
set -e; setup runs through ateepipeline with a reliable exit status (PIPESTATUS) instead of a racy process substitution.-x+.shellcheckrc), running in CI via the existing pre-commit step.Lot B — test suite
GIT_DIRso they are hook-safe.npm testruns in both the Ubuntu quality job and the macOS job (real install.sh coverage).Lot C — release
release-process.md. Made the manual-release choice explicit.Lot D — orphan scripts
mac defaults,mac keyboard,mac vscode(with--with-optional) wrapping the previously unreachable scripts; regenerated completion, added tests, documented in README and tool docs. They stay opt-in (not run bymac setup).CHANGELOG Unreleased updated accordingly.