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

jreleaser / jreleaser / #510

27 Jul 2025 12:31PM UTC coverage: 45.783% (-3.6%) from 49.39%
#510

push

github

aalmiray
feat(packagers): Stage distribution publication in a fixed directory

Closes #1943

12 of 25 new or added lines in 4 files covered. (48.0%)

2208 existing lines in 190 files now uncovered.

23924 of 52255 relevant lines covered (45.78%)

0.46 hits per line

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

81.19
/sdks/jreleaser-smtp-java-sdk/src/main/java/org/jreleaser/sdk/smtp/MessageSmtpCommand.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.sdk.smtp;
19

20
import jakarta.mail.Message;
21
import jakarta.mail.Session;
22
import jakarta.mail.Transport;
23
import jakarta.mail.internet.InternetAddress;
24
import jakarta.mail.internet.MimeBodyPart;
25
import jakarta.mail.internet.MimeMessage;
26
import jakarta.mail.internet.MimeMultipart;
27
import org.jreleaser.bundle.RB;
28
import org.jreleaser.logging.JReleaserLogger;
29
import org.jreleaser.model.JReleaserVersion;
30

31
import java.util.Date;
32
import java.util.LinkedHashMap;
33
import java.util.Locale;
34
import java.util.Map;
35
import java.util.Properties;
36

37
import static org.jreleaser.util.StringUtils.isNotBlank;
38

39
/**
40
 * @author Andres Almiray
41
 * @since 0.1.0
42
 */
43
public class MessageSmtpCommand implements SmtpCommand {
44
    private final JReleaserLogger logger;
45
    private final boolean dryrun;
46
    private final org.jreleaser.model.Mail.Transport transport;
47
    private final String host;
48
    private final int port;
49
    private final boolean auth;
50
    private final String username;
51
    private final String password;
52
    private final String from;
53
    private final String to;
54
    private final String cc;
55
    private final String bcc;
56
    private final String subject;
57
    private final String message;
58
    private final org.jreleaser.model.Mail.MimeType mimeType;
59
    private final Map<String, String> properties = new LinkedHashMap<>();
1✔
60

61
    private MessageSmtpCommand(JReleaserLogger logger,
62
                               boolean dryrun,
63
                               org.jreleaser.model.Mail.Transport transport,
64
                               String host,
65
                               int port,
66
                               boolean auth,
67
                               String username,
68
                               String password,
69
                               String from,
70
                               String to,
71
                               String cc,
72
                               String bcc,
73
                               String subject,
74
                               String message,
75
                               org.jreleaser.model.Mail.MimeType mimeType,
76
                               Map<String, String> properties) {
1✔
77
        this.logger = logger;
1✔
78
        this.dryrun = dryrun;
1✔
79
        this.transport = transport;
1✔
80
        this.host = host;
1✔
81
        this.port = port;
1✔
82
        this.auth = auth;
1✔
83
        this.username = username;
1✔
84
        this.password = password;
1✔
85
        this.from = from;
1✔
86
        this.to = to;
1✔
87
        this.cc = cc;
1✔
88
        this.bcc = bcc;
1✔
89
        this.subject = subject;
1✔
90
        this.message = message;
1✔
91
        this.mimeType = mimeType;
1✔
92
        this.properties.putAll(properties);
1✔
93
    }
1✔
94

95
    @Override
96
    public void execute() throws SmtpException {
97
        logger.info(RB.$("mail.message.send"));
1✔
98
        if (dryrun) return;
1✔
99

100
        Properties props = new Properties();
1✔
101
        props.putAll(properties);
1✔
102

103
        props.put("mail.smtp.host", host);
1✔
104
        props.put("mail.smtp.port", port);
1✔
105

106
        if (auth) {
1✔
107
            if (!props.containsKey("mail.smtp.auth")) {
×
108
                props.put("mail.smtp.auth", "true");
×
109
            }
110
            if (transport == org.jreleaser.model.Mail.Transport.SMTP) {
×
111
                if (!props.containsKey("mail.smtp.starttls.enable")) {
×
112
                    props.put("mail.smtp.starttls.enable", "true");
×
113
                }
114
            } else {
115
                if (!props.containsKey("mail.smtp.socketFactory.port")) {
×
116
                    props.put("mail.smtp.socketFactory.port", port);
×
117
                }
118
                if (!props.containsKey("mail.smtp.socketFactory.class")) {
×
119
                    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
×
120
                    props.put("mail.smtp.ssl.checkserveridentity", true);
×
121
                }
122
            }
123
        }
124

125
        try {
126
            Session session = Session.getInstance(props);
1✔
127
            Message message = new MimeMessage(session);
1✔
128

129
            if (isNotBlank(from)) {
1✔
130
                message.setFrom(new InternetAddress(from));
1✔
131
            }
132

133
            if (isNotBlank(to)) {
1✔
134
                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
1✔
135
            }
136
            if (isNotBlank(cc)) {
1✔
137
                message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc));
1✔
138
            }
139
            if (isNotBlank(bcc)) {
1✔
140
                message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc));
