# Releasing `sifs`
SIFS uses a small manual release flow for now:
- publish the Rust crate to crates.io
- create a GitHub release tag
- publish the Homebrew formula to `tristanmanchester/homebrew-tap`
Homebrew releases are published from the tap repository at
`tristanmanchester/homebrew-tap`.
## Files involved
- [`Cargo.toml`](Cargo.toml) - crate version and release metadata
- [`Cargo.lock`](Cargo.lock) - locked dependency graph used by Homebrew
- [`CHANGELOG.md`](CHANGELOG.md) - release notes source of truth
- [`README.md`](README.md) - user-facing install and usage documentation
- [`packaging/homebrew/sifs.rb`](packaging/homebrew/sifs.rb) - formula used for release preparation
- `tristanmanchester/homebrew-tap:Formula/sifs.rb` - published Homebrew formula
## Normal release flow
1. Make the changes you want to ship.
2. Move the relevant [`CHANGELOG.md`](CHANGELOG.md) `Unreleased` entries into a
`## X.Y.Z - YYYY-MM-DD` section and leave a fresh `Unreleased` section at the
top.
3. Bump `version` in [`Cargo.toml`](Cargo.toml).
4. Run local checks:
```bash
python3 scripts/ci_release_check.py
cargo fmt --all --check
cargo test --locked
cargo build --locked
cargo build --locked --features diagnostics --bins
cargo publish --dry-run --locked
cargo package --list
ruby -c packaging/homebrew/sifs.rb
```
5. Merge the release commit to `main`.
6. Publish the crate:
```bash
cargo publish --locked
```
7. Tag the same `main` commit and create the GitHub release:
```bash
git tag vX.Y.Z
git push origin vX.Y.Z
gh release create vX.Y.Z --repo tristanmanchester/sifs --title "sifs vX.Y.Z" --generate-notes
```
8. Compute the crates.io tarball checksum:
```bash
curl -L https://crates.io/api/v1/crates/sifs/X.Y.Z/download | shasum -a 256
```
9. Update `tristanmanchester/homebrew-tap`:
```bash
git clone https://github.com/tristanmanchester/homebrew-tap.git /tmp/homebrew-tap
cp packaging/homebrew/sifs.rb /tmp/homebrew-tap/Formula/sifs.rb
```
Update the copied formula so `url` points at the crates.io download URL for
the new version and `sha256` is the checksum from the previous step.
10. Validate the tap formula:
```bash
brew uninstall --ignore-dependencies sifs || true
brew install --build-from-source /tmp/homebrew-tap/Formula/sifs.rb
sifs --help
sifs search authenticate_token --source /tmp/tiny-repo --mode bm25 --offline --no-cache
sifs mcp install --dry-run --client codex --source /tmp/tiny-repo --offline
sifs mcp install --dry-run --client claude --scope local --source /tmp/tiny-repo --offline
sifs update --check --json
```
11. Commit and push the tap update.
## Current install surfaces
- `cargo install sifs` installs the public `sifs` binary from crates.io.
- `brew install tristanmanchester/tap/sifs` installs the public `sifs` binary
from the tap formula.
- `sifs-benchmark` and `sifs-embed` are supported diagnostics, but they are not
part of the default package-manager install surface. Build them explicitly
with:
```bash
cargo build --release --features diagnostics --bins
```
## Notes
- Release tags should be `vX.Y.Z` and should match the `Cargo.toml` version.
- GitHub release notes should come from the matching `CHANGELOG.md` version
section.
- Publish the Homebrew formula to the dedicated tap, not `homebrew/core`.
- The Homebrew test must stay model-free and network-free after installation;
use BM25 with `--offline --no-cache`.