Release notes: packages sharing one sourceUrl lose their notes and can be attributed to the wrong package #46302
Replies: 3 comments
|
Thanks for the report - please re-shape it into our template so it's easier for us to triage! |
|
Hi there, |
|
Reshaped into the template - thanks. Renovate 44.96.2, self-hosted CLI on GitLab. Our repos are private so I could not attach a public reproduction; I added the reproduction shape and a rendered PR body showing both symptoms instead, and I am happy to do a |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
How are you running Renovate?
Self-hosted Renovate CLI
Which platform you running Renovate on?
GitLab (.com or self-hosted)
Which version of Renovate are you using?
44.96.2
Please tell us more about your question or problem
When several dependencies in one PR resolve to the same
sourceUrl— the normal case for a monorepo that publishes many independently-versioned packages — Renovate treats them as one package for release-notes purposes. Two independent places key on the repository rather than on the package, which produces two distinct user-visible bugs.Bug 1 — only the first package's release notes are rendered.
lib/workers/repository/update/pr/index.ts:Without
sourceDirectorythe key is justrepoName, so the first upgrade claims the repo and every subsequent upgrade from it is left withhasReleaseNotes = falseandreleases = [], logged asRemoving duplicate release notesby the second pass keyed onnotesSourceUrl. Sincechangelog/hbs-template.tsonly emits a<details>per upgrade withhasReleaseNotes, the other packages disappear from the PR body — even though their releases exist and were fetched successfully.This looks intentional for deps that genuinely share one changelog, but it is wrong when the deps are distinct packages that merely share a source repo.
Bug 2 — release notes can be attributed to the wrong package.
lib/workers/repository/update/pr/changelog/release-notes.ts, inaddReleaseNotes():The key has no package component, so two packages from the same repo that share a version number collide, and whichever populates the cache first wins for both.
This is worse than cosmetic: the notes shown are plausible but belong to another package. In our case a major bump of
@scope/apidisplayed another package'sBREAKING CHANGESsection under@scope/api's version headings, with anchors pointing at the other package's tags. A reviewer reading the PR to decide whether a major bump is safe is reading the wrong package's breaking changes.Note
getReleaseNotes()itself resolves this correctly —getExactReleaseMatch()builds a package-qualified tag regex — so the wrong result comes purely from the cache short-circuiting before that runs.Why this is not more widely reported: in a fixed-version monorepo (all packages released together at the same version, one changelog) both bugs are invisible — the de-duplicated notes really are duplicates, and the colliding cache entries really are identical. They only become visible with independent versioning (Lerna
version: independent), where@scope/a@2.0.2and@scope/b@2.0.2are unrelated releases with different bodies and different tags.Suggested fix — include the package in both keys:
getRepoNameWithSourceDirectory()→ appendpackageName/depName, or fall back to it whensourceDirectoryis unset, so per-package notes survive de-duplication while genuinely duplicate changelogs still collapse.cacheKeyPrefixinaddReleaseNotes()→ includepackageName, so cached notes cannot leak across packages sharing a repo and a version number.Happy to open a PR if you agree on the shape.
Workaround we deployed: setting
sourceDirectoryper package viapackageRules, since it is the discriminator in both keys. It issupportsTemplating: trueand compiled inworkers/repository/updates/flatten.ts, so it can be derived rather than listed:{ "matchDatasources": ["npm"], "matchPackagePrefixes": ["@scope/"], "sourceUrl": "https://gitlab.com/org/monorepo", "sourceDirectory": "{{{replace '@scope/' 'packages/' packageName}}}" }This is a workaround rather than a fix: it overloads a field meaning "where the package lives in the repo" into "cache/dedup discriminator", it changes changelog-file lookup as a side effect, and it only works where the directory layout is derivable from the package name.
Reproduction shape (our repos are private, so this is a description rather than a link): a Lerna monorepo with
"version": "independent"publishing N packages, each release tagged@scope/<pkg>@<version>with a matching GitLab Release. A consumer repo depends on three of them and groups them into one PR viapackageRules.sourceUrlis set for the whole scope inpackageRules, because GitLab's npm registry serves only the abbreviated packument (Packages::Npm::GenerateMetadataService::PACKAGE_JSON_ALLOWED_FIELDS) and therefore omitsrepository, so it cannot be derived from the npm datasource. Result: one<details>block instead of three, and version numbers that exist in two packages render the wrong package's body. The shared-sourceUrlcondition is what matters, not GitLab specifically.Logs (if relevant)
Our CI runs Renovate at the default
infolevel, so theRemoving duplicate release notesdebug line is not captured. The evidence below is the rendered PR body, which shows both bugs at once — I can produce aLOG_LEVEL=debugrun if that would help.Rendered PR body — three grouped majors, one notes block, wrong attribution
@scope/apihas its own2.0.0/2.0.1/2.0.2releases with different bodies; they were never shown.@scope/biapp-entitiesand@scope/logginghave complete GitLab Releases for every version in range and got no block at all.All reactions