Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Feat/changelog add release information #1166

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
48e40d9
test(parser-angular): add unit test for extracting release notices fr…
codejedi365 Feb 1, 2025
6a0d054
test(parser-angular): refactor test params to match valid commit mess…
codejedi365 Feb 2, 2025
e918a6f
test(parser-scipy): add unit test for extracting release notices from…
codejedi365 Feb 1, 2025
e6e7173
test(parser-emoji): add unit test for extracting release notices from…
codejedi365 Feb 1, 2025
601c810
test(release-notes): add test of default template for additional rele…
codejedi365 Feb 2, 2025
dbbf197
test(changelog): add test of default template for additional release …
codejedi365 Feb 2, 2025
ac01c22
feat(commit-parser): enable parsers to identify additional release no…
codejedi365 Dec 20, 2024
7d07f0d
feat(parser-angular): add functionality to parse out `NOTICE:` prefix…
codejedi365 Dec 20, 2024
bacef8f
feat(parser-emoji): add functionality to parse out `NOTICE:` prefixed…
codejedi365 Dec 20, 2024
a242f9d
feat(changelog-md): add additional release info section to default ma…
codejedi365 Dec 20, 2024
252d82b
feat(changelog-rst): add additional release info section to default R…
codejedi365 Dec 20, 2024
1652673
fix(parser-angular): adjust parser to prevent empty message extractions
codejedi365 Dec 20, 2024
5111166
fix(parser-emoji): adjust parser to prevent empty message extractions
codejedi365 Dec 20, 2024
549be01
refactor(util): tweak parse paragraphs for git footers & multi-line d…
codejedi365 Feb 1, 2025
14ebf35
chore(changelog): update psr templates to include an additional relea…
codejedi365 Jan 27, 2025
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
42 changes: 40 additions & 2 deletions 42 config/release-templates/.components/changes.md.j2
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{% from 'macros.md.j2' import apply_alphabetical_ordering_by_brk_descriptions
%}{% from 'macros.md.j2' import apply_alphabetical_ordering_by_descriptions
%}{% from 'macros.md.j2' import apply_alphabetical_ordering_by_release_notices
%}{% from 'macros.md.j2' import emoji_map, format_breaking_changes_description
%}{% from 'macros.md.j2' import format_commit_summary_line
%}{% from 'macros.md.j2' import format_commit_summary_line, format_release_notice
%}{% from 'macros.md.j2' import section_heading_order, section_heading_translations
%}{#
EXAMPLE:
Expand All @@ -27,6 +28,14 @@ EXAMPLE:
- **scope**: this breaking change has a scope to identify the part of the code that
this breaking change applies to for better context.

### 💡 ADDITIONAL RELEASE INFORMATION

- This is a release note that provides additional information about the release
that is not a breaking change or a feature/bug fix.

- **scope**: this release note has a scope to identify the part of the code that
this release note applies to for better context.

#}{% set max_line_width = max_line_width | default(100)
%}{% set hanging_indent = hanging_indent | default(2)
%}{#
Expand All @@ -51,15 +60,20 @@ EXAMPLE:
}}{{ "%s\n" | format(commit_descriptions | unique | join("\n\n"))
}}{% endfor
%}{#
# # Determine if any commits have a breaking change description
# # Determine if any commits have a breaking change or release notice
# # commit_objects is a dictionary of strings to a list of commits { "features", [ParsedCommit(), ...] }
#}{% set breaking_commits = []
%}{% set notice_commits = []
%}{% for commits in commit_objects.values()
%}{% set valid_commits = commits | rejectattr("error", "defined")
%}{# # Filter out breaking change commits that have no breaking descriptions
#}{% set _ = breaking_commits.extend(
valid_commits | selectattr("breaking_descriptions.0")
)
%}{# # Filter out ParsedCommits commits that have no release notices
#}{% set _ = notice_commits.extend(
valid_commits | selectattr("release_notices.0")
)
%}{% endfor
%}{#
#}{% if breaking_commits | length > 0
Expand All @@ -85,4 +99,28 @@ EXAMPLE:
"\n%s\n" | format(brking_descriptions | unique | join("\n\n"))
}}{#
#}{% endif
%}{#
#}{% if notice_commits | length > 0
%}{# PREPROCESS COMMITS
#}{% set notice_ns = namespace(commits=notice_commits)
%}{% set _ = apply_alphabetical_ordering_by_release_notices(notice_ns)
%}{#
#}{% set release_notices = []
%}{#
#}{% for commit in notice_ns.commits
%}{% set full_description = "- %s" | format(
format_release_notice(commit).split("\n\n") | join("\n\n- ")
)
%}{% set _ = release_notices.append(
full_description | autofit_text_width(max_line_width, hanging_indent)
)
%}{% endfor
%}{#
# # PRINT RELEASE NOTICE INFORMATION (header & descriptions)
#}{{ "\n"
}}{{ "### %s ADDITIONAL RELEASE INFORMATION\n" | format(emoji_map["release_note"])
}}{{
"\n%s\n" | format(release_notices | unique | join("\n\n"))
}}{#
#}{% endif
%}
44 changes: 42 additions & 2 deletions 44 config/release-templates/.components/changes.rst.j2
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{% from 'macros.rst.j2' import apply_alphabetical_ordering_by_brk_descriptions
%}{% from 'macros.rst.j2' import apply_alphabetical_ordering_by_descriptions
%}{% from 'macros.rst.j2' import apply_alphabetical_ordering_by_release_notices
%}{% from 'macros.rst.j2' import emoji_map, extract_issue_link_references, extract_pr_link_reference
%}{% from 'macros.rst.j2' import format_breaking_changes_description, format_commit_summary_line
%}{% from 'macros.rst.j2' import format_link_reference
%}{% from 'macros.rst.j2' import format_link_reference, format_release_notice
%}{% from 'macros.rst.j2' import generate_heading_underline, section_heading_order
%}{% from 'macros.rst.j2' import section_heading_translations
%}{#
Expand All @@ -29,6 +30,15 @@
* **scope**: this breaking change has a scope to identify the part of the code that
this breaking change applies to for better context.

💡 ADDITIONAL RELEASE INFORMATION
---------------------------------

* This is a release note that provides additional information about the release
that is not a breaking change or a feature/bug fix.

* **scope**: this release note has a scope to identify the part of the code that
this release note applies to for better context.

.. _8a7B8ec: https://domain.com/owner/repo/commit/8a7b8ec
.. _abcdef0: https://domain.com/owner/repo/commit/abcdef0
.. _PR#10: https://domain.com/namespace/repo/pull/10
Expand Down Expand Up @@ -88,15 +98,20 @@

}}{% endfor
%}{#
# # Determine if any commits have a breaking change description
# # Determine if any commits have a breaking change or release notice
# # commit_objects is a dictionary of strings to a list of commits { "features", [ParsedCommit(), ...] }
#}{% set breaking_commits = []
%}{% set notice_commits = []
%}{% for commits in commit_objects.values()
%}{% set valid_commits = commits | rejectattr("error", "defined")
%}{# # Filter out breaking change commits that have no breaking descriptions
#}{% set _ = breaking_commits.extend(
valid_commits | selectattr("breaking_descriptions.0")
)
%}{# # Filter out ParsedCommits commits that have no release notices
#}{% set _ = notice_commits.extend(
valid_commits | selectattr("release_notices.0")
)
%}{% endfor
%}{#
#}{% if breaking_commits | length > 0
Expand All @@ -123,6 +138,31 @@
"\n%s\n" | format(brking_descriptions | unique | join("\n\n"))
}}{#
#}{% endif
%}{#
#}{% if notice_commits | length > 0
%}{# PREPROCESS COMMITS
#}{% set notice_ns = namespace(commits=notice_commits)
%}{% set _ = apply_alphabetical_ordering_by_release_notices(notice_ns)
%}{#
#}{% set release_notices = []
%}{#
#}{% for commit in notice_ns.commits
%}{% set full_description = "* %s" | format(
format_release_notice(commit).split("\n\n") | join("\n\n* ")
)
%}{% set _ = release_notices.append(
full_description | convert_md_to_rst | autofit_text_width(max_line_width, hanging_indent)
)
%}{% endfor
%}{#
# # PRINT RELEASE NOTICE INFORMATION (header & descriptions)
#}{{ "\n"
}}{{ "%s ADDITIONAL RELEASE INFORMATION\n" | format(emoji_map["release_note"])
}}{{ "---------------------------------\n"
}}{{
"\n%s\n" | format(release_notices | unique | join("\n\n"))
}}{#
#}{% endif
%}{#
#
# # PRINT POST PARAGRAPH LINKS
Expand Down
47 changes: 47 additions & 0 deletions 47 config/release-templates/.components/macros.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,41 @@
%}


{#
MACRO: format the release notice by:
- Capitalizing the description
- Adding an optional scope prefix
#}{% macro format_release_notice(commit)
%}{% set ns = namespace(full_description="")
%}{#
#}{% if commit.error is undefined
%}{% for paragraph in commit.release_notices
%}{% if paragraph | trim | length > 0
%}{#
#}{% set paragraph_text = capitalize_first_letter_only(paragraph) | trim | safe
%}{#
#}{% set ns.full_description = [
ns.full_description,
paragraph_text
] | join("\n\n")
%}{#
#}{% endif
%}{% endfor
%}{#
#}{% set ns.full_description = ns.full_description | trim
%}{#
#}{% if commit.scope
%}{% set ns.full_description = "**%s**: %s" | format(
commit.scope, ns.full_description
)
%}{% endif
%}{% endif
%}{#
#}{{ ns.full_description
}}{% endmacro
%}


{#
MACRO: order commits alphabetically by scope and attribute
- Commits are sorted based on scope and then the attribute alphabetically
Expand Down Expand Up @@ -198,3 +233,15 @@
%}{% set _ = order_commits_alphabetically_by_scope_and_attr(ns, 'breaking_descriptions.0')
%}{% endmacro
%}


{#
MACRO: apply smart ordering of commits objects based on alphabetized release notices and then scopes
- Commits are sorted based on the commit type and the commit message
- Commits are grouped by the commit type
- parameter: ns (namespace) object with a commits list
- returns None but modifies the ns.commits list in place
#}{% macro apply_alphabetical_ordering_by_release_notices(ns)
%}{% set _ = order_commits_alphabetically_by_scope_and_attr(ns, 'release_notices.0')
%}{% endmacro
%}
47 changes: 47 additions & 0 deletions 47 config/release-templates/.components/macros.rst.j2
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,41 @@
%}


