devist 0.1.0

Project bootstrap CLI for AI-assisted development. Spin up new projects from templates, manage backends, and keep your codebase comprehensible.
# Releasing devist

This document describes how to ship a new version.

## Overview

devist is published in three places. The release workflow handles the second
and third automatically once a tag is pushed.

| Channel | What | How |
|---|---|---|
| GitHub Releases | Prebuilt binaries for 5 platforms | Automatic on tag push |
| crates.io | Source crate (`cargo install devist`) | Automatic on stable tag |
| Homebrew tap | macOS / Linux Formula | Automatic on stable tag |

## One-time Setup

Before the first stable release, configure the following on GitHub.

### 1. crates.io API token

1. Generate an API token at <https://crates.io/me>.
   - Scope: `publish-new`, `publish-update`. Limit to crate `devist` after
     the first publish.
2. Add it to the `WebchemistCorp/devist` repo:
   - Settings → Environments → New environment named `crates-io`.
   - Add secret `CARGO_REGISTRY_TOKEN` with the token value.
   - Optionally require a manual approval for this environment so each
     publish needs your click.

### 2. Homebrew tap PAT

Create the tap repository: `WebchemistCorp/homebrew-devist`. Push the
contents of the local `homebrew-devist/` directory (placeholder Formula) to
seed it.

Then generate a personal access token (or fine-grained PAT) with write
access to `WebchemistCorp/homebrew-devist`:

1. <https://github.com/settings/tokens?type=beta>
2. Repository access → only `WebchemistCorp/homebrew-devist`.
3. Permissions → Contents: Read and write.
4. Add it to the `WebchemistCorp/devist` repo as a secret named
   `HOMEBREW_TAP_TOKEN`.

### 3. Publish a placeholder version (optional but recommended)

The very first `cargo publish` reserves the name on crates.io. If you want
to reserve `devist` before the actual release, you can publish a stub:

```bash
# Locally, with a clean checkout:
cargo publish --dry-run
# ... and only run the real `cargo publish` once you're ready.
```

## Per-release Procedure

### 1. Bump the version

Edit `Cargo.toml`:

```toml
version = "0.1.0"
```

Update `CHANGELOG.md`:

- Move "Unreleased" notes under a new `## [0.1.0] - YYYY-MM-DD` section.
- Add the GitHub compare/release links at the bottom.

### 2. Verify locally

```bash
cargo fmt --all -- --check
cargo clippy --release --all-targets -- -D warnings
cargo test --release
cargo publish --dry-run --allow-dirty
```

### 3. Commit and tag

```bash
git add Cargo.toml CHANGELOG.md
git commit -m "release: v0.1.0"
git tag v0.1.0
git push
git push --tags
```

### 4. Watch the workflow

The `Release` workflow runs automatically. It will:

1. Build binaries for 5 platforms.
2. Create a **draft** GitHub Release with all archives + checksums.
3. Run `cargo publish` (only if the tag has no `-` suffix).
4. Update the Homebrew tap's `Formula/devist.rb`.

Steps 3 and 4 require the secrets configured above. If they fail, the
workflow will surface the error.

### 5. Publish the draft Release

GitHub Releases page → review the draft → click **Publish release**.

Until you publish, users won't see the new version on the Releases page.
The `install.sh` resolution to "latest" will only pick up published
releases.

### 6. Smoke test

```bash
# Homebrew
brew update
brew upgrade devist
devist --version

# crates.io
cargo install devist --force
devist --version

# install.sh
curl -fsSL https://raw.githubusercontent.com/WebchemistCorp/devist/main/scripts/install.sh | sh
devist --version
```

## Versioning Policy

- `0.x.y` is **beta**. Breaking changes can land in any minor bump.
  The release workflow marks `v0.x.y` releases as **prerelease**, but
  still publishes to crates.io and Homebrew.
- Pre-release tags like `v0.2.0-rc1` skip crates.io and Homebrew steps
  (they only get a GitHub draft release with binaries).
- `1.0.0+` follows strict SemVer.

## Yanking a bad release

If something is broken on crates.io:

```bash
cargo yank --version 0.1.0
# Re-publish later: cargo yank --version 0.1.0 --undo
```

Yanking does not delete; it prevents new resolutions to that version.
For Homebrew, push a corrected commit to `homebrew-devist`.