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

jreleaser / jreleaser / #475

03 Apr 2025 10:50AM UTC coverage: 40.322% (-8.9%) from 49.193%
#475

push

github

aalmiray
feat(release): Support Forgejo as releaser

Closes #1842

Closes #1843

182 of 1099 new or added lines in 45 files covered. (16.56%)

4239 existing lines in 333 files now uncovered.

20797 of 51577 relevant lines covered (40.32%)

0.4 hits per line

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

58.7
/core/jreleaser-engine/src/main/java/org/jreleaser/workflow/WorkflowImpl.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.workflow;
19

20
import org.jreleaser.bundle.RB;
21
import org.jreleaser.engine.context.ModelValidator;
22
import org.jreleaser.engine.hooks.HookExecutor;
23
import org.jreleaser.extensions.api.ExtensionManagerHolder;
24
import org.jreleaser.extensions.api.workflow.WorkflowListenerException;
25
import org.jreleaser.model.JReleaserException;
26
import org.jreleaser.model.api.hooks.ExecutionEvent;
27
import org.jreleaser.model.internal.JReleaserContext;
28

29
import java.time.Duration;
30
import java.time.Instant;
31
import java.util.ArrayList;
32
import java.util.List;
33

34
import static org.jreleaser.util.TimeUtils.formatDuration;
35

36
/**
37
 * @author Andres Almiray
38
 * @since 0.1.0
39
 */
