clipmem 0.2.2

macOS clipboard memory backed by SQLite and searchable from OpenClaw
Documentation
# Releasing `clipmem`

This project uses a tag-driven release flow.

Pushing a semver tag like `v0.1.0` triggers the release workflow in [`.github/workflows/release.yml`](/Users/tristan/Projects/clipmem/.github/workflows/release.yml), which:

- validates that the tag matches `Cargo.toml`
- builds release artifacts with `cargo-dist`
- creates or updates the GitHub Release
- publishes to crates.io through the reusable publish workflow
- updates the Homebrew formula and cask in `tristanmanchester/homebrew-tap`

The Rust CLI and SwiftUI menu bar app ship as separate Homebrew install surfaces: the `clipmem` formula installs the CLI, and the `clipmem-app` cask installs the menu bar app plus a formula dependency.

## Files involved

- [`Cargo.toml`]/Users/tristan/Projects/clipmem/Cargo.toml – crate version and publish metadata
- [`dist-workspace.toml`]/Users/tristan/Projects/clipmem/dist-workspace.toml`cargo-dist` release configuration
- [`.github/workflows/ci.yml`]/Users/tristan/Projects/clipmem/.github/workflows/ci.yml – normal CI checks
- [`.github/workflows/release.yml`]/Users/tristan/Projects/clipmem/.github/workflows/release.yml – tag-driven release workflow
- [`.github/workflows/publish-crate.yml`]/Users/tristan/Projects/clipmem/.github/workflows/publish-crate.yml – crates.io publish job
- [`.github/scripts/write-menubar-cask.sh`]/Users/tristan/Projects/clipmem/.github/scripts/write-menubar-cask.sh – generated Homebrew cask writer
- [`macos/ClipmemMenuBar/`]/Users/tristan/Projects/clipmem/macos/ClipmemMenuBar – native menu bar app source and tests

## Normal release flow

`clipmem` now publishes to crates.io through Trusted Publishing using GitHub OIDC. The reusable publish workflow authenticates immediately before `cargo publish`, so no long-lived crates.io token is exposed to earlier build or test steps.

1. Make the changes you want to ship.
2. Bump `version` in [`Cargo.toml`]/Users/tristan/Projects/clipmem/Cargo.toml.
3. Run local checks:

   ```bash
   cargo test
   cargo publish --dry-run --locked
   cargo package --list
   dist plan --allow-dirty
   xcodebuild -project macos/ClipmemMenuBar/ClipmemMenuBar.xcodeproj -scheme ClipmemMenuBar -configuration Debug -destination 'platform=macOS' -derivedDataPath /tmp/clipmem-menubar-derived test
   ```

   `--allow-dirty` is required because [`.github/workflows/release.yml`]/Users/tristan/Projects/clipmem/.github/workflows/release.yml is intentionally hardened by hand and no longer exactly matches cargo-dist's generated template. Do not replace the workflow with generated remote installer commands just to make `dist plan` run without this flag.

4. Merge the release commit to `main`.
5. Push the release tag:

   ```bash
   git tag vX.Y.Z
   git push origin vX.Y.Z
   ```

6. Wait for the GitHub Actions release workflow to finish.
7. Verify:
   - the GitHub Release exists and has the expected assets
   - crates.io shows the new version
   - `brew install tristanmanchester/tap/clipmem` works on Apple Silicon
   - `brew install --cask tristanmanchester/tap/clipmem-app` works on Apple Silicon
   - `clipmem setup`, `clipmem service status`, and `clipmem doctor` work from the Homebrew install
   - the cask postflight starts capture without deleting or replacing the user's database
   - the menu bar app opens from `/Applications` and resolves `/opt/homebrew/bin/clipmem`
   - launch at login is enabled by default and can be disabled in Settings

## Current release artifacts

For `0.2.2`, `dist plan --allow-dirty` reports these CLI artifacts:

