# chamoji next-version

> Print the next semver version from the commits since the last release tag, or exit 3 when no release is needed.

Source: https://www.chamoji.dev/docs/commands/next-version

Print the next version, worked out from the commits since the last release tag. It doesn’t check the branch or touch your files, and in a single package it doesn’t fetch. When no commit calls for a release, it prints nothing to stdout and exits 3.

[MONOREPO-AWARE] [EXIT 3 FOR SCRIPTS]

> **Note:** In a single package with no release tag yet, it counts from 0.0.0, so a ✨
> commit gives 0.1.0. But a bare `chamoji release` won’t guess a first version:
> run `chamoji release 0.1.0`.

## What it does, in order

1. **Finds the last release.** The newest release tag in the history of `HEAD`, or of the ref you give with `--to`.
2. **Reads the commits since.** Each gitmoji has a bump: ✨ is minor, 🐛 is patch, 💥 is major. A breaking change is always major. The largest one wins.
3. **Prints the version.** Without a `v`, such as `0.2.0`, and exits 0. When no commit implies a bump, as with only docs, tests or refactors, it says so on stderr and exits 3.

In a repo with release units, it does this for each unit, with the unit’s own tags and commits, and prints one line per unit. A unit with no tag of its own gets its `firstVersion` when that’s set, or else the version in its manifest, or a date version for a `calver` unit. Settings such as `zeroMajor` and a unit’s `versioning` change how its version moves; [Config](https://www.chamoji.dev/docs/reference/config.md) has them.

With release units it needs the full history. In a shallow clone, such as the one GitHub Actions’ checkout makes by default, it first fetches every commit and tag from `origin`, and exits 2 when it can’t. In CI, check out with `fetch-depth: 0`.

## Arguments

`chamoji next-version` takes no arguments.

## Flags

| Name | Type | Description |
| --- | --- | --- |
| `--to <ref>` | string · default HEAD | Work out the version as of this ref instead of `HEAD`. Only in a repo without release units; with units it’s ignored. |
| `--config <file>` | string · default chamoji.config.json | Read this config file instead, from a path relative to the current folder. Without it, chamoji reads `chamoji.config.json` in the current folder, not at the repo root, so run chamoji from the root. A file that doesn’t exist exits 1. |
| `--ai` | boolean | Sort the commits no rule can place with Jev first, so their bumps count. It sends only unreleased commits. Needs `TYPESAFE_API_KEY`, or it exits 1. |
| `--unit <name>` | string · repeatable · monorepos | Only these units. Repeat it for several. Only in a repo with release units; elsewhere it exits 1. An unknown unit exits 1 and lists the units. (since 0.13.0) |
| `--json` | boolean · monorepos | Print each unit as JSON: its name, next version (`null` when it has nothing to release), and how many of its own and shared changes are waiting. Works with `--unit`. Only in a repo with release units; elsewhere it’s ignored and the version prints as usual. (since 0.13.0) |
| `--no-update-check` | boolean | Don’t check npm for a newer chamoji. See [the update notice](https://www.chamoji.dev/docs/install.md#the-update-notice). |

## Common combinations

- `chamoji next-version`: The next version, or exit 3 when there’s nothing to release.
- `chamoji next-version --to v1.4.0`: What the version would have been at an older ref.
- `chamoji next-version --json`: Every unit’s next version, and what is waiting, for CI or an agent.
- `chamoji next-version --unit web`: One unit in a monorepo.

In a release script, exit 3 stops the chain before anything is written:

```bash
version=$(chamoji next-version) && chamoji changelog --release "$version" -o CHANGELOG.md
```

## Output

These are from real runs. In widgets, a single package with a ✨ and a 🐛 since `v0.1.0`:

```txt title="chamoji next-version"
0.2.0
```

After a release, with only a 📝 commit since, it exits 3:

```txt title="chamoji next-version"
chamoji: no release needed (no commits since the last tag imply a version bump)
```

In `shop`, whose two apps release on their own. `web` has a fix since `web/v1.2.0`, and `mobile` has no tag yet, so it takes the version in its `package.json`:

```txt title="chamoji next-version"
mobile: 1.0.0
web: 1.2.1
```

```txt title="chamoji next-version --json"
{
  "units": [
    {
      "unit": "mobile",
      "version": "1.0.0",
      "own": 2,
      "shared": 2
    },
    {
      "unit": "web",
      "version": "1.2.1",
      "own": 1,
      "shared": 1
    }
  ]
}
```

When no unit would release, each line says why, and it exits 3:

```txt title="chamoji next-version"
mobile: nothing to release
web: no release needed (1 change of its own doesn't need one)
```

In a repo with two or more apps under `apps/` and no `release` section, the first run in each clone suggests setup, on stderr:

```txt title="chamoji next-version"
chamoji: this looks like a monorepo with several apps; run chamoji setup to version each one
0.1.0
```

## Exit codes

| Name | Type | Description |
| --- | --- | --- |
| `0` | | It printed a version. In a monorepo, at least one unit would release. |
| `3` | | No commit since the last tag implies a bump. In a monorepo, no unit would release. |
| `2` | | In a monorepo, a shallow clone it couldn’t unshallow, or a version file it can’t set, such as a `versionFiles` entry that is missing or a symlink. Also for a `release` section from a newer chamoji. |
| `1` | | Anything else, such as `--unit` in a repo without release units, or a missing config file. |

[Exit codes](https://www.chamoji.dev/docs/reference/exit-codes.md) has every command’s codes.

## Related

- [How commits are read](https://www.chamoji.dev/docs/reference/how-commits-are-read.md): Which commits imply which bump.
- [release](https://www.chamoji.dev/docs/commands/release.md): Cut the release next-version describes.
- [Monorepos](https://www.chamoji.dev/docs/guides/monorepos.md): Versions per unit, and the changes that ride along.
- [Exit codes](https://www.chamoji.dev/docs/reference/exit-codes.md): Using exit 3 in scripts and CI.
