Let :before_commit hooks be 2-arity functions receiving (next_vsn, token), so they can read execution state — in particular the resolved tag annotation.
Why
A changelog hook needs the annotation to pass it on to the changelog generator. Concretely, with git-cliff:
defp gen_changelog(vsn, token) do
System.cmd("git", ["cliff", "--tag", vsn, "--with-tag-message", token.annotation, "-o", "CHANGELOG.md"])
end
Without this, the hook cannot see the annotation that TagGitHead will write three stages later, so the release notes in the generated changelog and the ones in the tag message have to be maintained separately. The changelog is written during :before_commit, before the tag exists, so --with-tag-message is the only way to get the prose into the entry being cut — while a later full regeneration picks the same text back up from the annotated tag.
Implementation note
MixVersion.Stage.ApplyHook (lib/mix_version/stage/apply_hook.ex:46) currently dispatches on a bare is_function/1 guard:
defp apply_hook(f, token) when is_function(f) do
case f.(token.next_vsn) do
That clause matches a 2-arity function too and calls it with one argument, raising BadArityError. It needs splitting into is_function(f, 1) and is_function(f, 2) clauses. Both arities should keep working — a project typically mixes them, e.g. an arity-1 readmix hook alongside an arity-2 changelog hook.
Passing the whole MixVersion.Token makes opts, git_repo and hooks part of the public surface. Worth deciding deliberately; the struct is already documented as the execution state passed between stages.
Depends on #77 for the annotation to be resolved (%s substituted) by the time hooks run.
Let
:before_commithooks be 2-arity functions receiving(next_vsn, token), so they can read execution state — in particular the resolved tag annotation.Why
A changelog hook needs the annotation to pass it on to the changelog generator. Concretely, with git-cliff:
Without this, the hook cannot see the annotation that
TagGitHeadwill write three stages later, so the release notes in the generated changelog and the ones in the tag message have to be maintained separately. The changelog is written during:before_commit, before the tag exists, so--with-tag-messageis the only way to get the prose into the entry being cut — while a later full regeneration picks the same text back up from the annotated tag.Implementation note
MixVersion.Stage.ApplyHook(lib/mix_version/stage/apply_hook.ex:46) currently dispatches on a bareis_function/1guard:That clause matches a 2-arity function too and calls it with one argument, raising
BadArityError. It needs splitting intois_function(f, 1)andis_function(f, 2)clauses. Both arities should keep working — a project typically mixes them, e.g. an arity-1 readmix hook alongside an arity-2 changelog hook.Passing the whole
MixVersion.Tokenmakesopts,git_repoandhookspart of the public surface. Worth deciding deliberately; the struct is already documented as the execution state passed between stages.Depends on #77 for the annotation to be resolved (
%ssubstituted) by the time hooks run.