Skip to content
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

#92 - Add support for more characters as markdown list rows #93

Merged
merged 20 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6b15137
#92 - Add support for more characters as markdown list rows
miroslavpojer Oct 11, 2024
869a6f0
- Applied black.
miroslavpojer Oct 11, 2024
ce33aaa
- Improvement of unit tests.
miroslavpojer Oct 11, 2024
d4121ae
- Update of README.md. Fixed comment mentions.
miroslavpojer Oct 11, 2024
59e2895
- Remove not used import.
miroslavpojer Oct 11, 2024
f512978
- Apply black to fix PR check.
miroslavpojer Oct 11, 2024
4f2ccb2
#91 - Placeholder {number} does not # before Issue or PR number
miroslavpojer Oct 14, 2024
f8f9eb3
Merge branch 'master' into bugfix/91-Placeholder-number
miroslavpojer Oct 16, 2024
b8a34b1
- Fixed `Release Notes:` pattern for detection rls notes in PR body. …
miroslavpojer Oct 16, 2024
cf8ed92
- Rewording.
miroslavpojer Oct 16, 2024
5eee2e9
- Add type hint.
miroslavpojer Oct 16, 2024
3f02bfd
- Fixed text line about test and coverage in README.md.
miroslavpojer Oct 16, 2024
9e11d4d
- Moved mention of case-sensivity for `Release Notes:` detection string.
miroslavpojer Oct 16, 2024
24886a8
- Small changes and improvement from review notes.
miroslavpojer Oct 16, 2024
8d46ba8
- Fixed unit tests.
miroslavpojer Oct 16, 2024
b831fb1
- Removed TODO from pylintrc.
miroslavpojer Oct 16, 2024
1622020
- Removed not needed word.
miroslavpojer Oct 17, 2024
0362f31
- Fix of example file to fit the latest expected version.
miroslavpojer Oct 17, 2024
7eb8d24
- Applied changes from external development to keep them as examples …
miroslavpojer Oct 21, 2024
8af61cd
- Replace code root dir by . to add all python file.
miroslavpojer Oct 21, 2024
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
46 changes: 22 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ Generate Release Notes action is dedicated to enhance the quality and organizati
### `row-format-issue`
- **Description**: The format of the row for the issue in the release notes. The format can contain placeholders for the issue `number`, `title`, and issues `pull-requests`. The placeholders are case-sensitive.
- **Required**: No
- **Default**: `#{number} _{title}_ in {pull-requests}"`
- **Default**: `"{number} _{title}_ in {pull-requests}"`
MobiTikula marked this conversation as resolved.
Show resolved Hide resolved

### `row-format-pr`
- **Description**: The format of the row for the PR in the release notes. The format can contain placeholders for the PR `number`, `title`, and PR `pull-requests`. The placeholders are case-sensitive.
- **Description**: The format of the row for the PR in the release notes. The format can contain placeholders for the PR `number`, and `title`. The placeholders are case-sensitive.
- **Required**: No
- **Default**: `#{number} _{title}_"`
- **Default**: `"{number} _{title}_"`