1✔
141
            }
142

143
            message.setSubject(subject);
1✔
144

145
            MimeMultipart content = new MimeMultipart();
1✔
146
            MimeBodyPart textPart = new MimeBodyPart();
1✔
147
            textPart.setContent(this.message, mimeType.code());
1✔
148
            content.addBodyPart(textPart);
1✔
149
            message.setContent(content);
1✔
150

151
            message.setHeader("X-Mailer", "JReleaser " + JReleaserVersion.getPlainVersion());
1✔
152
            message.setSentDate(new Date());
1✔
153

154
            Transport t = session.getTransport(transport.name().toLowerCase(Locale.ENGLISH));
1✔
155
            if (auth) {
1✔
156
                t.connect(host, username, password);
×
157
            } else {
158
                t.connect();
1✔
159
            }
160
            t.sendMessage(message, message.getAllRecipients());
1✔
161
        } catch (Exception e) {
×
162
            throw new SmtpException(e);
×
163
        }
1✔
164
    }
1✔
165

166
    public static Builder builder(JReleaserLogger logger) {
167
        return new Builder(logger);
1✔
168
    }
169

170
    public static class Builder {
171
        private final JReleaserLogger logger;
172
        private boolean dryrun;
173
        private org.jreleaser.model.Mail.Transport transport = org.jreleaser.model.Mail.Transport.SMTP;
1✔
174
        private String host;
175
        private int port;
176
        private boolean auth;
177
        private String username;
178
        private String password;
179
        private String from;
180
        private String to;
181
        private String cc;
182
        private String bcc;
183
        private String subject;
184
        private String message;
185
        private org.jreleaser.model.Mail.MimeType mimeType = org.jreleaser.model.Mail.MimeType.TEXT;
1✔
186
        private final Map<String, String> properties = new LinkedHashMap<>();
1✔
187

188
        protected Builder(JReleaserLogger logger) {
1✔
189
            this.logger = logger;
1✔
190
        }
1✔
191

192
        public Builder dryrun(boolean dryrun) {
193
            this.dryrun = dryrun;
1✔
194
            return this;
1✔
195
        }
196

197
        public Builder transport(org.jreleaser.model.Mail.Transport transport) {
198
            this.transport = transport;
1✔
199
            return this;
1✔
200
        }
201

202
        public Builder host(String host) {
203
            this.host = host;
1✔
204
            return this;
1✔
205
        }
206

207
        public Builder port(int port) {
208
            this.port = port;
1✔
209
            return this;
1✔
210
        }
211

212
        public Builder auth(boolean auth) {
213
            this.auth = auth;
1✔
214
            return this;
1✔
215
        }
216

217
        public Builder username(String username) {
UNCOV
218
            this.username = username;
×
UNCOV
219
            return this;
×
220
        }
221

222
        public Builder password(String password) {
UNCOV
223
            this.password = password;
×
UNCOV
224
            return this;
×
225
        }
226

227
        public Builder from(String from) {
228
            this.from = from;
1✔
229
            return this;
1✔
230
        }
231

232
        public Builder to(String to) {
233
            this.to = to;
1✔
234
            return this;
1✔
235
        }
236

237
        public Builder cc(String cc) {
238
            this.cc = cc;
1✔
239
            return this;
1✔
240
        }
241

242
        public Builder bcc(String bcc) {
243
            this.bcc = bcc;
1✔
244
            return this;
1✔
245
        }
246

247
        public Builder subject(String subject) {
248
            this.subject = subject;
1✔
249
            return this;
1✔
250
        }
251

252
        public Builder message(String message) {
253
            this.message = message;
1✔
254
            return this;
1✔
255
        }
256

257
        public Builder mimeType(org.jreleaser.model.Mail.MimeType mimeType) {
258
            this.mimeType = mimeType;
1✔
259
            return this;
1✔
260
        }
261

262
        public Builder properties(Map<String, String> properties) {
263
            this.properties.putAll(properties);
×
264
            return this;
×
265
        }
266

267
        public MessageSmtpCommand build() {
268
            return new MessageSmtpCommand(
1✔
269
                logger,
270
                dryrun,
271
                transport,
272
                host,
273
                port,
274
                auth,
275
                username,
276
                password,
277
                from,
278
                to,
279
                cc,
280
                bcc,
281
                subject,
282
                message,
283
                mimeType,
284
                properties);
285
        }
286
    }
287
}
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