---
editLink: true
---

# Automatic versioning

The purpose of conventional commits is to be able to bump your project version and changelog
automatically. Cocogitto allow you to do this with the `cog bump` command.

The `bump` subcommand will execute the following steps:

1. Calculate the next version based on the commit types since the latest tag.
2. Execute a set configuration defined pre-bump hooks.
3. Append the changes for this version to `CHANGELOG.md`.
4. Create a version commit containing changes made during the previous steps.
5. Create a git tag on the version commit.
6. Execute a set of configuration defined post-bump hook.

## Auto bump

`cog bump` will calculate the next version based on your commit history since the latest
semver tag. Once a tag number has been calculated it will create a tagged commit containing
the changelog for this new tag.

### Auto bump commit types
By default, only the following commit types will trigger the following auto bumps.

```
fix: a commit of the type fix patches a bug in your codebase (this correlates with PATCH in Semantic Versioning).
feat: a commit of the type feat introduces a new feature to the codebase (this correlates with MINOR in Semantic Versioning).
BREAKING CHANGE: a commit that has a footer BREAKING CHANGE:, or appends a ! after the type/scope, introduces a breaking API change (correlating with MAJOR in Semantic Versioning). A BREAKING CHANGE can be part of commits of any type.
```

If you want to change this or include other types you can update that in [commit_types] in cog.toml.

### Example

Assuming we are working on the following git repository:

```git
* 8e08b78 - (HEAD -> master) feat: another cool feature <Paul Delafosse>
* 490b846 - docs: add some documentation <Paul Delafosse>
* 8bc0d28 - fix: fix a ugly bug <Paul Delafosse>
* a0c9050 - feat: add awesome feature <Paul Delafosse>
* 6d014b4 - chore: initial commit <Paul Delafosse>
```

Let us now create a version:

```bash
❯ cog bump --auto
Warning: using 'cog bump' with the default configuration.
You may want to create a 'cog.toml' file in your project root to configure bumps.

Failed to get current version, falling back to 0.0.0
Skipping irrelevant commits:
	- docs: 1

Found feature commit 8e08b7
Found bug fix commit 8bc0d2
Found feature commit a0c905
Bumped version: ... -> 0.1.0
```

If we look again at our git log:

```git
* 76c0ffd - (HEAD -> master, tag: 0.1.0) chore(version): 0.1.0 (2 minutes ago) <Paul Delafosse>
...
```

Also, a `CHANGELOG.md` file have been created using the `default` template:

```markdown
# Changelog

All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.

---

## 0.1.0 - 2021-11-11

#### Bug Fixes

- fix a ugly bug - (8bc0d28) - Paul Delafosse

#### Documentation

- add some documentation - (490b846) - Paul Delafosse

#### Features

- another cool feature - (8e08b78) - Paul Delafosse
- add awesome feature - (a0c9050) - Paul Delafosse

---

Changelog generated by [cocogitto](https://github.com/cocogitto/cocogitto).
```

Also see [template config](/reference/config) if you need to change the default changelog template.

::: tip
Sometimes getting a version number automatically is not what you want.
Cocogitto let you specify the target version with the following flags:

