--- 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 as 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 * 490b846 - docs: add some documentation * 8bc0d28 - fix: fix a ugly bug * a0c9050 - feat: add awesome feature * 6d014b4 - chore: initial commit ``` 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) ... ``` 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 `: set version manually ( ex: `cog bump --version 3.2.1`). - `--pre `: set the [pre-release metatada](https://semver.org/#spec-item-9). - `--build `: set the [build metatada](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 scritps 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: {{version|0.0.0}}. 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 cog_bump_{{version}}. **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}` (exemple: `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/**" ] ```