### `row-format-link-pr`
- **Description**: If defined `true`, the PR row will begin with a `"PR: "` string. Otherwise, no prefix will be added.
Expand Down Expand Up @@ -171,32 +171,30 @@ Add the following step to your GitHub workflow (in example are used non-default
## Features
### Built-in
#### Release Notes Extraction Process
This feature searches for release notes in the description of GitHub pull requests, making it easier for maintainers to track changes and updates.
- **Format:**
- The release notes section have to begin with the title `Release Notes:`, followed by the release notes in bullet points. [See Markdown formatting is supported](https://www.markdownguide.org/basic-syntax/#unordered-lists).
MobiTikula marked this conversation as resolved.
Show resolved Hide resolved
- If no release notes line is detected under the Release notes: "title," no release notes will be printed in the output.
- **Example:**
- Here are examples of how to structure the release notes (case-sensitive):
```
Release Notes:
- This update introduces a new caching mechanism that improves performance by 20%.

This action requires that your GitHub issues include comments with specific release notes. Here's how it works:
Release Notes:
* This update introduces a new caching mechanism that improves performance by 20%.

**Extraction Method**:
- The action scans through comments on each closed issue since the last release. It identifies comments that follow the specified format and extracts the content as part of the release notes.
- The time considered for the previous release is based on its creation time. This means that the action will look for issues closed after the creation time of the most recent release to ensure that all relevant updates since that release are included.
Release Notes:
+ This update introduces a new caching mechanism that improves performance by 20%.

**Comment Format**
- For an issue's contributions to be included in the release notes, it must contain a comment starting with "Release Notes" followed by the note content. This comment is typically added by the contributors.
- Here is an example of the content for a 'Release Notes' string, which is not case-sensitive:
```
Release Notes
- This update introduces a new caching mechanism that improves performance by 20%.
```
- Using `-` as a bullet point for each note is the best practice. The Markdown parser will automatically convert it to a list.
- These comments are not required for action functionality. If an issue does not contain a "Release Notes" comment, it will be marked accordingly in the release notes. This helps maintainers quickly identify which issues need attention for documentation.

#### Contributors Mention
Along with the release note content, the action also gathers a list of contributors for each issue. This includes issue assignees and authors of linked pull requests' commits, providing acknowledgment for their contributions in the release notes.
- The extraction process supports all three types of bullet points: `-`, `*`, and `+`, and their combinations even when mixed. (It is not recommended to mix them.)
- **Best Practice:** Select one character from `-`, `*`, `+` for bullet points. The Markdown parser will automatically format them as a list.
- **Optional:** Usage of release notes is not mandatory for this GH action.
MobiTikula marked this conversation as resolved.
Show resolved Hide resolved

#### Handling Multiple PRs
If an issue is linked to multiple PRs, the action fetches and aggregates contributions from all linked PRs.

#### No Release Notes Found
If no valid "Release Notes" comment is found in an issue, it will be marked accordingly. This helps maintainers quickly identify which issues need attention for documentation.

### Select start date for closed issues and PRs
By set **published-at** to true the action will use the `published-at` timestamp of the latest release as the reference point for searching closed issues and PRs, instead of the `created-at` date. If first release, repository creation date is used.

Expand All @@ -217,7 +215,7 @@ The action includes four specific warning chapters to highlight potential areas
- **Importance**: Ensures all issues are categorized correctly according to the project's classification system. It aids in organizing release notes into predefined chapters effectively.

- **_Closed Issues Without Release Notes_**
- **Purpose**: Identifies issues that do not contain a "Release Notes" comment.
- **Purpose**: Identifies pull requests which do not contain a "Release Notes" section in description.
- **Importance**: Ensures that all significant changes are properly documented in the release notes, enhancing the completeness and usefulness of the release information provided to end-users.

- **_Merged PRs Without Linked Issue_**
Expand Down Expand Up @@ -456,8 +454,8 @@ We defined chapters for our GH actions this way:
Then in chapters `New Features 🎉` and `Bugfixes 🛠` will be duplicated lines for this issue. When mentioned second+ times then **[Duplicate]** prefix will be visible.
In the `New Features 🎉` chapter will be mentioned this issue once only.

### What will happen when the issue contains multiple "Release Notes" comments?
All issue comments are checked for presence of `Release Notes` string. All detected release notes are collected printed under issue.
### What will happen when the pull request contains multiple "Release Notes" sections?
Only the first one will be used.

### What will happen when Merged PR is linked to open issues?
The PR will be mentioned in warning chapter **Merged PRs Linked to Open Issue**.
8 changes: 4 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ inputs:
required: false
default: 'false'
row-format-issue:
description: 'Format of the issue row in the release notes. Available placeholders: {link}, {title}, {pull-requests}. Placeholders are case-insensitive.'
description: 'Format of the issue row in the release notes. Available placeholders: {number}, {title}, {pull-requests}. Placeholders are case-insensitive.'
required: false
default: '#{number} _{title}_ in {pull-requests}'
default: '{number} _{title}_ in {pull-requests}'
row-format-pr:
description: 'Format of the pr row in the release notes. Available placeholders: {link}, {title}, {pull-requests}. Placeholders are case-insensitive.'
description: 'Format of the pr row in the release notes. Available placeholders: {number}, {title}, {pull-requests}. Placeholders are case-insensitive.'
required: false
default: '#{number} _{title}_'
default: '{number} _{title}_'
row-format-link-pr:
description: 'Add prefix "PR:" before link to PR when not linked an Issue.'
required: false
Expand Down
4 changes: 2 additions & 2 deletions release_notes_generator/action_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ def get_row_format_issue() -> str:
"""
Get the issue row format for the release notes.
"""
return get_action_input(ROW_FORMAT_ISSUE, "#{number} _{title}_ in {pull-requests}").strip()
return get_action_input(ROW_FORMAT_ISSUE, "{number} _{title}_ in {pull-requests}").strip()

@staticmethod
def get_row_format_pr() -> str:
"""
Get the pr row format for the release notes.
"""
return get_action_input(ROW_FORMAT_PR, "#{number} _{title}_").strip()
return get_action_input(ROW_FORMAT_PR, "{number} _{title}_").strip()

@staticmethod
def get_row_format_link_pr() -> bool:
Expand Down
24 changes: 14 additions & 10 deletions release_notes_generator/model/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
ISSUE_STATE_CLOSED,
ISSUE_STATE_OPEN,
RELEASE_NOTE_DETECTION_PATTERN,
RELEASE_NOTE_LINE_MARK,
RELEASE_NOTE_LINE_MARKS,
)
from release_notes_generator.utils.pull_reuqest_utils import extract_issue_numbers_from_body

Expand Down Expand Up @@ -129,12 +129,14 @@ def labels(self) -> list[str]:
# TODO in Issue named 'Configurable regex-based Release note detection in the PR body'
# - 'Release notest:' as detection pattern default - can be defined by user
# - '-' as leading line mark for each release note to be used
def get_rls_notes(self, detection_pattern=RELEASE_NOTE_DETECTION_PATTERN, line_mark=RELEASE_NOTE_LINE_MARK) -> str:
def get_rls_notes(
self, detection_pattern=RELEASE_NOTE_DETECTION_PATTERN, line_marks=RELEASE_NOTE_LINE_MARKS
) -> str:
"""
Gets the release notes of the record.

@param detection_pattern: The detection pattern to use.
@param line_mark: The line mark to use.
@param line_marks: The line marks to use.
@return: The release notes of the record as a string.
"""
release_notes = ""
Expand All @@ -150,8 +152,9 @@ def get_rls_notes(self, detection_pattern=RELEASE_NOTE_DETECTION_PATTERN, line_m
continue

if inside_release_notes:
if line.startswith(line_mark):
release_notes += f" {line.strip()}\n"
tmp = line.strip()
if len(tmp) > 0 and tmp[0] in line_marks:
release_notes += f" {line.rstrip()}\n"
else:
break

Expand All @@ -164,7 +167,8 @@ def contains_release_notes(self) -> bool:
if self.__is_release_note_detected:
return self.__is_release_note_detected

if RELEASE_NOTE_LINE_MARK in self.get_rls_notes():
rls_notes = self.get_rls_notes()
MobiTikula marked this conversation as resolved.
Show resolved Hide resolved
if any(mark in rls_notes for mark in RELEASE_NOTE_LINE_MARKS):
self.__is_release_note_detected = True

return self.__is_release_note_detected
Expand Down Expand Up @@ -207,8 +211,8 @@ def pr_links(self) -> Optional[str]:
if len(self.__pulls) == 0:
return None

template = "[#{number}](https://github.com/{full_name}/pull/{number})"
res = [template.format(number=pull.number, full_name=self.__repo.full_name) for pull in self.__pulls]
template = "#{number}"
res = [template.format(number=pull.number) for pull in self.__pulls]

return ", ".join(res)

Expand Down Expand Up @@ -276,7 +280,7 @@ def to_chapter_row(self) -> str:

if self.__gh_issue is None:
p = self.__pulls[0]
format_values["number"] = p.number
format_values["number"] = f"#{p.number}"
format_values["title"] = p.title
format_values["authors"] = self.authors if self.authors is not None else ""
format_values["contributors"] = self.contributors if self.contributors is not None else ""
Expand All @@ -285,7 +289,7 @@ def to_chapter_row(self) -> str:
row = f"{row_prefix}{pr_prefix}" + ActionInputs.get_row_format_pr().format(**format_values)

else:
format_values["number"] = self.__gh_issue.number
format_values["number"] = f"#{self.__gh_issue.number}"
format_values["title"] = self.__gh_issue.title
format_values["pull-requests"] = self.pr_links if len(self.__pulls) > 0 else ""
format_values["authors"] = self.authors if self.authors is not None else ""
Expand Down
2 changes: 1 addition & 1 deletion release_notes_generator/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

# Release notes comment constants
RELEASE_NOTE_DETECTION_PATTERN = "Release notes:"
RELEASE_NOTE_LINE_MARK = "-"
RELEASE_NOTE_LINE_MARKS = ["-", "*", "+"]

# Service chapters titles
CLOSED_ISSUES_WITHOUT_PULL_REQUESTS: str = "Closed Issues without Pull Request ⚠️"
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def mock_issue_closed_i1_bug(mocker):
def mock_pull_closed(mocker):
pull = mocker.Mock(spec=PullRequest)
pull.state = PR_STATE_CLOSED
pull.body = "Release notes:\n- Fixed bug\n- Improved performance\n"
pull.body = "Release notes:\n- Fixed bug\n- Improved performance\n+ More nice code\n * Awesome architecture"
pull.url = "http://example.com/pull/123"
label1 = mocker.Mock(spec=MockLabel)
label1.name = "label1"
Expand Down
20 changes: 13 additions & 7 deletions tests/release_notes/model/test_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_record_properties_authors_contributors(record_with_no_issue_one_pull_cl


def test_get_rls_notes(record_with_no_issue_one_pull_closed):
expected_notes = " - Fixed bug\n - Improved performance"
expected_notes = " - Fixed bug\n - Improved performance\n + More nice code\n * Awesome architecture"
assert record_with_no_issue_one_pull_closed.get_rls_notes() == expected_notes


Expand Down Expand Up @@ -100,7 +100,7 @@ def test_pr_contains_issue_mentions(record_with_no_issue_one_pull_closed, mocker


def test_pr_links(record_with_no_issue_one_pull_closed):
expected_links = "[#123](https://github.com/org/repo/pull/123)"
expected_links = "#123"
assert record_with_no_issue_one_pull_closed.pr_links == expected_links


Expand Down Expand Up @@ -137,20 +137,26 @@ def test_register_commit_failure(record_with_no_issue_one_pull_closed, caplog, m


def test_to_chapter_row_with_pull(record_with_no_issue_one_pull_closed):
expected_row = "PR: #123 _Fixed bug_\n - Fixed bug\n - Improved performance"
expected_row = (
"PR: #123 _Fixed bug_\n - Fixed bug\n - Improved performance\n + More nice code\n * Awesome architecture"
)
assert expected_row == record_with_no_issue_one_pull_closed.to_chapter_row()


def test_to_chapter_row_with_pull_no_pr_prefix(record_with_no_issue_one_pull_closed, mocker):
mocker.patch("release_notes_generator.builder.ActionInputs.get_row_format_link_pr", return_value=False)
expected_row = "#123 _Fixed bug_\n - Fixed bug\n - Improved performance"
expected_row = (
"#123 _Fixed bug_\n - Fixed bug\n - Improved performance\n + More nice code\n * Awesome architecture"
)
assert expected_row == record_with_no_issue_one_pull_closed.to_chapter_row()


def test_to_chapter_row_with_issue(record_with_issue_closed_one_pull):
expected_row = """#121 _Fix the bug_ in [#123](https://github.com/org/repo/pull/123)
expected_row = """#121 _Fix the bug_ in #123
- Fixed bug
- Improved performance"""
- Improved performance
+ More nice code
* Awesome architecture"""
assert expected_row == record_with_issue_closed_one_pull.to_chapter_row()


Expand All @@ -160,7 +166,7 @@ def test_to_chapter_row_with_pull_no_rls_notes(record_with_no_issue_one_pull_clo


def test_to_chapter_row_with_issue_no_rls_notes(record_with_issue_closed_one_pull_no_rls_notes):
expected_row = "#121 _Fix the bug_ in [#123](https://github.com/org/repo/pull/123)"
expected_row = "#121 _Fix the bug_ in #123"
assert expected_row == record_with_issue_closed_one_pull_no_rls_notes.to_chapter_row()


Expand Down
18 changes: 11 additions & 7 deletions tests/release_notes/test_release_notes_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def __init__(self, name):
RELEASE_NOTES_NO_DATA_NO_EMPTY_CHAPTERS = RELEASE_NOTES_NO_DATA_NO_WARNING_NO_EMPTY_CHAPTERS

RELEASE_NOTES_DATA_CUSTOM_CHAPTERS_ONE_LABEL = """### Chapter 1 🛠
- #122 _I1+bug_ in [#101](https://github.com/org/repo/pull/101), [#102](https://github.com/org/repo/pull/102)
- #122 _I1+bug_ in #101, #102
- PR 101 1st release note
- PR 101 2nd release note
- PR 102 1st release note
Expand All @@ -149,7 +149,7 @@ def __init__(self, name):
"""

RELEASE_NOTES_DATA_CUSTOM_CHAPTERS_MORE_LABELS_DUPLICITY_REDUCTION_ON = """### Chapter 1 🛠
- #122 _I1+bug-enhancement_ in [#101](https://github.com/org/repo/pull/101), [#102](https://github.com/org/repo/pull/102)
- #122 _I1+bug-enhancement_ in #101, #102
- PR 101 1st release note
- PR 101 2nd release note
- PR 102 1st release note
Expand All @@ -160,7 +160,7 @@ def __init__(self, name):
"""

RELEASE_NOTES_DATA_CUSTOM_CHAPTERS_MORE_LABELS_DUPLICITY_REDUCTION_OFF = """### New Features 🎉
- #1 _I1+0PR+2L-bug-enhancement_ in [#101](https://github.com/org/repo/pull/101), [#102](https://github.com/org/repo/pull/102)
- #1 _I1+0PR+2L-bug-enhancement_ in #101, #102
- PR 101 1st release note
- PR 101 2nd release note
- PR 102 1st release note
Expand Down Expand Up @@ -196,13 +196,15 @@ def __init__(self, name):
- PR: #123 _Fixed bug_
- Fixed bug
- Improved performance
+ More nice code
* Awesome architecture

#### Full Changelog
http://example.com/changelog
"""

RELEASE_NOTES_DATA_SERVICE_CHAPTERS_OPEN_ISSUE_AND_MERGED_PR_NO_USER_LABELS = """### Merged PRs Linked to 'Not Closed' Issue ⚠️
- #122 _I1 open_ in [#101](https://github.com/org/repo/pull/101), [#102](https://github.com/org/repo/pull/102)
- #122 _I1 open_ in #101, #102
- PR 101 1st release note
- PR 101 2nd release note
- PR 102 1st release note
Expand Down Expand Up @@ -231,7 +233,7 @@ def __init__(self, name):
"""

RELEASE_NOTES_DATA_CLOSED_ISSUE_WITH_PR_WITHOUT_USER_LABELS = """### Closed Issues without User Defined Labels ⚠️
- #122 _I1_ in [#101](https://github.com/org/repo/pull/101), [#102](https://github.com/org/repo/pull/102)
- #122 _I1_ in #101, #102
- PR 101 1st release note
- PR 101 2nd release note
- PR 102 1st release note
Expand Down Expand Up @@ -272,16 +274,18 @@ def __init__(self, name):
"""

RELEASE_NOTES_DATA_CLOSED_ISSUE_WITH_MERGED_PRS_WITHOUT_USER_LABELS = """### Closed Issues without User Defined Labels ⚠️
- #121 _Fix the bug_ in [#123](https://github.com/org/repo/pull/123)
- #121 _Fix the bug_ in #123
- Fixed bug
- Improved performance
+ More nice code
* Awesome architecture

#### Full Changelog
http://example.com/changelog
"""

RELEASE_NOTES_DATA_CLOSED_ISSUE_WITH_MERGED_PRS_WITH_USER_LABELS = """### Chapter 1 🛠
- #122 _I1+bug_ in [#123](https://github.com/org/repo/pull/123)
- #122 _I1+bug_ in #123
- Fixed bug
- Improved performance

Expand Down
Loading