# Releasing

Muga is published to crates.io as `muga`.

## Choosing the Next Version

Follow semantic versioning (`MAJOR.MINOR.PATCH`):

| Change type | Field to bump | Example |
|---|---|---|
| Bug fixes or internal refactoring | PATCH | `0.1.3` → `0.1.4` |
| Backwards-compatible new features | MINOR | `0.1.3` → `0.2.0` |
| Breaking changes | MAJOR | `0.1.3` → `1.0.0` |

The current version is in the `version` field of `Cargo.toml`.

## Release Flow

### 1. Run pre-release checks

```bash
cargo fmt --check
cargo test --locked
cargo publish --dry-run --locked
```

Fix any errors before proceeding.

### 2. Bump the version

Edit the `version` field in `Cargo.toml`:

```toml
version = "X.Y.Z"
```

Then update `Cargo.lock` to match:

```bash
cargo check
```

### 3. Commit

```bash
git add Cargo.toml Cargo.lock
git commit -m "chore: bump version to vX.Y.Z"
```

### 4. Create an annotated tag

```bash
git tag -a vX.Y.Z -m "muga vX.Y.Z"
```

Verify the tag was created correctly:

```bash
git tag -n | tail -5
```

### 5. Push

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

Pushing a `v*` tag triggers the `release.yml` GitHub Actions workflow, which tests the crate, verifies the package, publishes it to crates.io, and creates a GitHub Release.

### 6. Verify the release

1. Check the Actions tab on GitHub and confirm the workflow succeeded.
2. Confirm the new version appears on [crates.io/crates/muga](https://crates.io/crates/muga).
3. Confirm a new release was created on the GitHub Releases page.

## Trusted Publishing Setup

The workflow uses crates.io Trusted Publishing, so it does not need a long-lived crates.io token in GitHub Secrets.

Configure this once on crates.io for the `muga` crate:

- repository: `lef237/muga`
- workflow: `release.yml`
- environment: leave blank

The first release must be published manually before Trusted Publishing can be configured. That has already been done for `v0.1.0`.

## Recovering From a Bad Release

crates.io does not allow deleting a published version — once `X.Y.Z` is on the registry, it stays there forever. The recovery path is to yank the broken version and publish a new one.

1. Yank the bad version so new dependents stop resolving to it. Existing `Cargo.lock` files that already pinned it keep working.

```bash
cargo yank --version X.Y.Z
```

(If you later determine the version was actually fine, `cargo yank --version X.Y.Z --undo` reverses it.)

2. Delete the bad tag locally and on the remote so it does not linger as a published reference:

```bash
git tag -d vX.Y.Z
git push origin :refs/tags/vX.Y.Z
```

3. If a GitHub Release was created by the workflow, delete it from the GitHub UI (or with `gh release delete vX.Y.Z`).

4. Fix the underlying issue, bump `version` in `Cargo.toml` to the next patch (e.g. `X.Y.Z+1`), and run the normal Release Flow above. Do not reuse the yanked version number.

Yanking is the only supported "undo" — there is no way to overwrite or republish the same version, so always cut a new one.