40
class WorkflowImpl implements Workflow {
41
    private static final String SESSION = "session";
42
    private final JReleaserContext context;
43
    private final List<WorkflowItem> items = new ArrayList<>();
1✔
44

45
    public WorkflowImpl(JReleaserContext context, List<WorkflowItem> items) {
1✔
46
        this.context = context;
1✔
47
        ModelValidator.validate(context);
1✔
48
        this.items.addAll(items);
1✔
49
    }
1✔
50

51
    @Override
52
    public void execute() {
53
        try {
54
            doExecute();
1✔
55
        } finally {
56
            ExtensionManagerHolder.cleanup();
1✔
57
            context.getLogger().close();
1✔
58
        }
59
    }
1✔
60

61
    private void doExecute() {
62
        RuntimeException stepException = null;
1✔
63
        Throwable listenerException = null;
1✔
64
        Throwable startSessionException = null;
1✔
65
        Throwable endSessionException = null;
1✔
66

67
        Instant start = Instant.now();
1✔
68
        context.getLogger().info(RB.$("workflow.dryrun"), context.isDryrun());
1✔
69
        logFilters("workflow.included.downloader.types", context.getIncludedDownloaderTypes());
1✔
70
        logFilters("workflow.excluded.downloader.types", context.getExcludedDownloaderTypes());
1✔
71
        logFilters("workflow.included.downloader.names", context.getIncludedDownloaderNames());
1✔
72
        logFilters("workflow.excluded.downloader.names", context.getExcludedDownloaderNames());
1✔
73
        logFilters("workflow.included.assemblers", context.getIncludedAssemblers());
1✔
74
        logFilters("workflow.excluded.assemblers", context.getExcludedAssemblers());
1✔
75
        logFilters("workflow.included.distributions", context.getIncludedDistributions());
1✔
76
        logFilters("workflow.excluded.distributions", context.getExcludedDistributions());
1✔
77
        logFilters("workflow.included.catalogers", context.getIncludedCatalogers());
1✔
78
        logFilters("workflow.excluded.catalogers", context.getExcludedCatalogers());
1✔
79
        logFilters("workflow.included.packagers", context.getIncludedPackagers());
1✔
80
        logFilters("workflow.excluded.packagers", context.getExcludedPackagers());
1✔
81
        logFilters("workflow.included.deployer.types", context.getIncludedDeployerTypes());
1✔
82
        logFilters("workflow.excluded.deployer.types", context.getExcludedDeployerTypes());
1✔
83
        logFilters("workflow.included.deployer.names", context.getIncludedDeployerNames());
1✔
84
        logFilters("workflow.excluded.deployer.names", context.getExcludedDeployerNames());
1✔
85
        logFilters("workflow.included.uploader.types", context.getIncludedUploaderTypes());
1✔
86
        logFilters("workflow.excluded.uploader.types", context.getExcludedUploaderTypes());
1✔
87
        logFilters("workflow.included.uploader.names", context.getIncludedUploaderNames());
1✔
88
        logFilters("workflow.excluded.uploader.names", context.getExcludedUploaderNames());
1✔
89
        logFilters("workflow.included.announcers", context.getIncludedAnnouncers());
1✔
90
        logFilters("workflow.excluded.announcers", context.getExcludedAnnouncers());
1✔
91

92
        HookExecutor hooks = new HookExecutor(context);
1✔
93

94
        try {
95
            hooks.executeHooks(ExecutionEvent.before(SESSION));
1✔
96
        } catch (RuntimeException e) {
×
97
            context.getLogger().error(RB.$("ERROR_hooks_unexpected_error"));
×
98
            context.getLogger().trace(e);
×
99
            startSessionException = e;
×
100
        }
1✔
101

102
        if (null == startSessionException) {
1✔
103
            try {
104
                context.fireSessionStartEvent();
1✔
105
            } catch (WorkflowListenerException e) {
×
106
                context.getLogger().error(RB.$("listener.failure", e.getListener().getClass().getName()));
×
107
                context.getLogger().trace(e);
×
108
                if (!e.getListener().isContinueOnError()) {
×
109
                    startSessionException = e.getCause();
×
110
                }
111
            }
1✔
112
        }
113

114
        if (null == startSessionException) {
1✔
115
            for (WorkflowItem item : items) {
1✔
116
                boolean failure = false;
1✔
117
                try {
118
                    context.fireWorkflowEvent(ExecutionEvent.before(item.getCommand().toStep()));
1✔
119
                } catch (WorkflowListenerException beforeException) {
×
120
                    context.getLogger().error(RB.$("listener.failure", beforeException.getListener().getClass().getName()));
×
121
                    context.getLogger().trace(beforeException);
×
122
                    if (!beforeException.getListener().isContinueOnError()) {
×
123
                        listenerException = beforeException.getCause();
×
124
                        break;
×
125
                    }
126
                }
1✔
127

128
                try {
129
                    item.invoke(context);
1✔
130
                } catch (RuntimeException e) {
1✔
131
                    // terminate
132
                    failure = true;
1✔
133
                    stepException = e;
1✔
134

135
                    try {
136
                        context.fireWorkflowEvent(ExecutionEvent.failure(item.getCommand().toStep(), e));
1✔
137
                        break;
1✔
138
                    } catch (WorkflowListenerException failureException) {
×
139
                        context.getLogger().error(RB.$("listener.failure", failureException.getListener().getClass().getName()));
×
140
                        context.getLogger().trace(failureException);
×
141
                        if (!failureException.getListener().isContinueOnError()) {
×
142
                            listenerException = failureException.getCause();
×
143
                            break;
×
144
                        }
145
                    }
146
                }
1✔
147

148
                if (!failure) {
1✔
149
                    try {
150
                        context.fireWorkflowEvent(ExecutionEvent.success(item.getCommand().toStep()));
1✔
151
                    } catch (WorkflowListenerException afterException) {
×
152
                        context.getLogger().error(RB.$("listener.failure", afterException.getListener().getClass().getName()));
×
153
                        context.getLogger().trace(afterException);
×
154
                        if (!afterException.getListener().isContinueOnError()) {
×
155
                            listenerException = afterException.getCause();
×
156
                            break;
×
157
                        }
158
                    }
1✔
159
                }
160
            }
1✔
161
        }
162

163
        try {
164
            context.fireSessionEndEvent();
1✔
165
        } catch (WorkflowListenerException e) {
×
166
            context.getLogger().error(RB.$("listener.failure", e.getListener().getClass().getName()));
×
167
            context.getLogger().trace(e);
×
168
            if (!e.getListener().isContinueOnError()) {
×
169
                endSessionException = e.getCause();
×
170
            }
171
        }
1✔
172

173
        Instant end = Instant.now();
1✔
174

175
        double duration = Duration.between(start, end).toMillis() / 1000d;
1✔
176

177
        context.getLogger().reset();
1✔
178
        context.report();
1✔
179

180
        if (null != startSessionException) {
1✔
181
            context.getLogger().error(RB.$("workflow.failure"), formatDuration(duration));
×
182
            context.getLogger().trace(startSessionException);
×
183
            if (startSessionException instanceof RuntimeException) {
×
184
                throw (RuntimeException) startSessionException;
×
185
            } else {
186
                throw new JReleaserException(RB.$("ERROR_unexpected_error"), startSessionException);
×
187
            }
188
        } else if (null != endSessionException) {
1✔
189
            try {
190
                hooks.executeHooks(ExecutionEvent.failure(SESSION, endSessionException));
×
191
            } catch (RuntimeException e) {
×
192
                context.getLogger().error(RB.$("ERROR_hooks_unexpected_error"));
×
193
                context.getLogger().trace(e);
×
194
            }
×
195

196
            context.getLogger().error(RB.$("workflow.failure"), formatDuration(duration));
×
197
            context.getLogger().trace(endSessionException);
×
198
            if (endSessionException instanceof RuntimeException) {
×
199
                throw (RuntimeException) endSessionException;
×
200
            } else {
201
                throw new JReleaserException(RB.$("ERROR_unexpected_error"), endSessionException);
×
202
            }
203
        } else {
204
            if (null == stepException) {
1✔
205
                if (null != listenerException) {
1✔
206
                    if (listenerException instanceof RuntimeException) {
×
207
                        throw (RuntimeException) listenerException;
×
208
                    } else {
209
                        throw new JReleaserException(RB.$("ERROR_unexpected_error"), listenerException);
×
210
                    }
211
                }
212
                try {
213
                    hooks.executeHooks(ExecutionEvent.success(SESSION));
1✔
214
                } catch (RuntimeException e) {
×
215
                    context.getLogger().error(RB.$("ERROR_hooks_unexpected_error"));
×
216
                    context.getLogger().trace(e);
×
217
                }
1✔
218

219
                context.getLogger().info(RB.$("workflow.success"), formatDuration(duration));
1✔
220
            } else {
221
                try {
222
                    hooks.executeHooks(ExecutionEvent.failure(SESSION, stepException));
1✔
223
                } catch (RuntimeException e) {
×
224
                    context.getLogger().error(RB.$("ERROR_hooks_unexpected_error"));
×
225
                    context.getLogger().trace(e);
×
226
                }
1✔
227

228
                context.getLogger().error(RB.$("workflow.failure"), formatDuration(duration));
1✔
229
                context.getLogger().trace(stepException);
1✔
230
                throw stepException;
1✔
231
            }
232
        }
233
    }
1✔
234

235
    private void logFilters(String key, List<String> input) {
236
        if (!input.isEmpty()) {
1✔
UNCOV
237
            context.getLogger().info(RB.$(key, input));
×
238
        }
239
    }
1✔
240
}
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