Skip to content

[BUG] fails to parse commits with nested parentheses #2878

Description

@jguddas

Description

Conventional commit parsing in release-please can misbehave or fail when a commit or it's body contains nested parentheses, such as code references or function calls (e.g., Foo.Bar(baz(abc))). This issue is particularly notable in GitHub squash merge commits where nested parentheses are nested inside squashed comments or split commits in the message body.

Test Cases

Here are the test cases that demonstrate the desired behavior:

  it('handles commits with nested parentheses in body', async () => {
    const commits = [
      buildMockCommit(
        'feat: something\n\nFoo.Bar(baz(abc)). Some trailing text.'
      ),
    ];
    const conventionalCommits = parseConventionalCommits(commits);
    expect(conventionalCommits).lengthOf(1);
    expect(conventionalCommits[0].type).to.equal('feat');
  });

  it('handles a GitHub squash merge commit with nested parentheses inside squashed comments in the body', async () => {
    const squashCommitMessage = 
      'feat(scope): some message (#123)\n\n' +
      '* refactor(subscope): first squashed change\n\n' +
      'Some details here.\n\n' +
      '* refactor(subscope): second squashed change\n\n' +
      'Foo.Bar(baz(abc)). More details.';

    const commits = [buildMockCommit(squashCommitMessage)];
    const conventionalCommits = parseConventionalCommits(commits);
    expect(conventionalCommits).lengthOf(1);
    expect(conventionalCommits[0].type).to.equal('feat');
    expect(conventionalCommits[0].scope).to.equal('scope');
  });

  it('handles a squash merge with split commits that contain a nested parenthesis commit', async () => {
    const squashSplitMessage = 
      'feat(scope): some message (#123)\n\n' +
      'refactor(subscope): first squashed change\n\n' +
      'Some details here.\n\n' +
      'refactor(subscope): second squashed change\n\n' +
      'Foo.Bar(baz(abc)). More details.';

    const commits = [buildMockCommit(squashSplitMessage)];
    const conventionalCommits = parseConventionalCommits(commits);
    expect(conventionalCommits).lengthOf(3);
    expect(conventionalCommits[0].type).to.equal('feat');
    expect(conventionalCommits[1].type).to.equal('refactor');
    expect(conventionalCommits[2].type).to.equal('refactor');
  });

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions