# How to perform nextest releases

## Pre-requisites

Releases depend on:

- [cargo-release](https://github.com/crate-ci/cargo-release), which you can install by running `cargo install cargo-release`. Steps were tested with cargo-release 0.21.4.
- Some way to sign tags. Rain uses and recommends [gitsign](https://github.com/sigstore/gitsign), which uses your GitHub or other online identity to sign tags. Make sure to configure gitsign with:

  ```
  git config --local gpg.x509.program gitsign  # Use gitsign for signing
  git config --local gpg.format x509  # gitsign expects x509 args
  ```

(or `git config --global` to configure this for all repositories)

For a smoother experience, [set `gitsign.connectorID`](https://github.com/sigstore/gitsign#file-config) to the OAuth path you're using.

## Overview

The nextest workspace consists of a set of crates, each independently versioned. Releases are managed in a somewhat distributed way, with most of the process being managed by GitHub Actions runners.

## I. Prepare releases

1. First, check out the local branch `main` and fetch/rebase to `origin/main`.
2. Determine which crates need to be released and their version numbers. Most of the time this will just be nextest-runner and cargo-nextest, though if there are changes to other crates they'll need to be released as well.
   - For `nextest-runner`, always update the minor version number (0.27.0 to 0.28.0).
   - For `cargo-nextest`, always update the patch version number (0.9.38 to 0.9.39).
   - For other crates, look at the changes that were made. Keep in mind that `nextest-metadata` has a [minimum supported cargo-nextest version](https://nexte.st/docs/stability#nextest-metadata). If metadata generated by older versions of cargo-nextest can't be read by nextest-metadata, it's considered a breaking change.
3. Prepare changelogs. Every crate MUST have a changelog in the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format, updated to the latest version. If unreleased changelogs have been maintained, this can be as simple as adding a version header.

(Don't bump the version in `Cargo.toml` -- this will be done in the step below.)

## II. Create and push tags

We're going to now use `cargo-release` to create and push tags for each changed crate.

For each changed crate, in topological order (internal dependencies like `nextest-filtering` first, `cargo-nextest` last), run:

```
cargo release -p <crate-name> <version>
```

For example, `cargo release -p nextest-runner 0.28.0`. This will perform a dry run.

If everything looks good, run the same command with `--execute`. This will do a few things:

1. Create a commit with a version bump, e.g. `[nextest-runner] version 0.28.0`.
2. Create a signed tag pointing to this commit, e.g. `nextest-runner-0.28.0`.
3. Push this commit and this tag to the remote (default `origin`).

To customize the remote that https://github.com/nextest-rs/nextest is at, use `--push-remote`.

The [GitHub Actions `release.yml` workflow](../.github/workflows/release.yml) will then pick up the tag, and will create a GitHub release corresponding to the tag. Additionally, for `cargo-nextest`, the workflow will also kick off binary builds.

Once that is completed (and for cargo-nextest, binary builds have finished and release metadata has been pushed), the crates will automatically be published to crates.io.

> Note: there are some issues with races and spurious network failures that happen sometimes. If it looks like an intermittent failure, feel free to retry the GitHub Actions job. The steps are meant to be idempotent.
