# roses — release & distribution (TASK-10)

`roses` ships as a single self-contained binary. Releases are **automated from a git
tag** by two GitHub Actions workflows:

| Workflow | Trigger | Produces |
| --- | --- | --- |
| `.github/workflows/release.yml` (generated by [cargo-dist]) | tag `vX.Y.Z*` + PRs (plan only) | static **musl Linux** + **macOS** binaries (x86_64 + aarch64), checksums, a shell installer, a GitHub Release, and the **Homebrew formula** pushed to the tap. |
| `.github/workflows/publish-crates.yml` (hand-written) | final tag `vX.Y.Z` | `cargo publish` to crates.io (so `cargo install roses` works). |

The build matrix, installers, and tap live in **`dist-workspace.toml`** (`[dist]`).
**Do not hand-edit `release.yml`** — change `dist-workspace.toml` and regenerate:

```sh
cargo install cargo-dist --version 0.32.0 --locked   # the `dist` binary
dist plan        # validate config + preview the release artifacts (no network)
dist generate    # rewrite .github/workflows/release.yml from the config
```

On pull requests, `release.yml` runs in **`plan`** mode (`pr-run-mode = "plan"`) — it
validates the release config without releasing, alongside the normal `lint-and-test`
CI (see [`ci.md`](ci.md)).

## One-time setup (required before the first release)

1. **Create the tap repo** `rharmes/homebrew-tap` (empty, just a README). cargo-dist
   manages its contents.
2. **`HOMEBREW_TAP_TOKEN`** — a GitHub PAT with `repo` scope, added as a repository
   **secret on `rharmes/roses`** (not on the tap). `release.yml` uses it to push the
   formula.
3. **`CARGO_REGISTRY_TOKEN`** — a crates.io API token, added as a repository secret
   on `rharmes/roses`. `publish-crates.yml` uses it.
4. **Confirm the `roses` crate name is free** on crates.io (else `cargo publish`
   fails — rename, or drop the crates.io workflow).

## Cutting a release

1. Bump `version` in `Cargo.toml` (the first release is already `0.1.0`).
2. Commit on `main`, then tag and push:
   ```sh
   git tag v0.1.0
   git push origin v0.1.0
   ```
3. Watch the **Release** and **Publish to crates.io** workflow runs. When green:
   the [GitHub Release](https://github.com/rharmes/roses/releases) has the four
   binaries + checksums + `roses-installer.sh`; `brew install rharmes/tap/roses`
   and `cargo install roses` work.

## Known limitations

- **macOS binaries are unsigned.** Direct downloads trigger a Gatekeeper prompt
  (right-click → Open, or `xattr -d com.apple.quarantine`). Homebrew is less
  affected. Signing/notarization needs an Apple Developer cert — out of scope.
- **Linux keychain isn't wired up.** The musl binary builds, but `keyring` has no
  Linux backend enabled, so a Feedbin login won't persist between runs on Linux.
  A follow-up could add a Secret-Service backend (needs a running secret service at
  runtime). macOS uses the native Keychain and works.
- **No Windows build** (deliberate; the keyring backend isn't configured for it).

[cargo-dist]: https://github.com/axodotdev/cargo-dist
