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

jreleaser / jreleaser / #539

25 Sep 2025 06:51PM UTC coverage: 48.269% (+0.7%) from 47.589%
#539

push

github

web-flow
feat(release): Add support for github immutable releases

Closes #1978

2 of 14 new or added lines in 4 files covered. (14.29%)

10 existing lines in 5 files now uncovered.

25820 of 53492 relevant lines covered (48.27%)

0.48 hits per line

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

39.8
/core/jreleaser-engine/src/main/java/org/jreleaser/engine/assemble/Assemblers.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.assemble;
19

20
import org.jreleaser.bundle.RB;
21
import org.jreleaser.extensions.api.workflow.WorkflowListenerException;
22
import org.jreleaser.model.JReleaserException;
23
import org.jreleaser.model.api.JReleaserCommand;
24
import org.jreleaser.model.api.hooks.ExecutionEvent;
25
import org.jreleaser.model.internal.JReleaserContext;
26
import org.jreleaser.model.internal.assemble.Assemble;
27
import org.jreleaser.model.internal.assemble.Assembler;
28
import org.jreleaser.model.spi.assemble.AssemblerProcessingException;
29

30
import java.util.Map;
31

32
import static org.jreleaser.model.internal.JReleaserSupport.supportedAssemblers;
33

34
/**
35
 * @author Andres Almiray
36
 * @since 0.2.0
37
 */
