googleapis / googleapis/release-please

[BUG] fails to parse commits with nested parentheses

Open Beginner friendly
#2,878 1 comment 2 reactions 0 assignees View on GitHub
priority: p2 type: bug
Dominant language
TypeScript
Stars
7.5k
Forks
588
Avg merge
12h 16m
Merged PRs (30d)
7

Description

### 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:

```typescript
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');
});
```

Contributor guide

Open the contributing guide

Research direction

Start at the parseConventionalCommits entry point and inspect the existing tests that use buildMockCommit. Add the three supplied cases for nested parentheses in regular and squash-merge commit bodies, then run the parser test suite and confirm the expected commit counts, types, and scope are preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
release, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.