Skip to content

feat: improve changelog defaults #866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions semantic_release/commit_parser/angular.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,16 @@ def _logged_parse_error(commit: Commit, error: str) -> ParseError:

# types with long names in changelog
LONG_TYPE_NAMES = {
"feat": "feature",
"build": "build system",
"ci": "continuous integration",
"chore": "chores",
"docs": "documentation",
"perf": "performance",
"feat": "features",
"fix": "fixes",
"perf": "performance improvements",
"refactor": "refactoring",
"style": "code style",
"test": "tests",
}


Expand Down Expand Up @@ -82,7 +89,7 @@ def __init__(self, options: AngularParserOptions | None = None) -> None:
def get_default_options() -> AngularParserOptions:
return AngularParserOptions()

# Maybe this can be cached as an optimisation, similar to how
# Maybe this can be cached as an optimization, similar to how
# mypy/pytest use their own caching directories, for very large commit
# histories?
# The problem is the cache likely won't be present in CI environments
Expand Down
33 changes: 33 additions & 0 deletions semantic_release/data/templates/.macros/commit_msg_links.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{# MACRO: commit message links or PR/MR links of commit
@param commit: Commit object
@return: Commit message with PR/MR or commit hash links embedded
#}
{% macro commit_msg_links(commit)
%}{% set description = commit.descriptions[0] | capitalize
%}{#
# Replace PR references in the form of (!123) with a link to the PR
#}{% if description.split("(!") | length > 1
%}{% set pr_num = description.split("(!")[1].split(")")[0]
%}{% set replacement = "([!%s](%s))" | format(pr_num, pr_num | pull_request_url)
%}{% set description = description | replace("(!" ~ pr_num ~ ")", replacement)
%}{#
# Replace PR references in the form of (#123) with a link to the PR
#}{% elif description.split("(#") | length > 1
%}{% set pr_num = description.split("(#")[1].split(")")[0]
%}{% set replacement = "([#%s](%s))" | format(pr_num, pr_num | pull_request_url)
%}{% set description = description | replace("(#" ~ pr_num ~ ")", replacement)
%}{#
# DEFAULT: Append commit hash as url to the commit description
#}{% else
%}{% set description = "%s ([`%s`](%s))" | format(
description,
commit.short_hash,
commit.hexsha | commit_hash_url
)
%}{% endif
%}{#
# Return the modified description
#}{{ description

}}{% endmacro
%}
17 changes: 17 additions & 0 deletions semantic_release/data/templates/.macros/headings.angular.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% set heading_to_emoji_map = {
'breaking': '💥',
'feature': '✨',
'fix': '🪲',
'performance': '⚡',
'refactor': '♻️',
'chore': '🧹',
'documentation': '📖',
'test': '✅',
'ci': '🤖',
'style': '🎨',
'build system': '⚙️',
'unknown': '❗',
} %}

