Skip to content

Commit

Permalink
feat: Support special github scenarios via configuration (#52)
Browse files Browse the repository at this point in the history
Define behaviour for stripping PR information from github descriptions.
Extract PR information as a footer, and extract common github keywords
as footers.

closes #50
  • Loading branch information
EdgyEdgemond authored Aug 23, 2024
1 parent 632634d commit 69d5002
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 40 deletions.
21 changes: 17 additions & 4 deletions changelog_gen/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@

FOOTER_PARSERS = [
r"(Refs)(: )(#?[\w-]+)",
# TODO(edgy): Parse github behind a github config
# https://github.com/NRWLDev/changelog-gen/issues/50
r"(closes)( )(#[\w-]+)",
r"(fixes)( )(#[\w-]+)",
r"(Authors)(: )(.*)",
]

Expand All @@ -51,6 +47,15 @@ class PostProcessConfig:
auth_env: str | None = None


@dataclasses.dataclass
class GithubConfig:
"""Github specific helpers."""

strip_pr_from_description: bool = False
extract_pr_from_description: bool = False
extract_common_footers: bool = False


STRICT_VALIDATOR = re.compile(
r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?$",
)
Expand Down Expand Up @@ -88,6 +93,9 @@ class Config:
# Version bumping
files: dict = dataclasses.field(default_factory=dict)

# Github helpers
github: GithubConfig | None = None

# Changelog configuration
date_format: str | None = None
version_string: str = "v{new_version}"
Expand Down Expand Up @@ -186,6 +194,7 @@ def _process_pyproject(pyproject: Path) -> dict:
data["tool"]["changelog_gen"]["footer_parsers"] = footer_parsers
data["tool"]["changelog_gen"]["commit_types"] = commit_types
data["tool"]["changelog_gen"]["type_headers"] = type_headers

return data["tool"]["changelog_gen"]


Expand Down Expand Up @@ -227,6 +236,10 @@ def read(path: str = "pyproject.toml", **kwargs) -> Config:
msg = f"Failed to create post_process: {e!s}"
raise RuntimeError(msg) from e

if "github" in cfg:
github = GithubConfig(**cfg["github"])
cfg["github"] = github

try:
return Config(**cfg)
except TypeError as e:
Expand Down
22 changes: 20 additions & 2 deletions changelog_gen/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,12 @@ def extract(self: t.Self) -> list[Change]: # noqa: C901, PLR0912, PLR0915
prm = re.search(r"\(#\d+\)$", description)
if prm is not None:
# Strip githubs additional link information from description.
description = re.sub(r" \(#\d+\)$", "", description)
footers["pr"] = Footer("PR", ": ", prm.group()[1:-1])
if self.context.config.github and self.context.config.github.strip_pr_from_description:
description = re.sub(r" \(#\d+\)$", "", description)

if self.context.config.github and self.context.config.github.extract_pr_from_description:
footers["pr"] = Footer("PR", ": ", prm.group()[1:-1])

details = m[5] or ""

# Handle missing refs in commit message, skip link generation in writer
Expand All @@ -118,6 +122,20 @@ def extract(self: t.Self) -> list[Change]: # noqa: C901, PLR0912, PLR0915
if breaking:
self.context.info(" Breaking change detected:\n %s: %s", commit_type, description)

footer_parsers = self.context.config.footer_parsers
if self.context.config.github and self.context.config.github.extract_common_footers:
footer_parsers.extend([
r"(close)( )(#[\w-]+)",
r"(closes)( )(#[\w-]+)",
r"(closed)( )(#[\w-]+)",
r"(fix)( )(#[\w-]+)",
r"(fixes)( )(#[\w-]+)",
r"(fixed)( )(#[\w-]+)",
r"(resolve)( )(#[\w-]+)",
r"(resolves)( )(#[\w-]+)",
r"(resolved)( )(#[\w-]+)",
])

for line in details.split("\n"):
for parser in self.context.config.footer_parsers:
m = re.match(parser, line, re.IGNORECASE)
Expand Down
46 changes: 46 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,52 @@ pre_l = ["dev", "rc"]
Enforce strict rules based on SemVer 2.0.0 and error if non conforming parser or
serialisers are configured.


## Github

### `strip_pr_from_description`
_**[optional]**_<br />
**default**: False

Strip the `(#\d+)` from the end of github PR commit descriptions.

Example:

```toml
[tool.changelog_gen.github]
strip_pr_from_description = true
```

### `extract_pr_from_description`
_**[optional]**_<br />
**default**: False

Extract the `(#\d+)` from the end of github PR commit descriptions, and track
it as a footer for later extraction and link generation. Creates a `PR` footer entry.

Example:

```toml
[tool.changelog_gen.github]
extract_pr_from_description = true
```

### `extract_common_footers`
_**[optional]**_<br />
**default**: False

Extract supported keyword footers from github commits, `closes #1` etc.

Supported footers can be found
[here](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).

Example:

```toml
[tool.changelog_gen.github]
extract_common_footers = true
```

## Post processing

### `post_process`
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ allowed_branches = [
]
date_format = "- %Y-%m-%d"

[tool.changelog_gen.github]
strip_pr_from_description = true
extract_pr_from_description = true
extract_common_footers = true

[[tool.changelog_gen.extractors]]
footer = ["closes", "fixes", "Refs"]
pattern = '#(?P<issue_ref>\d+)'
Expand Down
2 changes: 0 additions & 2 deletions tests/cli/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ def test_config_displayed(cli_runner):
serialisers = ['{major}.{minor}.{patch}']
footer_parsers = [
'(Refs)(: )(#?[\w-]+)',
'(closes)( )(#[\w-]+)',
'(fixes)( )(#[\w-]+)',
'(Authors)(: )(.*)',
]
extractors = []
Expand Down
19 changes: 19 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,25 @@ def test_read_picks_up_type_headers(self, config_factory):
"test": "Miscellaneous",
}

def test_read_picks_up_github_config(self, config_factory):
config_factory(
"""
[tool.changelog_gen]
current_version = "0.0.0"
[tool.changelog_gen.github]
strip_pr_from_description = true
extract_pr_from_description = true
extract_common_footers = true
""",
)

c = config.read()
assert c.github == config.GithubConfig(
strip_pr_from_description=True,
extract_pr_from_description=True,
extract_common_footers=True,
)


class TestPostProcessConfig:
def test_read_picks_up_no_post_process_config(self, config_factory):
Expand Down
Loading

0 comments on commit 69d5002

Please sign in to comment.