- `--auto`: choose the next version for you (based on feature commit, bug fixes commit and BREAKING_CHANGE commit).
- `--major`: increment the MAJOR version.
- `--minor`: increment the MINOR version.
- `--patch`: increment the PATCH version.
- `--version <version>`: set version manually ( ex: `cog bump --version 3.2.1`).
- `--pre <metadata>`: set the [pre-release metadata](https://semver.org/#spec-item-9).
- `--build <metadata>`: set the [build metadata](https://semver.org/#spec-item-10).

**Example:**

```bash
cog bump --major --pre "beta.1" --build "foo.bar"
# 1.2.3 -> 2.0.0-beta.1+foo.bar
```

:::

**Note:** `cog bump --auto` treats `0.y.z` versions specially,
i.e. it will never do an auto bump to the `1.0.0` version, even if there are breaking changes.
That way, you can keep adding features in the development stage and decide yourself, when your API is stable.

#### Dry run

If you just need to get the next version number without performing the automatic bump use the `--dry-run` flag:

```shell
cog bump --dry-run --auto
```

:::tip
The `dry-run` flag can be helpful when writing shell scripts using cocogitto. Since only the version number will
output to stdout so you can do the following:

```shell
VERSION=$(cog bump --dry-run --auto) # -> VERSION=1.0.0
```

:::

## Bump hooks

### Pre bump hooks

Creating git tag automatically is great, but sometimes you need to edit some file with the new version number,
or perform some additional checks before doing so.

A typical example is editing your project manifest in your package manager configuration file.
You can run pre bump commands with the `latest` and `version` aliases to reference respectively
the latest known version and the target version.

In case you are first setting out your project and you don't have a version yet, you can define a default value for the aliases.
This can be simply done by adding a default value to the alias like: <code v-pre>{{version|0.0.0}}</code>.
The same can be done for any of the version aliases.

**Example:**

When adding the following hooks to `cog.toml`, the hook commands will be run before creating the version commit:

```toml
# cog.toml
pre_bump_hooks = [
    "cargo build --release",
    "echo 'bumping from {{latest|0.0.0}} to {{version|0.0.1}}'",
    "cargo bump {{version|0.0.1}}",
]
```

And result in the following bump:

```bash
❯ cog bump --auto
Skipping irrelevant commits:

Found feature commit 9055d9
   Compiling my_awesome_repo v0.1.0 (/home/okno/_Workshop/MyRepos/my_awesome_repo)
    Finished release [optimized] target(s) in 0.86s
bump from 0.1.0 to 0.2.0
Bumped version: 0.1.0 -> 0.2.0
```

::: tip
If any of the pre-bump command fails cocogitto will abort the bump.
Any changes made to the repository during the pre-bump phase will be stashed under <code v-pre>cog_bump_{{version}}</code>.

**Example:**

cog.toml:

```toml
pre_bump_hooks = [
  "cargo build --release",
  "echo 'bump from {{latest}} to {{version}}'",
  "exit 1" # Fail on purpose here
]
```

run:

```bash
❯ cog bump --auto
Skipping irrelevant commits:

Found bug fix commit a0de11
   Compiling my_awesome_repo v0.2.0 (/home/okno/_Workshop/MyRepos/my_awesome_repo)
    Finished release [optimized] target(s) in 0.22s
bump from 0.2.0 to 0.2.1
Error: prehook run `exit 1` failed
	All changes made during hook runs have been stashed on `cog_bump_0.2.1`
	you can run `git stash apply stash@0` to restore these changes.
```

:::

### Post bump hooks

Post-bump hooks works exactly like pre-bump hooks. They are run after the version has been created
and are typically used to push changes to the remote, publish packages and apply branching model strategies.

```toml
# cog.toml
post_bump_hooks = [
    "git push",
    "git push origin {{version}}",
    "cargo publish"
]
```

::: danger
There is no rollback procedure for post-bump hook, on failure cog will abort and leave the repository
in an undefined state.
We are working on allowing user to define their rollback procedures, but it is not there yet.
:::

### Version DSL

It is common to bump your development branch version package manifest after creating a new release.
A typical example in the java world would be to bump your maven snapshot on your development branch after a release.

```toml
# cog.toml
post_bump_hooks = [
    "git push",
    "git push origin {{version|1.0.0}}",
    "git checkout develop",
    "git rebase master",
    "mvn versions:set -DnewVersion={{version|1.0.0+minor-SNAPSHOT}}",
    "cog commit chore \"bump snapshot to {{version|1.0.0+1minor-SNAPSHOT}}\"",
    "git push",
]
```

As you can see we are bumping the manifest using a small DSL. It only has a few keywords:

- start with the one of `version`,`version_tag`, `latest`, `latest_tag` or `package` keyword.
- followed by an optional default value (example above: `|1.0.0`) in SemVer format in case the value for the keyword is not available - the default cannot be used with the package keyword.
- followed by the `+` operator.
- `major`, `minor` and `patch` to specify the kind of increment you want.
  Then an optional amount, default being one (`version+1minor` and `version+minor` being the same).
- followed by any number of `+{amount}{kind}` (example: `version+2major+1patch`)
- ended by any alphanumeric character (SemVer additional labels for pre-release and build metadata), here `-SNAPSHOT`.

### Bump profiles

For some branching model or release cadence you might want to bump your versions with
different hooks.

To do so you can define alternate profile hooks in `cog.toml`:

```toml
[bump_profiles.hotfix]
pre_bump_hooks = [
  # Ensure we are performing a bump from the latest release branch
  """
    [[ "$(git rev-parse --abbrev-ref HEAD)" == "release/{{latest}}" ]] && echo "On branch release/{{latest}}" || exit 1
    """,
]

post_bump_hooks = []
```

Once your custom hook profile is set you can call it with the `--hook-profile` flag:

```bash
❯ cog bump -H hotfix --auto
Skipping irrelevant commits:

Found feature commit 5b21b3
Found bug fix commit a0de11
[[ $(git rev-parse --abbrev-ref HEAD) == release/0.2.0 ]] && echo On branch release/0.2.0 || exit 1
On branch release/0.2.0
Bumped version: 0.2.0 -> 0.3.0
```

Note that for the sake of readability in this documentation, the above example use a oneliner
to check the current branch, but you would probably want to can a shell script instead:

```toml
pre_bump_hooks = [
  """
    sh -c "./check_branch.sh"
    """,
]
```

## Branch whitelist

It is a common practice to bump always from the same set of branches. For instance, you might want to allow bumping only
on branch `main` and branches prefixed with `release/`.

To do so add the following to your `cog.toml`:

```toml
branch_whitelist = [
  "main",
  "release/**"
]
```
