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

jreleaser / jreleaser / #555

22 Nov 2025 01:39PM UTC coverage: 48.203% (-0.05%) from 48.253%
#555

push

github

aalmiray
feat(jdks): Allow filtering by platform

Closes #2000

Co-authored-by: Ixchel Ruiz <ixchelruiz@yahoo.com>

0 of 42 new or added lines in 5 files covered. (0.0%)

128 existing lines in 8 files now uncovered.

26013 of 53965 relevant lines covered (48.2%)

0.48 hits per line

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

63.2
/core/jreleaser-engine/src/main/java/org/jreleaser/engine/catalog/Github.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.catalog;
19

20
import org.jreleaser.bundle.RB;
21
import org.jreleaser.engine.deploy.maven.ArtifactDeployers;
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.catalog.GithubCataloger;
27
import org.jreleaser.model.internal.common.Artifact;
28
import org.jreleaser.model.internal.deploy.maven.Maven;
29
import org.jreleaser.model.internal.deploy.maven.MavenDeployer;
30
import org.jreleaser.model.internal.distributions.Distribution;
31
import org.jreleaser.model.internal.util.Artifacts;
32
import org.jreleaser.model.spi.catalog.CatalogProcessingException;
33
import org.jreleaser.model.spi.deploy.maven.Deployable;
34

35
import java.io.IOException;
36
import java.nio.file.FileSystem;
37
import java.nio.file.FileSystems;
38
import java.nio.file.Files;
39
import java.nio.file.Path;
40
import java.nio.file.PathMatcher;
41
import java.util.ArrayList;
42
import java.util.LinkedHashSet;
43
import java.util.List;
44
import java.util.Map;
45
import java.util.Set;
46
import java.util.TreeSet;
47

48
import static java.nio.charset.StandardCharsets.UTF_8;
49
import static org.jreleaser.engine.catalog.CatalogerSupport.fireCatalogEvent;
50
import static org.jreleaser.model.api.catalog.GithubCataloger.KEY_SKIP_GITHUB;
51
import static org.jreleaser.model.internal.JReleaserSupport.supportedMavenDeployers;
52
import static org.jreleaser.util.StringUtils.isNotBlank;
53

54
/**
55
 * @author Andres Almiray
56
 * @since 1.13.0
57
 */
