Skip to content

Commit

Permalink
- Add support for row format for direct commits.
Browse files Browse the repository at this point in the history
- Improved validation logic to support difference keywords for issue, pr and commit format rows.
  • Loading branch information
miroslavpojer committed Oct 7, 2024
1 parent 3285283 commit c118375
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 70 deletions.
14 changes: 12 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,25 @@ inputs:
required: false
default: 'false'
row-format-issue:
description: 'Format of the issue row in the release notes. Available placeholders: {link}, {title}, {pull-requests}, {assignee}, {assignees}, {developed-by}, {co-authored-by}. Placeholders are case-insensitive.'
description: 'Format of the issue row in the release notes. Available placeholders: {number}, {title}, {pull-requests}, {assignee}, {assignees}, {developed-by}, {co-authored-by}. Placeholders are case-insensitive.'
required: false
default: '#{number} _{title}_ {pull-requests} {assignee} {developed-by} {co-authored-by}'
row-format-pr:
description: 'Format of the pr row in the release notes. Available placeholders: {link}, {title}, {pull-requests}, {assignee}, {assignees}, {developed-by}, {co-authored-by}. Placeholders are case-insensitive.'
description: 'Format of the pr row in the release notes. Available placeholders: {number}, {title}, {assignee}, {assignees}, {developed-by}, {co-authored-by}. Placeholders are case-insensitive.'
required: false
default: '#{number} _{title}_ {assignee} {developed-by} {co-authored-by}'
row-format-commit:
description: 'Format of the commit row in the release notes. Available placeholders: {sha}, {author}, {co-authored-by}. Placeholders are case-insensitive.'
required: false
default: '#{sha} {author} {co-authored-by}'
row-format-link-pr:
description: 'Add prefix "PR:" before link to PR when not linked an Issue.'
required: false
default: 'true'
row-format-link-commit:
description: 'Add prefix "Commit:" before link to direct commit.'
required: false
default: 'true'

outputs:
release-notes:
Expand Down Expand Up @@ -123,7 +131,9 @@ runs:
INPUT_GITHUB_REPOSITORY: ${{ github.repository }}
INPUT_ROW_FORMAT_ISSUE: ${{ inputs.row-format-issue }}
INPUT_ROW_FORMAT_PR: ${{ inputs.row-format-pr }}
INPUT_ROW_FORMAT_COMMIT: ${{ inputs.row-format-commit }}
INPUT_ROW_FORMAT_LINK_PR: ${{ inputs.row-format-link-pr }}
INPUT_ROW_FORMAT_LINK_COMMIT: ${{ inputs.row-format-link-commit }}
run: |
python ${{ github.action_path }}/main.py
shell: bash
224 changes: 171 additions & 53 deletions examples/output_example.md

Large diffs are not rendered by default.

37 changes: 34 additions & 3 deletions release_notes_generator/action_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
DUPLICITY_ICON,
ROW_FORMAT_LINK_PR,
ROW_FORMAT_ISSUE,
ROW_FORMAT_PR,
ROW_FORMAT_PR, ROW_FORMAT_COMMIT, ROW_FORMAT_LINK_COMMIT,
)
from release_notes_generator.utils.enums import DuplicityScopeEnum
from release_notes_generator.utils.gh_action import get_action_input
Expand Down Expand Up @@ -176,13 +176,27 @@ def get_row_format_pr() -> str:
"""
return get_action_input(ROW_FORMAT_PR, "#{number} _{title}_ {assignee} {developed-by} {co-authored-by}").strip()

@staticmethod
def get_row_format_commit() -> str:
"""
Get the commit row format for the release notes.
"""
return get_action_input(ROW_FORMAT_COMMIT, "#{sha} {author} {co-authored-by}").strip()

@staticmethod
def get_row_format_link_pr() -> bool:
"""
Get the value controlling whether the row format should include a 'PR:' prefix when linking to PRs.
"""
return get_action_input(ROW_FORMAT_LINK_PR, "true").lower() == "true"

@staticmethod
def get_row_format_link_commit() -> bool:
"""
Get the value controlling whether the row format should include a 'Commit:' prefix when linking to direct commit.
"""
return get_action_input(ROW_FORMAT_LINK_COMMIT, "true").lower() == "true"

@staticmethod
def validate_inputs():
"""
Expand Down Expand Up @@ -230,6 +244,9 @@ def validate_inputs():
row_format_link_pr = ActionInputs.get_row_format_link_pr()
ActionInputs.validate_input(row_format_link_pr, bool, "'row-format-link-pr' value must be a boolean.", errors)

