Homebrew Distribution
s2s can be installed on macOS via Homebrew using the official tap.
Quick install
Section titled “Quick install”brew tap kiniuncorp/s2sbrew install s2sUpgrade
Section titled “Upgrade”brew upgrade s2sArtifact naming convention
Section titled “Artifact naming convention”Release assets follow this naming scheme:
| Asset | Pattern |
|---|---|
| arm64 tarball | s2s-{semver}-macos-arm64.tar.gz |
| x64 tarball | s2s-{semver}-macos-x64.tar.gz |
| Checksums | sha256sums.txt |
| Release tag | v{semver} (e.g. v0.2.38) |
Each tarball contains a single executable named s2s.
Maintainer release workflow
Section titled “Maintainer release workflow”The release pipeline is fully automated. Publishing a GitHub release is the only manual step — the workflow builds the binaries and updates the Homebrew formula without any further action required.
One-time setup — HOMEBREW_TAP_TOKEN
Section titled “One-time setup — HOMEBREW_TAP_TOKEN”The workflow needs write access to the KiniunCorp/homebrew-s2s tap repository.
This is a one-time step per machine/account.
- Go to GitHub.com → Settings → Developer settings → Personal access tokens → Fine-grained tokens
- Click Generate new token
- Set:
- Token name:
homebrew-tap-writer - Expiration: your preference (1 year is reasonable)
- Repository access: Only selected repositories →
KiniunCorp/homebrew-s2s - Permissions: Repository permissions → Contents → Read and write
- Token name:
- Click Generate token and copy the value
- Go to github.com/KiniunCorp/spec-to-ship → Settings → Secrets and variables → Actions
- Click New repository secret
- Name:
HOMEBREW_TAP_TOKEN - Value: paste the token
- Name:
- Click Add secret
This only needs to be done once. The token survives across releases until it expires.
Releasing a new version
Section titled “Releasing a new version”Once the token is set up, the full release process is:
Step 1 — Tag and publish the release
# In the spec-to-ship repo, on main after all changes are mergedgit tag v0.2.39git push origin v0.2.39Then on GitHub: Releases → Draft a new release → select the tag → add release notes → click Publish release.
Step 2 — Done
The .github/workflows/release-binaries.yml workflow triggers automatically and:
- Compiles TypeScript → bundles via esbuild → packages standalone binaries via
@yao-pkg/pkg - Creates
s2s-{version}-macos-arm64.tar.gz,s2s-{version}-macos-x64.tar.gz,sha256sums.txt - Uploads all three as release assets
- Parses the checksums and pushes a commit to
KiniunCorp/homebrew-s2sthat updatesFormula/s2s.rbwith the new version and real SHA256s
Monitor the run at: https://github.com/KiniunCorp/spec-to-ship/actions
Users running brew update && brew upgrade s2s will get the new version once the
formula commit lands in the tap (usually within a minute of the workflow completing).
Manual fallback
Section titled “Manual fallback”If the update-formula job fails (e.g. expired token), update the formula manually:
# Get the checksums from the releasecurl -sL https://github.com/KiniunCorp/spec-to-ship/releases/download/v0.2.39/sha256sums.txtThen edit Formula/s2s.rb in the KiniunCorp/homebrew-s2s repo:
version "0.2.38"version "0.2.39"
on_arm do url ".../v0.2.38/s2s-0.2.38-macos-arm64.tar.gz" sha256 "<old>" url ".../v0.2.39/s2s-0.2.39-macos-arm64.tar.gz" sha256 "<arm64 hash from sha256sums.txt>"endon_intel do url ".../v0.2.38/s2s-0.2.38-macos-x64.tar.gz" sha256 "<old>" url ".../v0.2.39/s2s-0.2.39-macos-x64.tar.gz" sha256 "<x64 hash from sha256sums.txt>"endgit add Formula/s2s.rbgit commit -m "chore: update s2s formula to v0.2.39"git push origin mainValidation commands
Section titled “Validation commands”# Syntax and style check (passes with any valid SHA256 string)brew audit s2s
# Strict audit with online asset verification (requires real release to be live)brew audit --strict --new --online s2s
# Test the installed binarybrew test s2s
# Check installed versions2s --versionTriggering the pipeline manually (for testing)
Section titled “Triggering the pipeline manually (for testing)”The workflow supports workflow_dispatch for testing the build without publishing a
real release. Note: the update-formula job does not run on manual dispatch —
only the binary build and upload run.
- Create a draft release with the target tag (e.g.
v0.2.38) on GitHub - Go to
https://github.com/KiniunCorp/spec-to-ship/actions - Select “Build and Upload Release Binaries”
- Click “Run workflow”, enter the version tag, run
- Check the release page for uploaded assets
Troubleshooting
Section titled “Troubleshooting”update-formula job fails with “Bad credentials”
The HOMEBREW_TAP_TOKEN secret is missing, expired, or lacks write access to
KiniunCorp/homebrew-s2s. Regenerate the token and update the secret (see
One-time setup above).
Formula audit fails with “checksum mismatch”
The SHA256 in the formula does not match the downloaded tarball. This should not happen with the automated workflow, but if it does, re-download and recompute:
curl -L -O https://github.com/KiniunCorp/spec-to-ship/releases/download/v0.2.38/s2s-0.2.38-macos-arm64.tar.gzshasum -a 256 s2s-0.2.38-macos-arm64.tar.gzbrew install s2s reports “no bottle available”
The formula uses pre-built binary tarballs, not Homebrew bottles. This is expected.
The bin.install "s2s" line extracts the binary and places it in the Homebrew bin
directory. No compilation happens.
Release pipeline fails at the pkg step
Ensure the bundle.cjs was produced by esbuild. If esbuild fails, check that
dist/cli.js exists after npm run build. The TypeScript compiler must succeed
before esbuild runs.
Binary not found after install
Run brew doctor and check that the Homebrew bin directory is in PATH:
echo $PATH | tr ':' '\n' | grep homebrew