Skip to content

Prepare Skillwalker for Homebrew installs - #17

Merged
mxriverlynn merged 9 commits into
mainfrom
feat/homebrew-install-prep
Sep 23, 2026
Merged

mxriverlynn merged 9 commits into
mainfrom
feat/homebrew-install-prep

Conversation

@mxriverlynn

@mxriverlynn mxriverlynn commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Prepares Skillwalker to be installed with Homebrew. The formula and the testdouble/homebrew-tap repo come later. This PR makes the in-repo changes a formula needs, following the investigation.

What changes

  • --version reports a real version. scripts/build.ts passes packages/cli/package.json's version into the compiled binary. Running from source reports dev. Before this change, the binary printed unknown.
  • Compiled binaries are re-signed on macOS. bun build --compile leaves a signature that codesign --verify rejects, and recent macOS releases kill such binaries on launch. The build now strips the stale signature, signs ad hoc, and verifies. It fails if any step fails.
  • SKILLWALKER_SCRIPTS_DIR points the CLI at the sandbox scripts. sandbox create mounts the scripts folder into the sandbox. A Homebrew install's own folder changes with every version, so without this setting each brew upgrade would force sandbox update and a new Claude login. If the folder is missing a script, startup fails with an error that names the variable.
  • Error messages say skillwalker, not ./build/skillwalker. Five sandbox retry hints pointed at a path that won't exist after a Homebrew install.
  • Release workflow. Pushing a v* tag fails unless the tag matches the CLI package version. It then builds and smoke tests on arm64 and x86_64 macOS, and attaches skillwalker-<version>-darwin-<arch>.tar.gz plus .sha256 files to a draft GitHub Release.
  • macOS CI job. Smoke tests the compiled binaries on macos-15, where the signature check runs.

One change from the investigation plan

The plan read the version from a SKILLWALKER_VERSION environment variable, falling back to package.json. This PR reads it only from packages/cli/package.json, and the release workflow checks the tag against it. That leaves one source for the version.

Tests

  • Unit tests:
    • the dev version fallback
    • resolveSandboxScripts with the variable unset, set, relative, and missing a script
    • the five sandbox error messages
  • Smoke tests (make build && bun run test:smoke):
    • --version
    • running through a bin symlink into a libexec copy from another directory
    • SKILLWALKER_SCRIPTS_DIR, both valid and empty
    • codesign --verify on macOS

The symlink and scripts-folder smoke tests passed on their first run, because the behavior already existed. I broke the layout on purpose (left duckdb.node out of the copy) to confirm the symlink test goes red.

Local results on macOS 26.5.1, arm64 (first run on Bun 1.3.11, re-run on 1.4.2):

  • make test: 83 files, 1080 tests passed
  • bun run test:smoke: 8 passed
  • bun run typecheck and bun run format:check: pass
  • bun run lint: 263 warnings, the same count as main

Before merging or tagging

  • Confirm macos-15-intel is a valid GitHub-hosted runner label.
  • Confirm oven-sh/setup-bun@v2 accepts bun-version-file: package.json (it should read the packageManager pin, Bun 1.4.2).
  • Re-ran locally on the pinned Bun 1.4.2: make test 1080 passed, bun run test:smoke 8 passed, typecheck passed. On 1.4.2, a plain bun build --compile of the CLI already passes codesign --verify, so the re-sign step now only protects against a Bun downgrade or regression. The smoke test would catch either of those on its own.
  • Neither workflow change has run on GitHub yet. The macOS CI job will run on this PR.

Not in this PR

  • The Homebrew formula and the testdouble/homebrew-tap repo.
  • Automatic formula updates on release (needs the tap and a HOMEBREW_TAP_TOKEN secret).
  • README install instructions for brew install, which wait until the tap exists.

scripts/build.ts defines SKILLWALKER_VERSION from packages/cli/package.json,
so the compiled binary prints it instead of yargs' "unknown".
…box scripts

A Homebrew install keeps the binary in a versioned Cellar folder, so the
scripts folder mounted into the sandbox would change on every upgrade. The
override lets an installer point at a folder whose path stays the same.
…in errors

A Homebrew install has no ./build folder, so the retry hints pointed at a
path that does not exist.
bun build --compile appends its bundle after the linker signs the file, so
codesign --verify rejected both binaries. Strip the stale signature, sign
ad hoc, and verify, then smoke test the result on macOS.
Cover running through a bin symlink into libexec from another directory,
and reading the sandbox scripts from SKILLWALKER_SCRIPTS_DIR.
Pushing a v* tag checks it against packages/cli/package.json, builds and
smoke tests arm64 and x86_64 binaries, and attaches the tarballs and their
checksums to a draft GitHub Release. CI also smoke tests the binaries on
macOS, where the codesign check runs.
@mxriverlynn
mxriverlynn marked this pull request as ready for review September 23, 2026 13:51
@mxriverlynn
mxriverlynn merged commit eaa161a into main Sep 23, 2026
9 checks passed
@mxriverlynn
mxriverlynn deleted the feat/homebrew-install-prep branch September 23, 2026 13:51
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