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

Commit parsers to handle merge commit prefixes #540

Open
TGNThump opened this issue Jan 12, 2023 · 9 comments
Open

Commit parsers to handle merge commit prefixes #540

TGNThump opened this issue Jan 12, 2023 · 9 comments
Labels
confirmed Prevent from becoming stale feature A new feature or a feature request

Comments

@TGNThump
Copy link

TGNThump commented Jan 12, 2023

When you merge a PR within Azure DevOps, a prefix (Merged PR 12345:) is added to the commit message unless you manually remove it for every PR, leading to commit messages like:

Merged PR 541234: chore: Improve linting

Is there any way to specify a prefix regex to ignore when parsing commits or any other way to handle this case without requiring contributors to dig into the advanced merge options for every PR?

See conventional-changelog/standard-version#690 for a similar discussion from another project and https://developercommunity.visualstudio.com/t/change-default-title-for-pull-request-commits-to-n-1/365716

@TGNThump TGNThump changed the title Azure DevOps Squash Merge prefixes Azure DevOps merge commit prefixes Jan 12, 2023
@bernardcooke53
Copy link
Contributor

Hi @TGNThump,

Thanks for bringing this up - I don't think this is currently possible, but I think it would be a nice feature to have - a short term workaround would be to write a custom commit parser, but from the issue you referenced above it seems like this is something that multiple VCS do so it would be nice to have that option.

Adding an option to the commit parsers for an "optional merge commit pattern" which can be stripped should manage this.

@bernardcooke53 bernardcooke53 added feature A new feature or a feature request and removed question labels Jan 15, 2023
@bernardcooke53 bernardcooke53 changed the title Azure DevOps merge commit prefixes Commit parsers to handle merge commit prefixes Jan 15, 2023
@manudawber
Copy link

For anyone facing this with GitHub merge commits:

from semantic_release.history import angular_parser
from semantic_release.history.parser_helpers import ParsedCommit

MERGE_COMMIT_PREFIX = "Merge pull request"


def parse_commit_message(message: str) -> ParsedCommit:
    """Extends the `angular_parser` function to work with merge commits.

    Merge commits are not processed by `angular_parser` as they don't adhere to the conventional commit format. Given
    that we enforce pull request titles to follow this format, this custom parser is required to ensure these PR titles
    are usable by `python-semantic-release`.

    If a commit message starts with `MERGE_COMMIT_PREFIX` then it's considered a merge commit and the last line of the
    commit message will be extracted (this should be the original PR title) and sent to `angular_parser`.

    Example merge commit message:

    ```
    Merge pull request #553 from octocat/feature-x

    feat: enable feature X
    ```

    Args:
        message: A git commit message.

    Returns:
        A `ParsedCommit` object containing semantic release version and changelog information.
    """
    message = message.strip()  # remove leading/trailing blank lines
    if message.startswith(MERGE_COMMIT_PREFIX):
        message = message.splitlines()[-1]
    message = message.strip()  # remove leading/trailing whitespace
    return angular_parser(message)

@github-actions github-actions bot added the stale label Mar 26, 2024
@codejedi365 codejedi365 added confirmed Prevent from becoming stale and removed stale labels Mar 29, 2024
Copy link

It has been 60 days since the last update on this confirmed issue. @python-semantic-release/team can you provide an update on the status of this issue?

@github-actions github-actions bot added the needs-update Needs status update from maintainers label May 29, 2024
@codejedi365
Copy link
Contributor

No update yet, still in the backlog

@github-actions github-actions bot removed the needs-update Needs status update from maintainers label May 30, 2024
@lawrenceeldridge
Copy link

lawrenceeldridge commented Jun 2, 2024

Not sure if this helps but ended up creating a custom parser to work with Azure Devops merge commits. Hope this is useful until a dedicated option is available for prefix handling... just note that in this case I am using Poetry with pyproject.toml, so the tag configuration is being retrieved from here.

import re
import toml
import git

from semantic_release import (
    CommitParser,
    ParseResult,
    ParserOptions,
    ParsedCommit,
    LevelBump,
    ParseError,
)
from typing import Optional, Any


class MyParserOptions(ParserOptions):
    def __init__(self, **_: Any):
        # Load whole configuration
        super().__init__(**_)
        pyproject = toml.load("pyproject.toml")

        # Extract commit parsers options
        commit_parser_options = pyproject["tool"]["semantic_release"][
            "commit_parser_options"
        ]

        # Load options as instance variables
        self.allowed_tags = commit_parser_options["allowed_tags"]
        self.minor_tags = commit_parser_options["minor_tags"]
        self.patch_tags = commit_parser_options["patch_tags"]
        self.default_bump_level = LevelBump(commit_parser_options["default_bump_level"])


class MyCommitParser(CommitParser[ParseResult, MyParserOptions]):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.options = MyParserOptions()

    def parse(self, commit: git.objects.commit.Commit) -> Optional[ParseResult]:
        sentences = commit.message.strip().split("\n\n")
        unique_sentences = list(dict.fromkeys(sentences))
        message = "\n\n".join(unique_sentences)
        allowed_tags_regex_part = "|".join(map(re.escape, self.options.allowed_tags))
        match = re.match(
            rf"^.*({allowed_tags_regex_part})(?:\(([^)]+)\))?: (.+)(?:\n|$)([\s\S]*)",
            message,
        )

        if match:
            type_ = match.group(1)
            scope = match.group(2) or ""
            description = match.group(3)
            rest_of_message = match.group(4)

            descriptions = [description]
            breaking_descriptions = []

            for line in rest_of_message.split("\n"):
                line = line.strip()
                if line.startswith("BREAKING CHANGE: "):
                    breaking_descriptions.append(line.replace("BREAKING CHANGE: ", ""))
                elif line != "":
                    descriptions.append(line)

            bump = self.options.default_bump_level
            if breaking_descriptions:
                bump = LevelBump.MAJOR
            elif type_ in self.options.minor_tags:
                bump = LevelBump.MINOR
            elif type_ in self.options.patch_tags:
                bump = LevelBump.PATCH

            return ParsedCommit(
                bump=bump,
                type=type_,
                scope=scope,
                descriptions=descriptions,
                breaking_descriptions=breaking_descriptions,
                commit=commit,
            )

        else:
            return ParseError(commit=commit, error="Could not parse commit message")

Copy link

github-actions bot commented Aug 8, 2024

It has been 60 days since the last update on this confirmed issue. @python-semantic-release/team can you provide an update on the status of this issue?

@github-actions github-actions bot added the needs-update Needs status update from maintainers label Aug 8, 2024
@mikenerone
Copy link

A generalized approach for having different options for what to do with merge commits would be helpful. At my org we annotate each commit fully, so the messages in the merge commits are actually redundant and I'd like to simply skip them when generating the CHANGELOG.

@codejedi365
Copy link
Contributor

@mikenerone, I agree. You can see an example in PSR's project configuration. Merge commits are completely ignored using the changelog.exclude_commit_patterns.

@codejedi365
Copy link
Contributor

Unless there is a compelling reason, I move to close this feature request because ultimately your merge commits are nothing but duplicates of commits already in the git tree. If you are using semantic commits as they are intended then the changes are already documented and merge commits should just be excluded using the pattern matches. I may in the future include a simple Boolean to identify and filter out merge commits but until then the pattern exclusion is the recommended method for handling merge commits in history.

@github-actions github-actions bot removed the needs-update Needs status update from maintainers label Aug 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed Prevent from becoming stale feature A new feature or a feature request
Projects
None yet
Development

No branches or pull requests

6 participants