{#
MACRO: format the release notice by:
- Capitalizing the description
- Adding an optional scope prefix
#}{% macro format_release_notice(commit)
%}{% set ns = namespace(full_description="")
%}{#
#}{% if commit.error is undefined
%}{% for paragraph in commit.release_notices
%}{% if paragraph | trim | length > 0
%}{#
#}{% set paragraph_text = capitalize_first_letter_only(paragraph) | trim | safe
%}{#
#}{% set ns.full_description = [
ns.full_description,
paragraph_text
] | join("\n\n")
%}{#
#}{% endif
%}{% endfor
%}{#
#}{% set ns.full_description = ns.full_description | trim
%}{#
#}{% if commit.scope
%}{% set ns.full_description = "**%s**: %s" | format(
commit.scope, ns.full_description
)
%}{% endif
%}{% endif
%}{#
#}{{ ns.full_description
}}{% endmacro
%}


{#
MACRO: order commits alphabetically by scope and attribute
- Commits are sorted based on scope and then the attribute alphabetically
Expand Down Expand Up @@ -251,3 +286,15 @@
%}{% set _ = order_commits_alphabetically_by_scope_and_attr(ns, 'breaking_descriptions.0')
%}{% endmacro
%}


{#
MACRO: apply smart ordering of commits objects based on alphabetized release notices and then scopes
- Commits are sorted based on the commit type and the commit message
- Commits are grouped by the commit type
- parameter: ns (namespace) object with a commits list
- returns None but modifies the ns.commits list in place
#}{% macro apply_alphabetical_ordering_by_release_notices(ns)
%}{% set _ = order_commits_alphabetically_by_scope_and_attr(ns, 'release_notices.0')
%}{% endmacro
%}
6 changes: 6 additions & 0 deletions 6 config/release-templates/.release_notes.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@

