diff --git a/.changeset/swift-modules-changelog.md b/.changeset/swift-modules-changelog.md new file mode 100644 index 0000000..b71813c --- /dev/null +++ b/.changeset/swift-modules-changelog.md @@ -0,0 +1,5 @@ +--- +"changesets": minor +--- + +Add support for per-module changelogs, so each sub-module in a multi-module Maven project can maintain its own `CHANGELOG.md` instead of sharing a single aggregated one. diff --git a/README.md b/README.md index 951a0d1..dc3454e 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,31 @@ independent mode, the BOM's pom is left untouched (version *and* pinned properti standard per-module sections. The `bom` block in `.changeset/config.json` stays in place — `skipBom` is a per-run override, not a config change. Use it when you want to ship a quick starter patch between full BOM releases. +## Per-module changelogs + +By default the release block is prepended to a single `CHANGELOG.md` at the reactor root. With `independent` versioning you +can instead emit one `CHANGELOG.md` per bumped submodule by setting `changelog: "module"`: + +```json +{ + "versioning": "independent", + "changelog": "module" +} +``` + +Behavior: + +- Each module that bumps gets its own `CHANGELOG.md` next to its `pom.xml`, containing only that module's changes. +- Modules without changesets for the release are skipped — no empty file is created. +- No reactor-root `CHANGELOG.md` is written. Any existing root `CHANGELOG.md` is left untouched. +- If a [BOM](#bom-bill-of-materials-support) is also configured, the reactor-root `CHANGELOG.md` is *additionally* written as + a rollup summary — one entry per bumped module under a single `consumer-parent@` header, with each module's + changes nested below — so consumers see a dependabot-style overview of what moved in that BOM release while the + authoritative per-module history lives next to each module. + +`changelog: "module"` requires `versioning: "independent"`; combining it with `fixed` is a config validation error, since all +modules would share one version anyway. Omitting `changelog` keeps the previous behavior (a single root `CHANGELOG.md`). + ## How `prepare` and `release` interact `changesets:prepare` (aggregator goal, runs once at the reactor root) reads all changesets in `.changeset/`, computes a new @@ -181,4 +206,6 @@ in history instead of two. If you'd rather have `changesets:prepare` update the poms itself (e.g. to inspect them before triggering the release-plugin), omit `useReleasePluginIntegration`. The trade-off is an extra "chore: prepare release" commit -before `release:prepare` runs. \ No newline at end of file +before `release:prepare` runs. + +## Configuration reference diff --git a/changesets-java/src/main/java/se/fortnox/changesets/ChangesetsConfig.java b/changesets-java/src/main/java/se/fortnox/changesets/ChangesetsConfig.java index 1f300b5..a7e29fd 100644 --- a/changesets-java/src/main/java/se/fortnox/changesets/ChangesetsConfig.java +++ b/changesets-java/src/main/java/se/fortnox/changesets/ChangesetsConfig.java @@ -31,6 +31,7 @@ public record ChangesetsConfig( fixed = fixed == null ? List.of() : List.copyOf(fixed); changelog = changelog == null ? ChangelogMode.ROOT : changelog; validateGroupsAreDisjoint(linked, fixed); + validateChangelogModeAgainstVersioning(versioning, changelog); } public static ChangesetsConfig defaults() { @@ -55,6 +56,14 @@ public static ChangesetsConfig load(Path changesetsDir) { } } + private static void validateChangelogModeAgainstVersioning(VersioningStrategy versioning, ChangelogMode changelog) { + if (changelog == ChangelogMode.MODULE && versioning == VersioningStrategy.FIXED) { + throw new IllegalArgumentException( + "changelog mode 'module' requires versioning 'independent'; " + + "with 'fixed' versioning all modules share a single version, so per-module changelogs are not meaningful"); + } + } + private static void validateGroupsAreDisjoint(List> linked, List> fixed) { Set seen = new HashSet<>(); List> allGroups = new ArrayList<>(linked.size() + fixed.size()); @@ -87,8 +96,20 @@ public static VersioningStrategy fromString(String value) { } } + /** + * Where release changelog entries are written. + * + *
    + *
  • {@code ROOT} (default): a single aggregated {@code CHANGELOG.md} at the reactor root.
  • + *
  • {@code MODULE}: each bumped module gets its own {@code CHANGELOG.md} next to its + * {@code pom.xml}. When a BOM is configured, the reactor-root {@code CHANGELOG.md} is + * additionally written as a rollup summarising the per-module bumps for that BOM version. + * Requires {@code versioning: independent}.
  • + *
+ */ public enum ChangelogMode { - @JsonProperty("root") ROOT; + @JsonProperty("root") ROOT, + @JsonProperty("module") MODULE; @JsonCreator public static ChangelogMode fromString(String value) { @@ -97,6 +118,7 @@ public static ChangelogMode fromString(String value) { } return switch (value.toLowerCase()) { case "root" -> ROOT; + case "module" -> MODULE; default -> throw new IllegalArgumentException("Unknown changelog mode: " + value); }; } diff --git a/changesets-java/src/test/java/se/fortnox/changesets/ChangesetsConfigTest.java b/changesets-java/src/test/java/se/fortnox/changesets/ChangesetsConfigTest.java index 1c78900..16c543e 100644 --- a/changesets-java/src/test/java/se/fortnox/changesets/ChangesetsConfigTest.java +++ b/changesets-java/src/test/java/se/fortnox/changesets/ChangesetsConfigTest.java @@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static se.fortnox.changesets.ChangesetsConfig.ChangelogMode.MODULE; import static se.fortnox.changesets.ChangesetsConfig.ChangelogMode.ROOT; import static se.fortnox.changesets.ChangesetsConfig.VersioningStrategy.FIXED; import static se.fortnox.changesets.ChangesetsConfig.VersioningStrategy.INDEPENDENT; @@ -107,6 +108,20 @@ void appliesDefaultsForMissingFields() throws IOException { assertThat(config.changelog()).isEqualTo(ROOT); } + @Test + void parsesModuleChangelogMode() throws IOException { + Files.writeString(tempDir.resolve("config.json"), """ + { + "versioning": "independent", + "changelog": "module" + } + """); + + var config = ChangesetsConfig.load(tempDir); + + assertThat(config.changelog()).isEqualTo(MODULE); + } + @Test void returnsDefaultsOnMalformedJson() throws IOException { Files.writeString(tempDir.resolve("config.json"), "not json {"); @@ -143,6 +158,20 @@ void rejectsModuleInBothLinkedAndFixed() { .hasMessageContaining("pkg-a"); } + @Test + void rejectsModuleChangelogWithFixedVersioning() { + assertThatThrownBy(() -> new ChangesetsConfig(FIXED, List.of(), List.of(), MODULE, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("module"); + } + + @Test + void allowsModuleChangelogWithIndependentVersioning() { + var config = new ChangesetsConfig(INDEPENDENT, List.of(), List.of(), MODULE, null); + + assertThat(config.changelog()).isEqualTo(MODULE); + } + @Test void allowsDistinctGroups() { var config = new ChangesetsConfig( diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/bump-a.md b/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/bump-a.md new file mode 100644 index 0000000..ba49566 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/bump-a.md @@ -0,0 +1,5 @@ +--- +"starter-a": minor +--- + +Added starter-a feature diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/bump-b.md b/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/bump-b.md new file mode 100644 index 0000000..69bace5 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/bump-b.md @@ -0,0 +1,5 @@ +--- +"starter-b": patch +--- + +Tiny starter-b fix diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/config.json b/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/config.json new file mode 100644 index 0000000..0a351f0 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/.changeset/config.json @@ -0,0 +1,8 @@ +{ + "versioning": "independent", + "changelog": "module", + "bom": { + "module": "bom", + "consumerParent": "consumer-parent" + } +} diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/EXPECTED_CHANGELOG.md b/changesets-maven-plugin/src/it/module-changelog-bom/EXPECTED_CHANGELOG.md new file mode 100644 index 0000000..069ec2d --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/EXPECTED_CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +## consumer-parent@0.4.0 + +### starter-a@2.1.0 + +#### Minor Changes + +- Added starter-a feature + +### starter-b@3.0.1 + +#### Patch Changes + +- Tiny starter-b fix + +### bom@0.4.0 + +#### Pinned version updates + +- starter-a@2.1.0 +- starter-b@3.0.1 + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/bom/pom.xml b/changesets-maven-plugin/src/it/module-changelog-bom/bom/pom.xml new file mode 100644 index 0000000..6ad3285 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/bom/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + se.fortnox.maven.it + module-changelog-bom-root + 1.0.0 + + + bom + 0.3.0 + pom + + + 2.0.0 + 3.0.0 + + + + + + se.fortnox.maven.it + starter-a + ${starter-a.version} + + + se.fortnox.maven.it + starter-b + ${starter-b.version} + + + + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/consumer-parent/pom.xml b/changesets-maven-plugin/src/it/module-changelog-bom/consumer-parent/pom.xml new file mode 100644 index 0000000..c359d9c --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/consumer-parent/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + se.fortnox.maven.it + bom + 0.3.0 + ../bom + + + consumer-parent + pom + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/invoker.properties b/changesets-maven-plugin/src/it/module-changelog-bom/invoker.properties new file mode 100644 index 0000000..dce7e2c --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/invoker.properties @@ -0,0 +1 @@ +invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:prepare diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/pom.xml b/changesets-maven-plugin/src/it/module-changelog-bom/pom.xml new file mode 100644 index 0000000..eb8d6de --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + se.fortnox.maven.it + module-changelog-bom-root + 1.0.0 + pom + + IT: BOM + per-module changelogs, with root CHANGELOG.md rollup. + + + UTF-8 + + + bom + consumer-parent + starter-a + starter-b + + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/starter-a/EXPECTED_CHANGELOG.md b/changesets-maven-plugin/src/it/module-changelog-bom/starter-a/EXPECTED_CHANGELOG.md new file mode 100644 index 0000000..40483fc --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/starter-a/EXPECTED_CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## starter-a@2.1.0 + +### Minor Changes + +- Added starter-a feature + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/starter-a/pom.xml b/changesets-maven-plugin/src/it/module-changelog-bom/starter-a/pom.xml new file mode 100644 index 0000000..f75b721 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/starter-a/pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + se.fortnox.maven.it + module-changelog-bom-root + 1.0.0 + + + starter-a + 2.0.0 + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/starter-b/EXPECTED_CHANGELOG.md b/changesets-maven-plugin/src/it/module-changelog-bom/starter-b/EXPECTED_CHANGELOG.md new file mode 100644 index 0000000..fc2fde6 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/starter-b/EXPECTED_CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## starter-b@3.0.1 + +### Patch Changes + +- Tiny starter-b fix + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/starter-b/pom.xml b/changesets-maven-plugin/src/it/module-changelog-bom/starter-b/pom.xml new file mode 100644 index 0000000..1ee1cf3 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/starter-b/pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + se.fortnox.maven.it + module-changelog-bom-root + 1.0.0 + + + starter-b + 3.0.0 + diff --git a/changesets-maven-plugin/src/it/module-changelog-bom/verify.groovy b/changesets-maven-plugin/src/it/module-changelog-bom/verify.groovy new file mode 100644 index 0000000..894e190 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog-bom/verify.groovy @@ -0,0 +1,36 @@ +import groovy.xml.XmlSlurper + +import static org.assertj.core.api.Assertions.assertThat + +def versions = new File(basedir, '.changeset/VERSIONS').text +assertThat(versions).contains("starter-a=2.1.0") +assertThat(versions).contains("starter-b=3.0.1") +assertThat(versions).contains("bom=0.4.0") + +// BOM bumped to next-dev SNAPSHOT, properties rewritten +def bom = new XmlSlurper().parse(new File(basedir, 'bom/pom.xml')) +assertThat(bom.version).isEqualTo('0.4.1-SNAPSHOT') +assertThat(bom.properties.'starter-a.version'.text()).isEqualTo('2.1.1-SNAPSHOT') +assertThat(bom.properties.'starter-b.version'.text()).isEqualTo('3.0.2-SNAPSHOT') + +// Starters bumped to their own next-dev SNAPSHOTs +def starterA = new XmlSlurper().parse(new File(basedir, 'starter-a/pom.xml')) +assertThat(starterA.version).isEqualTo('2.1.1-SNAPSHOT') + +def starterB = new XmlSlurper().parse(new File(basedir, 'starter-b/pom.xml')) +assertThat(starterB.version).isEqualTo('3.0.2-SNAPSHOT') + +// Per-module changelogs written next to each starter's pom +assertThat(new File(basedir, 'starter-a/CHANGELOG.md')) + .hasSameTextualContentAs(new File(basedir, 'starter-a/EXPECTED_CHANGELOG.md')) +assertThat(new File(basedir, 'starter-b/CHANGELOG.md')) + .hasSameTextualContentAs(new File(basedir, 'starter-b/EXPECTED_CHANGELOG.md')) + +// No bom/CHANGELOG.md when BOM has no explicit changesets of its own +assertThat(new File(basedir, 'bom/CHANGELOG.md')).doesNotExist() + +// Root CHANGELOG.md = the BOM rollup summary +assertThat(new File(basedir, 'CHANGELOG.md')) + .hasSameTextualContentAs(new File(basedir, 'EXPECTED_CHANGELOG.md')) + +true diff --git a/changesets-maven-plugin/src/it/module-changelog/.changeset/bump-a.md b/changesets-maven-plugin/src/it/module-changelog/.changeset/bump-a.md new file mode 100644 index 0000000..4ae38ea --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/.changeset/bump-a.md @@ -0,0 +1,5 @@ +--- +"module-a": minor +--- + +Added module-a feature diff --git a/changesets-maven-plugin/src/it/module-changelog/.changeset/bump-b.md b/changesets-maven-plugin/src/it/module-changelog/.changeset/bump-b.md new file mode 100644 index 0000000..1881197 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/.changeset/bump-b.md @@ -0,0 +1,5 @@ +--- +"module-b": patch +--- + +Tiny module-b fix diff --git a/changesets-maven-plugin/src/it/module-changelog/.changeset/config.json b/changesets-maven-plugin/src/it/module-changelog/.changeset/config.json new file mode 100644 index 0000000..5eb984c --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/.changeset/config.json @@ -0,0 +1,4 @@ +{ + "versioning": "independent", + "changelog": "module" +} diff --git a/changesets-maven-plugin/src/it/module-changelog/invoker.properties b/changesets-maven-plugin/src/it/module-changelog/invoker.properties new file mode 100644 index 0000000..dce7e2c --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/invoker.properties @@ -0,0 +1 @@ +invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:prepare diff --git a/changesets-maven-plugin/src/it/module-changelog/module-a/EXPECTED_CHANGELOG.md b/changesets-maven-plugin/src/it/module-changelog/module-a/EXPECTED_CHANGELOG.md new file mode 100644 index 0000000..b64a90c --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/module-a/EXPECTED_CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## module-a@2.1.0 + +### Minor Changes + +- Added module-a feature + diff --git a/changesets-maven-plugin/src/it/module-changelog/module-a/pom.xml b/changesets-maven-plugin/src/it/module-changelog/module-a/pom.xml new file mode 100644 index 0000000..1804dfc --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/module-a/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + module-a + 2.0.0 + + se.fortnox.maven.it + module-changelog-root + 1.0.0 + + diff --git a/changesets-maven-plugin/src/it/module-changelog/module-b/EXPECTED_CHANGELOG.md b/changesets-maven-plugin/src/it/module-changelog/module-b/EXPECTED_CHANGELOG.md new file mode 100644 index 0000000..ea1c737 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/module-b/EXPECTED_CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## module-b@3.0.1 + +### Patch Changes + +- Tiny module-b fix + diff --git a/changesets-maven-plugin/src/it/module-changelog/module-b/pom.xml b/changesets-maven-plugin/src/it/module-changelog/module-b/pom.xml new file mode 100644 index 0000000..60ec773 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/module-b/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + module-b + 3.0.0 + + se.fortnox.maven.it + module-changelog-root + 1.0.0 + + diff --git a/changesets-maven-plugin/src/it/module-changelog/pom.xml b/changesets-maven-plugin/src/it/module-changelog/pom.xml new file mode 100644 index 0000000..9427422 --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + se.fortnox.maven.it + module-changelog-root + 1.0.0 + pom + + IT: independent versioning + per-module changelogs. + + + UTF-8 + + + module-a + module-b + + diff --git a/changesets-maven-plugin/src/it/module-changelog/verify.groovy b/changesets-maven-plugin/src/it/module-changelog/verify.groovy new file mode 100644 index 0000000..87a688d --- /dev/null +++ b/changesets-maven-plugin/src/it/module-changelog/verify.groovy @@ -0,0 +1,25 @@ +import groovy.xml.XmlSlurper + +import static org.assertj.core.api.Assertions.assertThat + +def versions = new File(basedir, '.changeset/VERSIONS').text +assertThat(versions).contains("module-a=2.1.0") +assertThat(versions).contains("module-b=3.0.1") + +// Submodules each bumped to their own next-dev SNAPSHOT +def moduleA = new XmlSlurper().parse(new File(basedir, 'module-a/pom.xml')) +assertThat(moduleA.version).isEqualTo('2.1.1-SNAPSHOT') + +def moduleB = new XmlSlurper().parse(new File(basedir, 'module-b/pom.xml')) +assertThat(moduleB.version).isEqualTo('3.0.2-SNAPSHOT') + +// Per-module changelogs written next to each module's pom +assertThat(new File(basedir, 'module-a/CHANGELOG.md')) + .hasSameTextualContentAs(new File(basedir, 'module-a/EXPECTED_CHANGELOG.md')) +assertThat(new File(basedir, 'module-b/CHANGELOG.md')) + .hasSameTextualContentAs(new File(basedir, 'module-b/EXPECTED_CHANGELOG.md')) + +// No root CHANGELOG.md when MODULE mode without BOM +assertThat(new File(basedir, 'CHANGELOG.md')).doesNotExist() + +true diff --git a/changesets-maven-plugin/src/main/java/se/fortnox/changesets/maven/PrepareMojo.java b/changesets-maven-plugin/src/main/java/se/fortnox/changesets/maven/PrepareMojo.java index b0eee3d..8e19d85 100644 --- a/changesets-maven-plugin/src/main/java/se/fortnox/changesets/maven/PrepareMojo.java +++ b/changesets-maven-plugin/src/main/java/se/fortnox/changesets/maven/PrepareMojo.java @@ -17,6 +17,7 @@ import se.fortnox.changesets.ChangesetLocator; import se.fortnox.changesets.ChangesetsConfig; import se.fortnox.changesets.ChangesetsConfig.Bom; +import se.fortnox.changesets.ChangesetsConfig.ChangelogMode; import se.fortnox.changesets.VersionCalculator; import se.fortnox.changesets.VersionsFile; @@ -100,7 +101,7 @@ public void execute() throws MojoExecutionException { logger.info("Wrote " + VersionsFile.locate(reactorRoot) + " with " + changedVersions.size() + " entry/entries"); } - writeChangelog(reactorRoot, plan, config.bom(), byArtifactId); + writeChangelog(reactorRoot, plan, config, byArtifactId); if (useReleasePluginIntegration) { logger.info("Changesets processed, but not updating POMs due to useReleasePluginIntegration being set to true."); @@ -163,7 +164,7 @@ private Map collectReactorVersions() { return reactor; } - private void writeChangelog(Path reactorRoot, Map plan, Bom bom, Map byArtifactId) { + private void writeChangelog(Path reactorRoot, Map plan, ChangesetsConfig config, Map byArtifactId) { Map entries = new LinkedHashMap<>(); for (ModuleBump bump : plan.values()) { entries.put(bump.artifactId(), new ReleaseEntry( @@ -173,6 +174,7 @@ private void writeChangelog(Path reactorRoot, Map plan, Bom )); } + Bom bom = config.bom(); BomContext bomContext = null; if (bom != null && plan.containsKey(bom.module())) { ModuleBump bomBump = plan.get(bom.module()); @@ -181,9 +183,33 @@ private void writeChangelog(Path reactorRoot, Map plan, Bom bomContext = new BomContext(headerArtifactId, bomBump.newVersion(), bom.module(), pinnedUpdates); } + if (config.changelog() == ChangelogMode.MODULE) { + writePerModuleChangelogs(entries, byArtifactId); + if (bomContext != null) { + new ChangelogAggregator(reactorRoot).mergeReleaseToChangelog(entries, bomContext); + } + return; + } + new ChangelogAggregator(reactorRoot).mergeReleaseToChangelog(entries, bomContext); } + private void writePerModuleChangelogs(Map entries, Map byArtifactId) { + for (ReleaseEntry entry : entries.values()) { + if (entry.changesets().isEmpty()) { + continue; + } + MavenProject moduleProject = byArtifactId.get(entry.artifactId()); + if (moduleProject == null) { + continue; + } + Path moduleDir = moduleProject.getBasedir().toPath(); + Map single = new LinkedHashMap<>(); + single.put(entry.artifactId(), entry); + new ChangelogAggregator(moduleDir).mergeReleaseToChangelog(single); + } + } + private Map collectPinnedUpdates(Bom bom, Map plan, Map byArtifactId) { MavenProject bomProject = byArtifactId.get(bom.module()); Map reactorIdsByGav = new LinkedHashMap<>();