38
public final class Assemblers {
39
    private Assemblers() {
40
        // noop
41
    }
42

43
    public static void assemble(JReleaserContext context) {
44
        context.getLogger().info(RB.$("assemblers.header"));
1✔
45
        context.getLogger().increaseIndent();
1✔
46
        context.getLogger().setPrefix("assemble");
1✔
47

48
        Assemble assemble = context.getModel().getAssemble();
1✔
49
        if (!assemble.isEnabled()) {
1✔
50
            context.getLogger().info(RB.$("assemblers.not.enabled"));
×
51
            context.getLogger().restorePrefix();
×
52
            return;
×
53
        }
54

55
        try {
56
            doAssemble(context, assemble);
1✔
57
        } finally {
58
            context.getLogger().decreaseIndent();
1✔
59
            context.getLogger().restorePrefix();
1✔
60
        }
61
    }
1✔
62

63
    private static void doAssemble(JReleaserContext context, Assemble assemble) {
64
        if (!context.getIncludedAssemblers().isEmpty()) {
1✔
65
            for (String assemblerType : context.getIncludedAssemblers()) {
×
66
                // check if the assemblerType is valid
67
                if (!supportedAssemblers().contains(assemblerType)) {
×
68
                    context.getLogger().warn(RB.$("ERROR_unsupported_assembler", assemblerType));
×
69
                    continue;
×
70
                }
71

72
                Map<String, Assembler<?>> assemblers = assemble.findAssemblersByType(assemblerType);
×
73

74
                if (assemblers.isEmpty()) {
×
75
                    context.getLogger().info(RB.$("assemblers.no.match"), assemblerType);
×
76
                    return;
×
77
                }
78

79
                if (!context.getIncludedDistributions().isEmpty()) {
×
80
                    for (String distributionName : context.getIncludedDistributions()) {
×
81
                        boolean[] assembled = new boolean[]{false};
×
82
                        if (!assemblers.containsKey(distributionName)) {
×
83
                            context.getLogger().error(RB.$("assemblers.distribution.not.configured"), assemblerType, distributionName);
×
84
                            continue;
×
85
                        }
86

87
                        assemble.findAllAssemblers().stream()
×
88
                            .filter(a -> distributionName.equals(a.getName()))
×
89
                            .peek(assembler -> context.getLogger().info(RB.$("assemblers.assemble.distribution.with"),
×
90
                                distributionName, assembler.getName()))
×
91
                            .forEach(assembler -> {
×
92
                                if (assemble(context, assembler)) assembled[0] = true;
×
93
                            });
×
94

95
                        if (!assembled[0]) {
×
96
                            context.getLogger().info(RB.$("assemblers.not.triggered"));
×
97
                        }
98
                    }
×
99
                } else {
100
                    context.getLogger().info(RB.$("assemblers.assemble.all.distributions.with"), assemblerType);
×
101
                    boolean[] assembled = new boolean[]{false};
×
102
                    assemblers.values().forEach(assembler -> {
×
103
                        if (assemble(context, assembler)) assembled[0] = true;
×
104
                    });
×
105

106
                    if (!assembled[0]) {
×
107
                        context.getLogger().info(RB.$("assemblers.not.triggered"));
×
108
                    }
109
                }
110
            }
×
111
        } else if (!context.getIncludedDistributions().isEmpty()) {
1✔
112
            for (String distributionName : context.getIncludedDistributions()) {
×
113
                context.getLogger().info(RB.$("assemblers.assemble.distribution.with.all"), distributionName);
×
114

115
                boolean[] assembled = new boolean[]{false};
×
116
                assemble.findAllAssemblers().stream()
×
117
                    .filter(a -> distributionName.equals(a.getName()))
×
118
                    .forEach(assembler -> {
×
119
                        if (assemble(context, assembler)) assembled[0] = true;
×
120
                    });
×
121

122
                if (!assembled[0]) {
×
123
                    context.getLogger().info(RB.$("assemblers.not.triggered"));
×
124
                }
125
            }
×
126
        } else {
127
            context.getLogger().info(RB.$("assemblers.assemble.all.distributions"));
1✔
128
            boolean assembled = false;
1✔
129
            for (Assembler<?> assembler : assemble.findAllAssemblers()) {
1✔
130
                String assemblerType = assembler.getType();
1✔
131
                String distributionName = assembler.getName();
1✔
132
                if (context.getExcludedAssemblers().contains(assemblerType) ||
1✔
133
                    context.getExcludedDistributions().contains(distributionName)) {
1✔
134
                    context.getLogger().info(RB.$("assemblers.assembler.excluded"), assemblerType, distributionName);
×
135
                    continue;
×
136
                }
137

138
                if (assemble(context, assembler)) assembled = true;
1✔
139
            }
1✔
140

141
            if (!assembled) {
1✔
142
                context.getLogger().info(RB.$("assemblers.not.triggered"));
×
143
            }
144
        }
145
    }
1✔
146

147
    private static boolean assemble(JReleaserContext context, Assembler<?> assembler) {
148
        try {
149
            context.getLogger().increaseIndent();
1✔
150
            context.getLogger().setPrefix(assembler.getType());
1✔
151

152
            fireAssembleEvent(ExecutionEvent.before(JReleaserCommand.ASSEMBLE.toStep()), context, assembler);
1✔
153

154
            DistributionAssembler processor = createDistributionAssembler(context, assembler);
1✔
155
            boolean assembled = processor.assemble();
1✔
156

157
            fireAssembleEvent(ExecutionEvent.success(JReleaserCommand.ASSEMBLE.toStep()), context, assembler);
1✔
158
            return assembled;
1✔
UNCOV
159
        } catch (AssemblerProcessingException e) {
×
UNCOV
160
            fireAssembleEvent(ExecutionEvent.failure(JReleaserCommand.ASSEMBLE.toStep(), e), context, assembler);
×
UNCOV
161
            throw new JReleaserException(e.getMessage(), e);
×
162
        } finally {
163
            context.getLogger().restorePrefix();
1✔
164
            context.getLogger().decreaseIndent();
1✔
165
        }
166
    }
167

168
    private static DistributionAssembler createDistributionAssembler(JReleaserContext context,
169
                                                                     Assembler<?> assembler) {
170
        return DistributionAssembler.builder()
1✔
171
            .context(context)
1✔
172
            .assembler(assembler)
1✔
173
            .build();
1✔
174
    }
175

176
    private static void fireAssembleEvent(ExecutionEvent event, JReleaserContext context, Assembler<?> assembler) {
177
        if (!assembler.isEnabled()) return;
1✔
178

179
        try {
180
            context.fireAssembleStepEvent(event, assembler.asImmutable());
1✔
181
        } catch (WorkflowListenerException e) {
×
182
            context.getLogger().error(RB.$("listener.failure", e.getListener().getClass().getName()));
×
183
            context.getLogger().trace(e);
×
184
            if (event.getType() != ExecutionEvent.Type.FAILURE && !e.getListener().isContinueOnError()) {
×
185
                if (e.getCause() instanceof RuntimeException) {
×
186
                    throw (RuntimeException) e.getCause();
×
187
                } else {
188
                    throw new JReleaserException(RB.$("ERROR_unexpected_error"), e.getCause());
×
189
                }
190
            }
191
        }
1✔
192
    }
1✔
193
}
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