googleapis / googleapis/release-please

Regression: `<...>` inside inline code spans in commit subjects still break PR-body parsing, silently skipping a component release (manifest mode)

Open
#2,801 2 comments 0 reactions 1 assignee Claimed by @chingor13 View on GitHub
priority: p3 type: bug
Dominant language
TypeScript
Stars
7.5k
Forks
588
Avg merge
12h 16m
Merged PRs (30d)
7

Description

This is a regression / incomplete fix of #1659 (fixed by #1661). HTML tags inside **inline code spans** in commit subjects are intentionally left unescaped by `htmlEscape`, but they still break the PR-body re-parsing step, causing a component's release to be silently skipped.

### Environment
- `release-please` **17.6.0** (`googleapis/release-please-action@v5`)
- Manifest mode, multi-package monorepo, `include-component-in-tag: true`

### Root cause
- `src/changelog-notes/default.ts` `htmlEscape()` escapes bare `<`/`>`, but via the regex `` /``[^`].*[^`]``|`[^`]*`|<|>/g `` with `match.length > 1 ? match : ...` it leaves `<`/`>` **inside inline code spans untouched**. So a subject like ``add `check --report ` `` keeps a **raw ``** in the generated release-PR body.
- On release creation, `src/util/pull-request-body.ts` `extractMultipleReleases()` re-parses the PR body with `node-html-parser`. It does not understand markdown backticks, so `` is treated as an unclosed HTML tag and the following `` block(s) get nested inside it and dropped from `root.getElementsByTagName('details')` — the exact mechanism described in #1659.
- `src/strategies/base.ts` then logs `Pull request contains releases, but not for component: ` and skips that component: **no git tag, no GitHub release, no publish** — while the workflow still reports success.
- The next release-please run can no longer find that component's release boundary (tag missing) and re-walks its **entire history**, producing a bogus major bump in the next release PR.

### Steps to reproduce
1. In a manifest repo with ≥2 packages, land a commit whose subject contains an inline code span with an HTML-tag-looking token, e.g. ``feat: add `--report ` flag`` (affecting multiple packages so it appears in multiple `` blocks).
2. Merge the release PR.
3. Observe that the component carrying the 2nd occurrence is not released (no tag/release/publish), though the run succeeds.

### Minimal reproduction
```js
// npm i release-please@17.6.0
const { PullRequestBody } = require('release-please/build/src/util/pull-request-body.js');
const body = [
':robot: release', '---', '',
'pkg-a: 1.0.0\n\n### Features\n\n* add `--report ` flag\n',
'pkg-b: 2.0.0\n\n### Features\n\n* add `--report ` flag\n',
'---', 'footer',
].join('\n');

console.log(PullRequestBody.parse(body).releaseData.map(d => d.component));
// => [ 'pkg-a' ] <-- pkg-b silently dropped

console.log(PullRequestBody.parse(body.replaceAll('', '<path>')).releaseData.map(d => d.component));
// => [ 'pkg-a', 'pkg-b' ] <-- escaping the angle brackets fixes it
```
Real-world case: an 11-package release PR dropped exactly the package whose `` block contained the 2nd `` occurrence.

### Suggested fix
Since the PR body is later **HTML-parsed** (not rendered as markdown), `<`/`>` should be escaped even when inside code spans when generating the body. Alternatively, make `extractMultipleReleases` extract `` blocks robustly so an unclosed tag in note text cannot corrupt the DOM and drop sibling blocks.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.