Versioce
This is a mix task to bump version of your project. Versioce includes batteries that are customizable for your liking. It is heavily inspired by bumpversion.
Quick links
Installation
The package can be installed by adding versioce
to your list of dependencies in mix.exs
:
def deps do
[
{:versioce, "~> 2.0.0"}
]
end
Migrating from older versions
Major versions bring braking changes or deprecations. For migration instructions see Migrations doc
Usage
Configure the files
You should let Versioce
know what files you want your version bumped in.
By default only the files README.md
and mix.exs
are used.
You can add additional files to this list in the config
config :versioce,
files: [
"README.md",
"docker/Dockerfile"
]
Note: All file paths should be relative to the
mix.exs
file.mix.exs
will always be used and bumped as it is the core file, from whichversioce
will pick your current version. This was done in order to remove any additional config files (ex..bumpversion.cfg
in bumpversion).
Configure Hooks
Versioce
is agnostic of your VCS(although has hooks for git) or other things you need to do.
Some people want to generate changelogs, some - automatically notify teammates
at slack, publish package to hex, etc.
To make it possible - Versioce
has Hooks. There are pre
hooks and post
hooks.
Hook is a list of simple elixir modules that have run
function in them.
Check other available configurations in config docs
Pre hooks
Are fired before any of the bumping is done.
Check available built-in pre hooks
They receive all the parameters for the bump
task as a list of strings.
Which they can use for their side-effects. But they are required to return
this list.
The result of the first hook will be piped into the next one.
defmodule MyProj.Versioce.PreHook do
use Versioce.PreHook
def run(params) do
IO.inspect(params)
{:ok, params}
end
end
And in your config:
config :versioce,
pre_hooks: [MyProj.Versioce.PreHook],
After that:
> mix bump.version
0.1.0
> mix bump patch
Running pre-hooks: [MyProj.Versioce.PreHook]
["patch"]
Bumping version from 0.1.0:
0.1.1
Running post-hooks: []
Done.
Post hooks
Work the same as pre hooks. The only differences are:
- They are fired after all the version bumping
- Their
run
function receives aversion
which was bumped to instead of params.
Check available built-in post hooks
defmodule MyProj.Versioce.PostHook do
use Versioce.PostHook
def run(version) do
IO.inspect(version)
{:ok, version}
end
end
And in your config:
config :versioce,
post_hooks: [MyProj.Versioce.PostHook],
After that:
> mix bump.version
0.1.0
> mix bump patch
Running pre-hooks: []
Bumping version from 0.1.0:
0.1.1
Running post-hooks: [MyProj.Versioce.PostHook]
"0.1.1"
Done.
Bump your versions!
Simply run mix bump
with the preferred binding or a ready version.
> mix bump.version
0.1.0
> mix bump patch
Running pre-hooks: []
Bumping version from 0.1.0:
0.1.1
Running post-hooks: []
Done.
> mix bump major
Running pre-hooks: []
Bumping version 0.1.1:
1.0.0
Running post-hooks: []
Done.
> mix bump 2.0.2
Running pre-hooks: []
Bumping version from 1.1.1:
2.0.2
Running post-hooks: []
Done.
You can also add pre-release or build information easily with --pre
or --build
> mix bump.version
0.1.0
> mix bump --pre alpha.3
Running pre-hooks: []
Bumping version from 0.1.0:
0.1.1-alpha.3
Running post-hooks: []
Done.
> mix bump --build 20210101011700.amd64
Running pre-hooks: []
Bumping version from 0.1.1-alpha.3:
0.1.1-alpha.3+20210101011700.amd64
Running post-hooks: []
Done.
CalVer
Versioce has a limited support for CalVer.
Be aware that it is supported lazily, ie. if you start using regular semantic versioning you will need to make a bump to a specific sematic version first, otherwise Versioce will bump your calver version like it is a semantic one. This is probably not what you want.
CalVer also currently does not support --pre
and --build
params, they will be ignored.
For the available formats of the calver consult the config docs
> mix bump.version
0.1.0
> mix bump calver
Running pre-hooks: []
Bumping version from 0.1.0:
2022.11.28
Running post-hooks: []
Done.
Changelog generation
Versioce has the functionality to generate changelogs. By default it produces a changlog in the Keepachangelog format from your Git history, but both can be configured:
config :versioce, :changelog,
datagrabber: Versioce.Changelog.DataGrabber.Git, # Or your own datagrabber module
formatter: Versioce.Changelog.Formatter.Keepachangelog # Or your own formatter module
Make sure to set the proper anchors configuration according to your repository policies, so Versioce can place entries in the proper sections:
config :versioce, :changelog,
anchors:
%{
added: ["[ADD]"],
changed: ["[IMP]"],
deprecated: ["[DEP]"],
removed: ["[REM]"],
fixed: ["[FIXED]"],
security: ["[SEC]"]
}
Anchors definition should follow the
Versioce.Changelog.Anchors
struct format. As it will be converted to it down the line.
And you're all set!
Now you can either run a mix changelog
task to generate a changelog file
or add Versioce.PostHooks.Changelog
post hook in your configuration:
config :versioce,
post_hooks: [Versioce.PostHooks.Changelog],
Important: If you want to use this hook in combination with
Versioce.PostHooks.Git.Release
, make sure that changelog is before the release hook, as well as eitherVersioce.Config.Git.dirty_add/0
is enabled or your changelog file is added toVersioce.Config.Git.additional_files/0
Make sure to check other configurations for the changelog generation inVersioce.Config.Changelog
The name
The name Versioce
is a play on Italian brand Versace with a word version.
It obviously has no connection to it.
I obviously lack any creativity or imagination.
Similar projects
- https://github.com/glasnoster/eliver
- https://github.com/oo6/mix-bump
- https://github.com/zachdaniel/git_ops
Some acknowledgments
A huge inspiration for this project was Elixir conf talk by Jeremy Searls
Which I highly recommend you to watch