Skip to main content

src/version_bump@plugins@release_notes.erl

-module(version_bump@plugins@release_notes).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/version_bump/plugins/release_notes.gleam").
-export([notes_for/1, plugin/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(
    " The `release-notes-generator` plugin.\n"
    "\n"
    " A port of semantic-release's `@semantic-release/release-notes-generator`.\n"
    " It implements only the `generate_notes` hook: given the parsed conventional\n"
    " commits in the context and the version of the pending release, it renders\n"
    " the Markdown release notes via the shared `notes` module.\n"
    "\n"
    " When there is no `next_release` (nothing to release) the hook returns an\n"
    " empty string, matching semantic-release where notes are only generated for a\n"
    " release that is actually happening.\n"
).

-file("src/version_bump/plugins/release_notes.gleam", 52).
?DOC(
    " The configured repository URL, threaded through to the notes renderer for\n"
    " future link generation.\n"
).
-spec repository_url(version_bump@context:context()) -> gleam@option:option(binary()).
repository_url(Context) ->
    erlang:element(2, erlang:element(4, Context)).

-file("src/version_bump/plugins/release_notes.gleam", 42).
?DOC(
    " Pure core of the hook: render the release notes for a context, or `\"\"` when\n"
    " there is no pending release. Kept separate from `generate_notes` so it can\n"
    " be unit-tested without constructing a `Result`.\n"
).
-spec notes_for(version_bump@context:context()) -> binary().
notes_for(Context) ->
    case erlang:element(9, Context) of
        none ->
            <<""/utf8>>;

        {some, Next} ->
            version_bump@note:generate(
                erlang:element(7, Context),
                erlang:element(2, Next),
                repository_url(Context)
            )
    end.

-file("src/version_bump/plugins/release_notes.gleam", 32).
?DOC(
    " `generate_notes` hook: render Markdown release notes for the pending release.\n"
    "\n"
    " `_spec` is unused — this plugin takes no options. The notes are derived\n"
    " entirely from the context's commits, the next release's version, and the\n"
    " configured repository URL.\n"
).
-spec generate_notes(
    version_bump@config:plugin_spec(),
    version_bump@context:context()
) -> {ok, binary()} | {error, version_bump@error:release_error()}.
generate_notes(_, Context) ->
    {ok, notes_for(Context)}.

-file("src/version_bump/plugins/release_notes.gleam", 23).
?DOC(
    " Build the `release-notes-generator` plugin. It implements `generate_notes`\n"
    " and leaves every other hook unset.\n"
).
-spec plugin() -> version_bump@plugin:plugin().
plugin() ->
    _record = version_bump@plugin:new(<<"release-notes-generator"/utf8>>),
    {plugin,
        erlang:element(2, _record),
        erlang:element(3, _record),
        erlang:element(4, _record),
        erlang:element(5, _record),
        {some, fun generate_notes/2},
        erlang:element(7, _record),
        erlang:element(8, _record),
        erlang:element(9, _record),
        erlang:element(10, _record),
        erlang:element(11, _record)}.