{# The ordered list of which headings to display in order #}
{% set section_headings = heading_to_emoji_map.keys() %}
24 changes: 24 additions & 0 deletions semantic_release/data/templates/.macros/headings.emoji.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{# The ordered list of which headings to display in order #}
{% set section_headings = [
':boom:',
':sparkles:',
":children_crossing:",
":lipstick:",
":iphone:",
":egg:",
":chart_with_upwards_trend:",
":ambulance:",
":lock:",
":bug:",
":zap:",
":goal_net:",
":alien:",
":wheelchair:",
":speech_balloon:",
":mag:",
":apple:",
":penguin:",
":checkered_flag:",
":robot:",
":green_apple:",
] %}
17 changes: 17 additions & 0 deletions semantic_release/data/templates/.macros/headings.scipy.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% set heading_to_emoji_map = {
'breaking': '💥',
'feature': '✨',
'fix': '🪲',
'performance': '⚡',
'refactor': '♻️',
'chore': '🧹',
'documentation': '📖',
'test': '✅',
'ci': '🤖',
'style': '🎨',
'build system': '⚙️',
'unknown': '❗',
} %}

{# The ordered list of which headings to display in order #}
{% set section_headings = heading_to_emoji_map.keys() %}
18 changes: 18 additions & 0 deletions semantic_release/data/templates/.macros/headings.tag.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

{% set heading_to_emoji_map = {
'breaking': '💥',
'feature': '✨',
'fix': '🪲',
'performance': '⚡',
'refactor': '♻️',
'chore': '🧹',
'documentation': '📖',
'test': '✅',
'ci': '🤖',
'style': '🎨',
'build system': '⚙️',
'unknown': '❗',
} %}

{# The ordered list of which headings to display in order #}
{% set section_headings = heading_to_emoji_map.keys() %}
77 changes: 77 additions & 0 deletions semantic_release/data/templates/CHANGELOG.angular.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# CHANGELOG
{#
#}{% from '.macros/commit_msg_links.j2' import commit_msg_links
%}{% from '.macros/headings.angular.j2' import section_headings

%}{% if context.history.unreleased | length > 0
%}{{
"\n## Unreleased\n"

}}{% for type_ in section_headings if type_ in context.history.unreleased
%}{{
"\n### %s\n" | format(type_ | capitalize)

}}{% for commit in context.history.unreleased[type_] | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(commit.scope, commit_msg_links(commit) )

}}{% endfor
%}{% for commit in context.history.unreleased[type_] | rejectattr("scope") | sort(attribute='descriptions.0')
%}{{
"\n- %s\n" | format(commit_msg_links(commit))

}}{% endfor
%}{% endfor
%}{{ "\n"
}}{% endif
%}{#

RELEASED

#}{% for version, release in context.history.released.items()
%}{{
"\n## %s (%s)\n" | format(
version.as_semver_tag(),
release.tagged_date.strftime("%Y-%m-%d")
)

}}{% for type_ in section_headings if type_ in release["elements"]
%}{{
"\n### %s\n" | format(type_ | capitalize)

}}{% for commit in release["elements"][type_] | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(commit.scope, commit_msg_links(commit) )

}}{% endfor
%}{% for commit in release["elements"][type_] | rejectattr("scope") | sort(attribute='descriptions.0')
%}{{
"\n- %s\n" | format(commit_msg_links(commit))

}}{% endfor
%}{% endfor
%}{#

#}{% if "breaking" in release["elements"]
%}{{
"\n### BREAKING CHANGES\n"
}}{#
#}{% set breaking_commits = release["elements"]["breaking"] | selectattr("breaking_descriptions")
%}{% for commit in breaking_commits | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(
commit.scope,
commit.breaking_descriptions | join("\n\n") | indent(4) | capitalize
)

}}{% endfor
%}{% for commit in breaking_commits | rejectattr("scope") | sort(attribute='breaking_descriptions.0')
%}{{
"\n- %s\n" | format(
commit.breaking_descriptions | join("\n\n") | indent(4) | capitalize
)

}}{% endfor
%}{% endif
%}{% endfor
%}
77 changes: 77 additions & 0 deletions semantic_release/data/templates/CHANGELOG.emoji.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# CHANGELOG
{#
#}{% from '.macros/commit_msg_links.j2' import commit_msg_links
%}{% from '.macros/headings.emoji.j2' import section_headings

%}{% if context.history.unreleased | length > 0
%}{{
"\n## Unreleased\n"

}}{% for type_ in section_headings if type_ in context.history.unreleased
%}{{
"\n### %s\n" | format(type_ | capitalize)

}}{% for commit in context.history.unreleased[type_] | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(commit.scope, commit_msg_links(commit) )

}}{% endfor
%}{% for commit in context.history.unreleased[type_] | rejectattr("scope") | sort(attribute='descriptions.0')
%}{{
"\n- %s\n" | format(commit_msg_links(commit))

}}{% endfor
%}{% endfor
%}{{ "\n"
}}{% endif
%}{#

RELEASED

#}{% for version, release in context.history.released.items()
%}{{
"\n## %s (%s)\n" | format(
version.as_semver_tag(),
release.tagged_date.strftime("%Y-%m-%d")
)

}}{% for type_ in section_headings if type_ in release["elements"]
%}{{
"\n### %s\n" | format(type_ | capitalize)

}}{% for commit in release["elements"][type_] | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(commit.scope, commit_msg_links(commit) )

}}{% endfor
%}{% for commit in release["elements"][type_] | rejectattr("scope") | sort(attribute='descriptions.0')
%}{{
"\n- %s\n" | format(commit_msg_links(commit))

}}{% endfor
%}{% endfor
%}{#

#}{% if "breaking" in release["elements"]
%}{{
"\n### BREAKING CHANGES\n"
}}{#
#}{% set breaking_commits = release["elements"]["breaking"] | selectattr("breaking_descriptions")
%}{% for commit in breaking_commits | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(
commit.scope,
commit.breaking_descriptions | join("\n\n") | indent(4) | capitalize
)

}}{% endfor
%}{% for commit in breaking_commits | rejectattr("scope") | sort(attribute='breaking_descriptions.0')
%}{{
"\n- %s\n" | format(
commit.breaking_descriptions | join("\n\n") | indent(4) | capitalize
)

}}{% endfor
%}{% endif
%}{% endfor
%}
77 changes: 77 additions & 0 deletions semantic_release/data/templates/CHANGELOG.scipy.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# CHANGELOG
{#
#}{% from '.macros/commit_msg_links.j2' import commit_msg_links
%}{% from '.macros/headings.scipy.j2' import section_headings

%}{% if context.history.unreleased | length > 0
%}{{
"\n## Unreleased\n"

}}{% for type_ in section_headings if type_ in context.history.unreleased
%}{{
"\n### %s\n" | format(type_ | capitalize)

}}{% for commit in context.history.unreleased[type_] | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(commit.scope, commit_msg_links(commit) )

}}{% endfor
%}{% for commit in context.history.unreleased[type_] | rejectattr("scope") | sort(attribute='descriptions.0')
%}{{
"\n- %s\n" | format(commit_msg_links(commit))

}}{% endfor
%}{% endfor
%}{{ "\n"
}}{% endif
%}{#

RELEASED

#}{% for version, release in context.history.released.items()
%}{{
"\n## %s (%s)\n" | format(
version.as_semver_tag(),
release.tagged_date.strftime("%Y-%m-%d")
)

}}{% for type_ in section_headings if type_ in release["elements"]
%}{{
"\n### %s\n" | format(type_ | capitalize)

}}{% for commit in release["elements"][type_] | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(commit.scope, commit_msg_links(commit) )

}}{% endfor
%}{% for commit in release["elements"][type_] | rejectattr("scope") | sort(attribute='descriptions.0')
%}{{
"\n- %s\n" | format(commit_msg_links(commit))

}}{% endfor
%}{% endfor
%}{#

#}{% if "breaking" in release["elements"]
%}{{
"\n### BREAKING CHANGES\n"
}}{#
#}{% set breaking_commits = release["elements"]["breaking"] | selectattr("breaking_descriptions")
%}{% for commit in breaking_commits | selectattr("scope") | sort(attribute='scope')
%}{{
"\n- **%s**: %s\n" | format(
commit.scope,
commit.breaking_descriptions | join("\n\n") | indent(4) | capitalize
)

}}{% endfor
%}{% for commit in breaking_commits | rejectattr("scope") | sort(attribute='breaking_descriptions.0')
%}{{
"\n- %s\n" | format(
commit.breaking_descriptions | join("\n\n") | indent(4) | capitalize
)

}}{% endfor
%}{% endif
%}{% endfor
%}
Loading
Loading