- `source.tar.gz`
- `source.tar.gz.sha256`
- `clipmem.rb`
- `sha256.sum`
- `clipmem-aarch64-apple-darwin.tar.xz`
- `clipmem-aarch64-apple-darwin.tar.xz.sha256`

The menu bar app release job adds these app artifacts to the same GitHub Release:

- `clipmem-app-aarch64-apple-darwin.zip`
- `clipmem-app-aarch64-apple-darwin.zip.sha256`

The generated Homebrew formula installs the `clipmem` binary for Apple Silicon. It does not include a `service do` stanza, so users should start background capture with `clipmem setup` when installing the CLI alone. The `clipmem-app` cask depends on that formula and runs `clipmem setup` in its postflight step.

## Menu bar app release

The release workflow builds `ClipmemMenuBar.app` with `Release` configuration on `macos-14`, signs it with Developer ID Application, notarizes it with `notarytool`, staples the notarization ticket, uploads the final zip to the GitHub Release, and publishes `Casks/clipmem-app.rb` to the tap.

Required GitHub secrets:

- `APPLE_DEVELOPER_ID_CERTIFICATE_BASE64` – base64-encoded `.p12` Developer ID Application certificate.
- `APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORD` – password for that `.p12`.
- `APPLE_TEAM_ID` – Apple Developer team id.
- Preferred notarization path: `APP_STORE_CONNECT_API_KEY_BASE64`, `APP_STORE_CONNECT_KEY_ID`, and `APP_STORE_CONNECT_ISSUER_ID`.
- Fallback notarization path: `APPLE_ID` and `APPLE_APP_SPECIFIC_PASSWORD`.
- `HOMEBREW_TAP_TOKEN` – token that can push to `tristanmanchester/homebrew-tap`.

Clean-machine cask verification:

```bash
brew install tristanmanchester/tap/clipmem
clipmem --version
brew install --cask tristanmanchester/tap/clipmem-app
clipmem service status
open -a ClipmemMenuBar
```

The cask intentionally removes only app preferences on zap. Do not delete `~/Library/Application Support/clipmem` from the cask because that directory contains the user's clipboard archive and logs.

## Trusted Publishing configuration

The crates.io Trusted Publisher for `clipmem` should be configured as:

1. In the crate settings on crates.io:
   - `clipmem` -> Settings -> Trusted Publishing
2. Add a GitHub trusted publisher with:
   - repository owner: `tristanmanchester`
   - repository name: `clipmem`
   - workflow filename: `release.yml`
   - environment: `release`
3. Confirm the GitHub repo `release` environment exists, since the workflow runs in that environment and crates.io matches against it.
4. After the first successful OIDC-backed publish, remove the old `CARGO_REGISTRY_TOKEN` GitHub Actions secret if it still exists.

## Current CI checks

Normal CI in [`.github/workflows/ci.yml`](/Users/tristan/Projects/clipmem/.github/workflows/ci.yml) runs:

- `cargo test`
- `cargo publish --dry-run --locked`
- `cargo package --list`

The release publish workflow reruns the same validation before publishing.

## Notes

- Release tags should be `vX.Y.Z`.
- The packaged binary target is currently `aarch64-apple-darwin` only.
- The Homebrew formula and cask are published to the dedicated tap, not `homebrew/core`.
- The Homebrew formula installs the CLI only; the SwiftUI app is installed by the `clipmem-app` cask.
- GitHub Release is an output of the tag push, not the thing that triggers publishing.
- The reusable publish job is invoked from `release.yml`, and crates.io currently validates the caller workflow filename from GitHub's `workflow_ref` claim. Keep the trusted publisher registered to `release.yml`.
- [`.github/workflows/release.yml`]/Users/tristan/Projects/clipmem/.github/workflows/release.yml is now a security-owned workflow. If you regenerate cargo-dist files with `dist init --yes`, review the diff manually and keep the pinned installer hardening in place instead of restoring generated bootstrap commands.