GitOps

Hex pmHex DocsTotal DownloadLicense

A small tool to help generate changelogs from conventional commit messages. For more information, see conventional commits. For an example, see this project's CHANGELOG.md.

Roadmap (in no particular order):

Important addendums:

A new version of the spec in beta adds a rather useful convention. Add ! after the type/scope to simply signal it as a breaking change, instead of adding BREAKING CHANGE: description in your commit message. For example: fix(Spline Reticulator)!:

The spec doesn't specify behavior around multiple scopes. This library parses scopes as a comma separated list. This allows for easily readable multiple word lists feat(Something Special, Something Else Special): message. Keep in mind that you are very limited on space in these messages, and if you find yourself using multiple scopes your commit is probably too big.

Installation with Igniter

If Igniter is not already in your project, add it to your deps:

def deps do
[
{:igniter, "~> 0.5", only: [:dev, :test]}
]
end

Then, run the installer:

mix igniter.install git_ops

Manual Installation

def deps do
[
{:git_ops, "~> 2.6.1", only: [:dev]}
]
end

Configuration

config :git_ops,
mix_project: Mix.Project.get!(),
changelog_file: "CHANGELOG.md",
# if set to true, this uses git user.email to lookup user on github and insert the handle in release notes
# otherwise it uses the author name as provided in the commit
github_handle_lookup?: true,
github_api_base_url: "https://api.github.com",
repository_url: "https://github.com/my_user/my_repo",
types: [
# Makes an allowed commit type called `tidbit` that is not
# shown in the changelog
tidbit: [
hidden?: true
],
# Makes an allowed commit type called `important` that gets
# a section in the changelog with the header "Important Changes"
important: [
header: "Important Changes"
]
],
tags: [
# Only add commits to the changelog that has the "backend" tag
allowed: ["backend"],
# Filter out or not commits that don't contain tags
allow_untagged?: true
],
# Instructs the tool to manage your mix version in your `mix.exs` file
# See below for more information
manage_mix_version?: true,
# Instructs the tool to manage the version in your README.md
# Pass in `true` to use `"README.md"` or a string to customize
manage_readme_version: "README.md",
# Manage an arbitrary list of files during release.
# See "Managing additional files" below for details.
managed_files: [
{"apps/my_app/mix.exs", :mix},
{"README.md", :string}
],
version_tag_prefix: "v",
# Where the current version is read from:
# :mix (default) reads the configured mix_project's version,
# :tags reads the last valid version tag, and
# {:file, path, regex} reads the regex's first capture group from path.
# :tags and {:file, ...} need no mix project, enabling non-Elixir projects.
version_source: :mix

Configuration with git_ops.json

A git_ops.json file at the repository root takes precedence over the application environment, and is how repositories without a mix project — or with more than one package — configure git_ops. With a config file the current version is read from tags by default (version_source: "tags"), so no mix project is required.

{
"repository_url": "https://github.com/my_user/my_repo",
"types": {"docs": {"hidden": true}, "important": {"header": "Important Changes"}},
"version_tag_prefix": "v",
"managed_files": [{"path": "package.json", "type": "json"}]
}

managed_files entries take a type ("mix", "json" for a "version": "..." field, "raw" for a file whose whole content is the version, or "string") or a custom "pattern" template in which {version} is replaced.

Monorepos and pull-request releases

A packages map in git_ops.json releases each directory independently — its own <name>-v tags, changelog, and managed files — and "release_strategy": "pull_request" proposes releases as pull requests whose merge is the release (with mix git_ops.tag_merged reconciling tags and GitHub releases afterwards). See the Monorepos guide.

Getting started:

mix git_ops.release --initial

Commit the result of that, using a message like chore: Initial Release

Then when you want to release again, use:

mix git_ops.release

For the full documentation of that task, see the task documentation in hex.

Managing your mix version

To have mix manage your mix version, add manage_mix_version?: true to your configuration.

Then, use a module attribute called @version to manage your application's version. Look at this project's mix.exs for an example.

Managing your readme version

Most project readmes have a line like this that would ideally remain up to date:

{:git_ops, "~> 2.6.1", only: [:dev]}

You can keep that number up to date via manage_readme_version, which accepts true for README.md or a string pointing to some other path relative to your project root.

Managing additional files

For projects that need to update version strings in multiple files (e.g. poncho apps with several mix.exs files), use the managed_files option:

config :git_ops,
managed_files: [
{"apps/my_app/mix.exs", :mix},
{"apps/my_other_app/mix.exs", :mix},
{"README.md", :string},
{"package.json", fn v -> "\"version\": \"#{v}\"" end, fn v -> "\"version\": \"#{v}\"" end}
]

Each entry is a tuple describing a file and how to find/replace the version string within it:

The managed_files list is merged with any files contributed by manage_mix_version? and manage_readme_version, so you can use all three options together or migrate to managed_files entirely.

Using this with open source projects

If you'd like your contributors to use the conventional commit format, you can use a PULL_REQUEST_TEMPLATE.md like the one in our repo. However, it is also possible to manage it as the maintainers of a project by altering either the merge commit or alter the commit when merging/squashing (recommended)

Similar projects