- **scope**: this breaking change has a scope to identify the part of the code that this breaking change applies to for better context.

### 💡 ADDITIONAL RELEASE INFORMATION

- This is a release note that provides additional information about the release that is not a breaking change or a feature/bug fix.

- **scope**: this release note has a scope to identify the part of the code that this release note applies to for better context.

### ✅ Resolved Issues

- [#000](https://domain.com/namespace/repo/issues/000): _Title_
Expand Down
33 changes: 20 additions & 13 deletions 33 src/semantic_release/commit_parser/angular.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def __init__(self, options: AngularParserOptions | None = None) -> None:
),
flags=re.MULTILINE | re.IGNORECASE,
)
self.notice_selector = regexp(r"^NOTICE: (?P<notice>.+)$")
self.filters = {
"typo-extra-spaces": (regexp(r"(\S) +(\S)"), r"\1 \2"),
"git-header-commit": (
Expand Down Expand Up @@ -236,11 +237,18 @@ def get_default_options() -> AngularParserOptions:
def commit_body_components_separator(
self, accumulator: dict[str, list[str]], text: str
) -> dict[str, list[str]]:
if match := breaking_re.match(text):
accumulator["breaking_descriptions"].append(match.group(1) or "")
if (match := breaking_re.match(text)) and (brk_desc := match.group(1)):
accumulator["breaking_descriptions"].append(brk_desc)
# TODO: breaking change v10, removes breaking change footers from descriptions
# return accumulator

elif (match := self.notice_selector.match(text)) and (
notice := match.group("notice")
):
accumulator["notices"].append(notice)
# TODO: breaking change v10, removes notice footers from descriptions
# return accumulator

elif match := self.issue_selector.search(text):
# if match := self.issue_selector.search(text):
predicate = regexp(r",? and | *[,;/& ] *").sub(
Expand All @@ -256,11 +264,12 @@ def commit_body_components_separator(
predicate.split(","),
)
)
accumulator["linked_issues"] = sort_numerically(
set(accumulator["linked_issues"]).union(new_issue_refs)
)
# TODO: breaking change v10, removes resolution footers from descriptions
# return accumulator
if new_issue_refs:
accumulator["linked_issues"] = sort_numerically(
set(accumulator["linked_issues"]).union(new_issue_refs)
)
# TODO: breaking change v10, removes resolution footers from descriptions
# return accumulator

# Prevent appending duplicate descriptions
if text not in accumulator["descriptions"]:
Expand Down Expand Up @@ -295,6 +304,7 @@ def parse_message(self, message: str) -> ParsedMessageResult | None:
{
"breaking_descriptions": [],
"descriptions": [],
"notices": [],
"linked_issues": [],
},
)
Expand All @@ -315,6 +325,7 @@ def parse_message(self, message: str) -> ParsedMessageResult | None:
scope=parsed_scope,
descriptions=tuple(body_components["descriptions"]),
breaking_descriptions=tuple(body_components["breaking_descriptions"]),
release_notices=tuple(body_components["notices"]),
linked_issues=tuple(body_components["linked_issues"]),
linked_merge_request=linked_merge_request,
)
Expand Down Expand Up @@ -455,7 +466,7 @@ def unsquash_commit_message(self, message: str) -> list[str]:
[],
)

return separate_commit_msgs
return list(filter(None, separate_commit_msgs))

def _find_squashed_commits_in_str(self, message: str) -> list[str]:
separate_commit_msgs: list[str] = []
Expand Down Expand Up @@ -490,8 +501,4 @@ def _find_squashed_commits_in_str(self, message: str) -> list[str]:

current_msg = clean_paragraph

# Store the last commit message (if its not empty)
if current_msg:
separate_commit_msgs.append(current_msg)

return separate_commit_msgs
return [*separate_commit_msgs, current_msg]
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.