• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jreleaser / jreleaser / #558

08 Dec 2025 02:56PM UTC coverage: 48.239% (+0.02%) from 48.215%
#558

push

github

aalmiray
feat(core): warn when a name template cannot be resolved

Closes #1960

Closes #1961

299 of 573 new or added lines in 133 files covered. (52.18%)

4 existing lines in 4 files now uncovered.

26047 of 53996 relevant lines covered (48.24%)

0.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

15.0
/core/jreleaser-engine/src/main/java/org/jreleaser/engine/release/ChangelogResolver.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 *
4
 * Copyright 2020-2025 The JReleaser authors.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     https://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
package org.jreleaser.engine.release;
19

20
import org.jreleaser.bundle.RB;
21
import org.jreleaser.engine.changelog.Changelog;
22
import org.jreleaser.model.Constants;
23
import org.jreleaser.model.internal.JReleaserContext;
24
import org.jreleaser.model.internal.release.BaseReleaser;
25
import org.jreleaser.model.internal.release.Changelog.Append;
26
import org.jreleaser.mustache.TemplateContext;
27

28
import java.io.IOException;
29
import java.nio.file.Files;
30
import java.nio.file.Path;
31

32
import static java.lang.System.lineSeparator;
33
import static java.nio.charset.StandardCharsets.UTF_8;
34
import static java.nio.file.StandardOpenOption.CREATE_NEW;
35
import static java.nio.file.StandardOpenOption.WRITE;
36
import static org.jreleaser.mustache.MustacheUtils.applyTemplate;
37
import static org.jreleaser.mustache.MustacheUtils.passThrough;
38
import static org.jreleaser.util.StringUtils.isNotBlank;
39
import static org.jreleaser.util.StringUtils.stripMargin;
40

41
/**
42
 * @author Andres Almiray
43
 * @since 1.5.0
44
 */
45
public class ChangelogResolver {
46
    private static final String JRELEASER_CHANGELOG_ANCHOR = "<!-- JRELEASER_CHANGELOG_APPEND - Do not remove or modify this section -->";
47

48
    private ChangelogResolver() {
49
        // noop
50
    }
51

52
    public static void resolve(JReleaserContext context) {
53
        String resolvedChangelog = Changelog.createChangelog(context);
1✔
54
        context.getChangelog().setResolvedChangelog(resolvedChangelog);
1✔
55

56
        if (isNotBlank(resolvedChangelog) &&
1✔
57
            context.getModel().getProject().isRelease() &&
1✔
58
            context.getModel().getRelease().getReleaser().getChangelog().getAppend().isEnabled()) {
1✔
59
            appendChangelog(context, resolvedChangelog);
×
60
        }
61
    }
1✔
62

63
    private static void appendChangelog(JReleaserContext context, String resolvedChangelog) {
64
        BaseReleaser<?, ?> releaser = context.getModel().getRelease().getReleaser();
×
65
        Append append = releaser.getChangelog().getAppend();
×
66

67
        TemplateContext props = context.fullProps();
×
NEW
68
        String resolvedTitle = applyTemplate(context.getLogger(), append.getTitle(), props);
×
69

70
        props.set(Constants.KEY_CHANGELOG_TITLE, passThrough(resolvedTitle));
×
71
        props.set(Constants.KEY_CHANGELOG_CONTENT, passThrough(resolvedChangelog));
×
72
        props.set(Constants.KEY_CHANGELOG_CHANGES, passThrough(context.getChangelog().getFormattedChanges()));
×
73
        props.set(Constants.KEY_CHANGELOG_CONTRIBUTORS, passThrough(context.getChangelog().getFormattedContributors()));
×
NEW
74
        String appendableChangelog = stripMargin(applyTemplate(context.getLogger(), append.getResolvedContentTemplate(context), props));
×
75

76
        Path target = context.getBasedir().resolve(append.getTarget());
×
77
        String fullChangelog = null;
×
78
        try {
79
            fullChangelog = Files.exists(target) ? new String(Files.readAllBytes(target), UTF_8) : "";
×
80
        } catch (IOException e) {
×
81
            fullChangelog = "";
×
82
            context.getLogger().trace(e);
×
83
            context.getLogger().warn(RB.$("ERROR_cannot_read_changelog"),
×
84
                context.relativizeToBasedir(target));
×
85
        }
×
86

87
        String separator = separator(releaser);
×
88

89
        if (fullChangelog.contains(JRELEASER_CHANGELOG_ANCHOR)) {
×
90
            fullChangelog = fullChangelog.replaceFirst(JRELEASER_CHANGELOG_ANCHOR,
×
91
                JRELEASER_CHANGELOG_ANCHOR + separator + appendableChangelog + separator + separator);
92
        } else {
93
            fullChangelog = appendableChangelog + separator + separator + fullChangelog;
×
94
        }
95

96
        context.getLogger().info(RB.$("changelog.generator.store"), context.getBasedir().relativize(target));
×
97

98
        try {
99
            Files.write(target, fullChangelog.getBytes(UTF_8), Files.exists(target) ? WRITE : CREATE_NEW);
×
100
        } catch (IOException e) {
×
101
            context.getLogger().trace(e);
×
102
            context.getLogger().error(RB.$("ERROR_unexpected_error_changelog_append"));
×
103
        }
×
104
    }
×
105

106
    private static String separator(BaseReleaser<?, ?> releaser) {
107
        String separator = lineSeparator();
×
108
        if (org.jreleaser.model.api.release.GitlabReleaser.TYPE.equals(releaser.getServiceName())) {
×
109
            separator += lineSeparator();
×
110
        }
111
        return separator;
×
112
    }
113
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc