Skip to content

🎯 v1.0.0 readiness: exit-status fix, shellcheck, bats suite, manual release, extra commands#5

Merged
Labault merged 10 commits into
mainfrom
chore/v1-readiness
Jun 17, 2026
Merged

🎯 v1.0.0 readiness: exit-status fix, shellcheck, bats suite, manual release, extra commands#5
Labault merged 10 commits into
mainfrom
chore/v1-readiness

Conversation

@Labault

@Labault Labault commented Jun 17, 2026

Copy link
Copy Markdown
Owner

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) and commitlint pass across the branch.

Lot A — blockers

  • fix(setup): post-install validation no longer aborts a successful install under set -e; setup runs through a tee pipeline with a reliable exit status (PIPESTATUS) instead of a racy process substitution.
  • ci: shell scripts are now gated by shellcheck (pinned pre-commit hook, -x + .shellcheckrc), running in CI via the existing pre-commit step.

Lot B — test suite

  • test: real bats-core suite replacing the smoke script, covering profiles, path_manager, command registry/metadata, CLI (help/suggestions), setup, doctor failure status, uninstall config, completion, and the full update and install lifecycles (against a local remote, offline). Git-using tests clear inherited GIT_DIR so they are hook-safe.
  • ci: npm test runs in both the Ubuntu quality job and the macOS job (real install.sh coverage).

Lot C — release

  • ci: removed the release-please workflow — gitmoji-first commits aren't parsed as conventional types, so it was a false sense of automation that also contradicted the already-manual release-process.md. Made the manual-release choice explicit.

Lot D — orphan scripts

  • feat(cli): exposed 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 by mac setup).

CHANGELOG Unreleased updated accordingly.

Labault added 10 commits June 17, 2026 19:31
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.
@Labault Labault force-pushed the chore/v1-readiness branch from 4be51cb to f03ebe6 Compare June 17, 2026 18:04
@Labault Labault merged commit 090e197 into main Jun 17, 2026
4 checks passed
@Labault Labault deleted the chore/v1-readiness branch June 17, 2026 18:11
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant