Skip to content
Open
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
4 changes: 4 additions & 0 deletions docs/concepts/commit_parsing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ how PSR's core features:
:ref:`changelog.exclude_commit_patterns <config-changelog-exclude_commit_patterns>`
to ignore those commit styles.

Set ``commit_parser_options.render_emoji`` to ``true`` to render the default shortcode
tags as descriptive Unicode headings, such as ``🐛 Bug Fixes``, and remove the leading
tag from each commit description.

- **Pull/Merge Request Identifier Detection**: This parser implements PSR's
:ref:`commit_parser-builtin-linked_merge_request_detection` to identify and extract
pull/merge request numbers. The parser will return a string value if a pull/merge
Expand Down
53 changes: 49 additions & 4 deletions src/semantic_release/commit_parser/emoji.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,34 @@
from semantic_release.globals import logger
from semantic_release.helpers import sort_numerically, text_reducer

DEFAULT_EMOJI_CHANGELOG_SECTIONS = {
":boom:": "💥 Breaking Changes",
":sparkles:": "✨ Features",
":children_crossing:": "🚸 User Experience",
":lipstick:": "💄 UI and Style",
":iphone:": "📱 Responsive Design",
":egg:": "🥚 Easter Eggs",
":chart_with_upwards_trend:": "📈 Analytics",
":ambulance:": "🚑 Critical Hotfixes",
":lock:": "🔒 Security",
":bug:": "🐛 Bug Fixes",
":zap:": "⚡ Performance",
":goal_net:": "🥅 Error Handling",
":alien:": "👽 External API Changes",
":wheelchair:": "♿ Accessibility",
":speech_balloon:": "💬 Text and Literals",
":mag:": "🔍 SEO",
":apple:": "🍎 macOS",
":penguin:": "🐧 Linux",
":checkered_flag:": "🏁 Windows",
":robot:": "🤖 Android",
":green_apple:": "🍏 iOS",
":checkmark:": "✅ Tests",
":construction_worker:": "👷 Continuous Integration",
":memo:": "📝 Documentation",
":recycle:": "♻️ Refactoring",
}


@dataclass
class EmojiParserOptions(ParserOptions):
Expand Down Expand Up @@ -103,6 +131,12 @@ class EmojiParserOptions(ParserOptions):
ignore_merge_commits: bool = True
"""Toggle flag for whether or not to ignore merge commits"""

render_emoji: bool = False
"""
Render default emoji tags as descriptive Unicode changelog section headings
and remove the leading tag from commit descriptions.
"""

@property
def tag_to_level(self) -> dict[str, LevelBump]:
"""A mapping of commit tags to the level bump they should result in."""
Expand Down Expand Up @@ -134,8 +168,9 @@ class EmojiCommitParser(CommitParser[ParseResult, EmojiParserOptions]):
If the message does not contain any known emojis, then the level to bump
will be 0 and the type of change "Other". This parser never raises
UnknownCommitMessageStyleError.
Emojis are not removed from the description, and will appear alongside
the commit subject in the changelog.
By default, emojis are not removed from the description and will appear
alongside the commit subject in the changelog. Set ``render_emoji`` to
render descriptive Unicode headings and omit the leading tag.
"""

# TODO: Deprecate in lieu of get_default_options()
Expand Down Expand Up @@ -289,7 +324,17 @@ def parse_message(self, message: str) -> ParsedMessageResult:
primary_emoji, self.options.default_bump_level
)

# All emojis will remain part of the returned description
category = primary_emoji
if (
self.options.render_emoji
and match
and (
rendered_category := DEFAULT_EMOJI_CHANGELOG_SECTIONS.get(primary_emoji)
)
):
category = rendered_category
subject = subject[match.end() :].lstrip()

body_components: dict[str, list[str]] = reduce(
self.commit_body_components_separator,
[
Expand All @@ -308,7 +353,7 @@ def parse_message(self, message: str) -> ParsedMessageResult:
return ParsedMessageResult(
bump=level_bump,
type=primary_emoji,
category=primary_emoji,
category=category,
scope=parsed_scope,
descriptions=(
descriptions[:1] if level_bump is LevelBump.MAJOR else descriptions
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/semantic_release/commit_parser/test_emoji.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,33 @@ def test_default_emoji_parser(
assert breaking_descriptions == result.breaking_descriptions


@pytest.mark.parametrize(
"message, category, scope, description",
[
(":bug: correct some text", "🐛 Bug Fixes", "", "correct some text"),
(
":sparkles:(cli): add a new option",
"✨ Features",
"cli",
"add a new option",
),
],
)
def test_emoji_parser_render_emoji_for_changelog(
message: str,
category: str,
scope: str,
description: str,
):
parser = EmojiCommitParser(EmojiParserOptions(render_emoji=True))

result = parser.parse_message(message)

assert category == result.category
assert scope == result.scope
assert (description,) == result.descriptions


@pytest.mark.parametrize(
"message, subject, merge_request_number",
[
Expand Down
Loading