58
public final class Github {
59
    private static final String GLOB_PREFIX = "glob:";
60
    private static final String REGEX_PREFIX = "regex:";
61

62
    private Github() {
63
        // noop
64
    }
65

66
    public static void catalog(JReleaserContext context) {
67
        context.getLogger().increaseIndent();
1✔
68
        context.getLogger().setPrefix("github");
1✔
69

70
        GithubCataloger github = context.getModel().getCatalog().getGithub();
1✔
71
        if (!github.isEnabled()) {
1✔
72
            context.getLogger().info(RB.$("catalogers.not.enabled"));
×
73
            context.getLogger().decreaseIndent();
×
74
            context.getLogger().restorePrefix();
×
75
            return;
×
76
        }
77

78
        try {
79
            fireCatalogEvent(ExecutionEvent.before(JReleaserCommand.CATALOG.toStep()), context, github);
1✔
80
            attestation(context, github);
1✔
81
            fireCatalogEvent(ExecutionEvent.success(JReleaserCommand.CATALOG.toStep()), context, github);
1✔
82
        } catch (CatalogProcessingException e) {
×
83
            fireCatalogEvent(ExecutionEvent.failure(JReleaserCommand.CATALOG.toStep(), e), context, github);
×
84
            throw new JReleaserException(RB.$("ERROR_unexpected_error"), e);
×
85
        } finally {
86
            context.getLogger().decreaseIndent();
1✔
87
            context.getLogger().restorePrefix();
1✔
88
        }
89
    }
1✔
90

91
    private static void attestation(JReleaserContext context, GithubCataloger github) throws CatalogProcessingException {
92
        Set<PathMatcher> includes = new LinkedHashSet<>();
1✔
93
        Set<PathMatcher> excludes = new LinkedHashSet<>();
1✔
94

95
        FileSystem fileSystem = FileSystems.getDefault();
1✔
96
        for (String s : github.getIncludes()) {
1✔
97
            includes.add(fileSystem.getPathMatcher(normalize(s)));
×
98
        }
×
99
        for (String s : github.getExcludes()) {
1✔
100
            excludes.add(fileSystem.getPathMatcher(normalize(s)));
×
101
        }
×
102

103
        if (includes.isEmpty()) {
1✔
104
            includes.add(fileSystem.getPathMatcher(GLOB_PREFIX + "**/*"));
1✔
105
        }
106

107
        List<String> subjects = new ArrayList<>();
1✔
108
        String attestationName = github.getResolvedAttestationName(context);
1✔
109

110
        context.getLogger().info(attestationName);
1✔
111

112
        if (github.isFiles()) {
1✔
113
            for (Artifact artifact : Artifacts.resolveFiles(context)) {
1✔
114
                if (!artifact.isActiveAndSelected() || artifact.extraPropertyIsTrue(KEY_SKIP_GITHUB) ||
1✔
115
                    artifact.isOptional(context) && !artifact.resolvedPathExists()) continue;
1✔
116
                addSubject(context, subjects, artifact, includes, excludes);
1✔
117
            }
1✔
118
        }
119

120
        if (github.isArtifacts()) {
1✔
121
            for (Distribution distribution : context.getModel().getActiveDistributions()) {
1✔
122
                for (Artifact artifact : distribution.getArtifacts()) {
1✔
123
                    if (!artifact.isActiveAndSelected()) continue;
1✔
124
                    artifact.getEffectivePath(context, distribution);
1✔
125
                    if (artifact.isOptional(context) && !artifact.resolvedPathExists()) continue;
1✔
126
                    addSubject(context, subjects, artifact, includes, excludes);
1✔
127
                }
1✔
128
            }
1✔
129
        }
130

131
        if (github.isDeployables()) {
1✔
132
            for (Deployable deployable : collectDeployables(context)) {
1✔
133
                if (!deployable.isPom() && !deployable.isArtifact()) continue;
1✔
134
                Artifact artifact = Artifact.of(deployable.getLocalPath());
1✔
135
                addSubject(context, subjects, artifact, includes, excludes);
1✔
136
            }
1✔
137
        }
138

139
        if (subjects.isEmpty()) {
1✔
140
            context.getLogger().info(RB.$("catalog.no.artifacts"));
×
141
            context.getLogger().decreaseIndent();
×
142
            context.getLogger().restorePrefix();
×
143
            return;
×
144
        }
145

146
        String newContent = String.join(System.lineSeparator(), subjects);
1✔
147
        Path attestationFile = context.getCatalogsDirectory()
1✔
148
            .resolve(github.getType())
1✔
149
            .resolve(attestationName);
1✔
150

151
        try {
152
            if (Files.exists(attestationFile)) {
1✔
153
                String oldContent = new String(Files.readAllBytes(attestationFile), UTF_8);
1✔
154
                if (newContent.equals(oldContent)) {
1✔
155
                    // no need to write down the same content
UNCOV
156
                    context.getLogger().info(RB.$("catalog.github.not.changed"));
×
UNCOV
157
                    context.getLogger().restorePrefix();
×
UNCOV
158
                    context.getLogger().decreaseIndent();
×
UNCOV
159
                    return;
×
160
                }
161
            }
162
        } catch (IOException ignored) {
×
163
            // OK
164
        }
1✔
165

166
        try {
167
            if (isNotBlank(newContent)) {
1✔
168
                Files.createDirectories(attestationFile.getParent());
1✔
169
                Files.write(attestationFile, newContent.getBytes(UTF_8));
1✔
170
            } else {
171
                Files.deleteIfExists(attestationFile);
×
172
            }
173
        } catch (IOException e) {
×
174
            throw new JReleaserException(RB.$("ERROR_unexpected_error_writing_file", attestationFile.toAbsolutePath()), e);
×
175
        }
1✔
176
    }
1✔
177

178
    private static String normalize(String pattern) {
179
        if (pattern.startsWith(GLOB_PREFIX) || pattern.startsWith(REGEX_PREFIX)) return pattern;
×
180
        return GLOB_PREFIX + pattern;
×
181
    }
182

183
    private static void addSubject(JReleaserContext context, List<String> subjects, Artifact artifact, Set<PathMatcher> includes, Set<PathMatcher> excludes) {
184
        Path path = artifact.getEffectivePath(context);
1✔
185
        String artifactFileName = path.toString();
1✔
186

187
        if (includes.stream().anyMatch(matcher -> matcher.matches(path)) &&
1✔
188
            excludes.stream().noneMatch(matcher -> matcher.matches(path))) {
1✔
189
            subjects.add(artifactFileName);
1✔
190
            context.getLogger().debug("- " + artifact.getEffectivePath(context).getFileName());
1✔
191
        }
192
    }
1✔
193

194
    private static Set<Deployable> collectDeployables(JReleaserContext context) {
195
        Set<String> stagingRepositories = new TreeSet<>();
1✔
196
        Set<Deployable> deployables = new TreeSet<>();
1✔
197
        Maven maven = context.getModel().getDeploy().getMaven();
1✔
198

199
        if (!context.getIncludedDeployerTypes().isEmpty()) {
1✔
200
            for (String deployerType : context.getIncludedDeployerTypes()) {
×
201
                if (!supportedMavenDeployers().contains(deployerType)) continue;
×
202

203
                Map<String, MavenDeployer<?>> deployers = maven.findMavenDeployersByType(deployerType);
×
204

205
                if (deployers.isEmpty()) return deployables;
×
206

207
                if (!context.getIncludedDeployerNames().isEmpty()) {
×
208
                    for (String deployerName : context.getIncludedDeployerNames()) {
×
209
                        if (!deployers.containsKey(deployerName)) continue;
×
210

211
                        MavenDeployer<?> deployer = deployers.get(deployerName);
×
212
                        if (!deployer.isEnabled()) continue;
×
213

214
                        handleDeployer(context, stagingRepositories, deployables, deployer);
×
215
                    }
×
216
                } else {
217
                    for (MavenDeployer<?> deployer : deployers.values()) {
×
218
                        handleDeployer(context, stagingRepositories, deployables, deployer);
×
219
                    }
×
220
                }
221
            }
×
222
        } else if (!context.getIncludedDeployerNames().isEmpty()) {
1✔
223
            for (String deployerName : context.getIncludedDeployerNames()) {
×
224
                maven.findAllActiveMavenDeployers().stream()
×
225
                    .filter(a -> deployerName.equals(a.getName()))
×
226
                    .forEach(deployer -> handleDeployer(context, stagingRepositories, deployables, deployer));
×
227
            }
×
228
        } else {
229
            for (MavenDeployer<?> deployer : maven.findAllActiveMavenDeployers()) {
1✔
230
                if (context.getExcludedDeployerTypes().contains(deployer.getType()) ||
1✔
231
                    context.getExcludedDeployerNames().contains(deployer.getName())) {
1✔
232
                    continue;
×
233
                }
234

235
                handleDeployer(context, stagingRepositories, deployables, deployer);
1✔
236
            }
1✔
237
        }
238

239
        return deployables;
1✔
240
    }
241

242
    private static void handleDeployer(JReleaserContext context, Set<String> stagingRepositories, Set<Deployable> deployables, MavenDeployer<?> deployer) {
243
        org.jreleaser.model.spi.deploy.maven.MavenDeployer<?, ?> artifactMavenDeployer = ArtifactDeployers.findMavenDeployer(context, deployer);
1✔
244
        for (String stagingRepository : deployer.getStagingRepositories()) {
1✔
245
            if (stagingRepositories.contains(stagingRepository)) continue;
1✔
246
            artifactMavenDeployer.collectDeployables(deployables, stagingRepository);
1✔
247
        }
1✔
248
    }
1✔
249
}
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