row_format_link_commit = ActionInputs.get_row_format_link_commit()
ActionInputs.validate_input(row_format_link_commit, bool, "'row-format-link-commit' value must be a boolean.", errors)

# Features
print_empty_chapters = ActionInputs.get_print_empty_chapters()
ActionInputs.validate_input(print_empty_chapters, bool, "Print empty chapters must be a boolean.", errors)
Expand All @@ -251,6 +268,12 @@ def validate_inputs():

errors.extend(detect_row_format_invalid_keywords(row_format_pr, row_type="PR"))

row_format_commit = ActionInputs.get_row_format_commit()
if not isinstance(row_format_commit, str) or not row_format_commit.strip():
errors.append("Commit Row format must be a non-empty string.")

errors.extend(detect_row_format_invalid_keywords(row_format_commit, row_type="Commit"))

# Log errors if any
if errors:
for error in errors:
Expand All @@ -260,9 +283,17 @@ def validate_inputs():
logging.debug("Repository: %s/%s", owner, repo_name)
logger.debug("Tag name: %s", tag_name)
logger.debug("Chapters JSON: %s", chapters_json)
logger.debug("Duplication scope: %s", ActionInputs.get_duplicity_scope())
logger.debug("Duplication icon: %s", duplicity_icon)
logger.debug("Warnings: %s", warnings)
logger.debug("Published at: %s", published_at)
logger.debug("Skip release notes label: %s", skip_release_notes_label)
logger.debug("Verbose logging: %s", verbose)
logger.debug("Warnings: %s", warnings)
logger.debug("Print empty chapters: %s", print_empty_chapters)
logger.debug("Chapters to PR without issue: %s", chapters_to_pr_without_issue)
logger.debug("Verbose logging: %s", verbose)
logger.debug("Github repository: %s", repository_id)
logger.debug("Row format issue: %s", row_format_issue)
logger.debug("Row format PR: %s", row_format_pr)
logger.debug("Row format commit: %s", row_format_commit)
logger.debug("Row format link PR: %s", row_format_link_pr)
logger.debug("Row format link commit: %s", row_format_commit)
6 changes: 3 additions & 3 deletions release_notes_generator/model/base_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,10 @@ def get_rls_notes(self, detection_pattern=RELEASE_NOTE_DETECTION_PATTERN, line_m

for line in body_lines:
if detection_pattern in line:
logger.debug("Hello rls notes gen - pr.number %s, line: %s, detection_pattern: %s", pull.number, line, detection_pattern)
inside_release_notes = True

if detection_pattern not in line and inside_release_notes:
if line.startswith(line_mark):
logger.debug("Hello rls notes gen - new line: %s", line)
release_notes += f" {line.strip()}\n"
else:
break
Expand All @@ -267,7 +265,6 @@ def contains_release_notes(self) -> bool:
rls_notes = self.get_rls_notes()
# if RELEASE_NOTE_LINE_MARK in self.get_rls_notes():
if RELEASE_NOTE_LINE_MARK in rls_notes:
logger.debug("DEBUG: Detected rls notes in value: %s", rls_notes)
self.__is_release_note_detected = True

return self.__is_release_note_detected
Expand Down Expand Up @@ -317,6 +314,9 @@ def _get_row_format_values(self, row_format: str) -> dict:
if "{assignees}" in row_format:
assignees = self.assignees
format_values["assignees"] = f"assigned to @{assignees}" if assignees is not None else ""
if "{author}" in row_format:
developers = self.developers
format_values["author"] = f"developed by {developers}" if developers is not None else ""
if "{developed-by}" in row_format:
developers = self.developers
format_values["developed-by"] = f"developed by {developers}" if developers is not None else ""
Expand Down
15 changes: 9 additions & 6 deletions release_notes_generator/model/commit_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def assignees(self) -> Optional[str]:
@property
def developers(self) -> Optional[str]:
"""Get the developers of the record."""
return f"{self.commits[0].author.login}" if self.commits else None
return f"@{self.commits[0].author.login}" if self.commits else None

@property
def contributors(self) -> Optional[str]:
Expand Down Expand Up @@ -131,13 +131,16 @@ def to_chapter_row(self) -> str:
"""
self.increment_present_in_chapters()
row_prefix = f"{ActionInputs.get_duplicity_icon()} " if self.present_in_chapters > 1 else ""
format_values = {
"sha": self.__commit.sha if self.__commit is not None else None,
}

commit_sha = self.__commit.sha if self.__commit is not None else None
row = f"{row_prefix}Commit: {commit_sha} developed by {self.developers}"
format_values.update(self._get_row_format_values(ActionInputs.get_row_format_commit()))

contributors = self.contributors
if contributors:
row += f" co-authored by {contributors}."
prefix = "Commit: " if ActionInputs.get_row_format_link_commit() else ""
row = f"{row_prefix}{prefix}" + ActionInputs.get_row_format_commit().format(**format_values)
if self.contains_release_notes():
row = f"{row}\n{self.get_rls_notes()}"

return row.replace(" ", " ")

Expand Down
6 changes: 5 additions & 1 deletion release_notes_generator/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@
RUNNER_DEBUG = "RUNNER_DEBUG"
ROW_FORMAT_ISSUE = "row-format-issue"
ROW_FORMAT_PR = "row-format-pr"
ROW_FORMAT_COMMIT = "row-format-commit"
ROW_FORMAT_LINK_PR = "row-format-link-pr"
SUPPORTED_ROW_FORMAT_KEYS = ["number", "title", "pull-requests", "assignee", "assignees", "developed-by", "co-authored-by"]
ROW_FORMAT_LINK_COMMIT = "row-format-link-commit"
SUPPORTED_ROW_ISSUE_FORMAT_KEYS = ["number", "title", "pull-requests", "assignee", "assignees", "developed-by", "co-authored-by"]
SUPPORTED_ROW_PR_FORMAT_KEYS = ["number", "title", "assignee", "assignees", "developed-by", "co-authored-by"]
SUPPORTED_ROW_COMMIT_FORMAT_KEYS = ["sha", "author", "co-authored-by"]

# Features
WARNINGS = "warnings"
Expand Down
3 changes: 3 additions & 0 deletions release_notes_generator/utils/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

class NotSupportedException(Exception):
pass
16 changes: 14 additions & 2 deletions release_notes_generator/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
from github.GitRelease import GitRelease
from github.Repository import Repository

from release_notes_generator.utils.constants import SUPPORTED_ROW_FORMAT_KEYS
from release_notes_generator.utils.constants import SUPPORTED_ROW_ISSUE_FORMAT_KEYS, \
SUPPORTED_ROW_PR_FORMAT_KEYS, SUPPORTED_ROW_COMMIT_FORMAT_KEYS
from release_notes_generator.utils.exceptions import NotSupportedException

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -69,7 +71,17 @@ def detect_row_format_invalid_keywords(row_format: str, row_type: str = "Issue")
"""
errors = []
keywords_in_braces = re.findall(r"\{(.*?)\}", row_format)
invalid_keywords = [keyword for keyword in keywords_in_braces if keyword not in SUPPORTED_ROW_FORMAT_KEYS]
match row_type:
case "Issue":
supported_keys = SUPPORTED_ROW_ISSUE_FORMAT_KEYS
case "PR":
supported_keys = SUPPORTED_ROW_PR_FORMAT_KEYS
case "Commit":
supported_keys = SUPPORTED_ROW_COMMIT_FORMAT_KEYS
case _:
raise NotSupportedException(f"Row type '{row_type}' is not supported.")

invalid_keywords = [keyword for keyword in keywords_in_braces if keyword not in supported_keys]
if invalid_keywords:
errors.append(f"Invalid {row_type} row format '{row_format}'. Invalid keyword(s) found: {', '.join(invalid_keywords)}")
return errors

0 comments on commit c118375

Please sign in to comment.