Skip to content

Single-package node repo with include-component-in-tag:false deadlocks on tagging — empty component override ignored #1205

Description

@Eleazar-Harold

TL;DR

For a single-package node repo with include-component-in-tag: false, release-please-action never tags or releases the merged release PR, even though the PR is correctly labeled autorelease: pending. The release-build phase logs:

⚠ PR component: undefined does not match configured component: <package.json#name>

and then the pull-request-build phase logs:

⚠ There are untagged, merged release PRs outstanding - aborting

The deadlock is unrecoverable through config and recurs on every push. Setting component: "" on the package, removing package-name, and setting pull-request-title-pattern explicitly all fail to break it.

Expected behaviour

When a release PR (labeled autorelease: pending) is merged to main, the next workflow run should:

  1. Detect the merged-but-untagged PR
  2. Create the git tag (v<version>)
  3. Create the GitHub Release
  4. Update the label from autorelease: pending to autorelease: tagged

… for a single-package repo regardless of whether package.json#name matches an empty/unset component config.

Observed behaviour

Action SHA: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 (v5.0.0)
release-please version (logged by the action): 17.6.0

Two consecutive release cycles (v1.1.0 and v1.1.1) on the same single-package repo each opened a release PR correctly, but on merge the action refused to tag:

✔ Building releases
✔ Building strategies by path
❯ .: node
❯ Found pull request #10: 'chore: release main'
✔ Building release for path: .
❯ type: node
⚠ pullRequestTitlePattern miss the part of '${scope}'
⚠ pullRequestTitlePattern miss the part of '${component}'
❯ targetBranch: main
❯ Fetching package.json from branch main
⚠ PR component: undefined does not match configured component: kujali-chatcare
…
✔ Collecting commits since all latest releases
❯ looking for tagName: v1.1.1
…
⚠ There are untagged, merged release PRs outstanding - aborting

Both releases had to be tagged manually (gh release create vX.Y.Z --target <merge-sha> …) and then the label flipped to autorelease: tagged to break the loop.

Reproduction

release-please-config.json:

{
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
  "include-component-in-tag": false,
  "include-v-in-tag": true,
  "pull-request-title-pattern": "chore: release ${version}",
  "packages": {
    ".": {
      "release-type": "node",
      "changelog-path": "CHANGELOG.md",
      "component": ""
    }
  }
}

.release-please-manifest.json:

{ ".": "1.0.0" }

package.json:

{ "name": "kujali-chatcare", "version": "1.0.0", }

Workflow trigger: push to main, single job using the SHA above. Token is a classic PAT with repo + workflow scopes (the org has fine-grained PATs disabled).

Steps:

  1. Push commits with feat: / fix: types to main.
  2. release-please opens a release PR titled chore: release main, with label autorelease: pending.
  3. Merge the PR (squash).
  4. Next push triggers release-please again — but instead of tagging the merged PR, it logs the component-mismatch warning and aborts.

What I tried

Attempt Result
Default config with package-name: "kujali-chatcare" Component mismatch (undefined ≠ kujali-chatcare), abort
Removed package-name from the package config Same — the node strategy still derives the component from package.json#name
Added component: "" to the package config Same — empty string is silently ignored, derived component still used
Added pull-request-title-pattern: "chore: release ${version}" at top level Pattern ignored; PR title remains chore: release main; same abort

Root cause hypothesis

The node release-type derives an implicit component from package.json#name. When include-component-in-tag: false is set, the resulting release PR title (chore: release main — no ${component} segment) does not encode the component. But on subsequent runs the release-build phase still checks PR.component (parsed from title → undefined) against package.component (derived → kujali-chatcare). The mismatch makes release-build skip the tagging path, the pull-request-build phase sees the merged-but-untagged PR, and the whole run aborts.

An explicit empty-string component: "" ought to override the derived value, but in release-please@17.6.0 it appears to be discarded (either by the ?? fallback to the strategy's derived component or by JSON parsing).

Workaround

Manual tag + release on each merge, then re-label:

gh release create v1.1.1 --target <merge-sha> --title "v1.1.1" --notes-file <changelog-extract>
gh pr edit <pr#> --remove-label "autorelease: pending" --add-label "autorelease: tagged"

This works because once the PR is labeled autorelease: tagged, release-please ignores it on the next run and stops the abort loop. But the manual step defeats the whole point of the action.

Proposed fix

Either:

  • (a) Honour explicit empty-string component on a package config, so single-package repos with include-component-in-tag: false can opt out of component matching entirely; OR
  • (b) Skip component matching when include-component-in-tag: false — if the tag isn't going to encode the component, the PR title shouldn't need to either, so the comparison is moot; OR
  • (c) Detect single-package configs (packages has exactly one entry at .) and apply (b) automatically.

Happy to PR (b) or (c) if either is the preferred direction.

Environment

  • Repo: single-package, single-path (.), release-type: node
  • Org: fine-grained PAT requests disabled at org level → classic PAT used
  • Action version: release-please-action@45996ed… (v5.0.0)
  • release-please CLI version (per action log): 17.6.0
  • package.json#name: kujali-chatcare
  • include-component-in-tag: false
  • include-v-in-tag: true

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions