Skip to content

Commit

Permalink
[signing] more control over which artifacts/files get signed. Resolves
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmiray committed Jul 29, 2021
1 parent af11ea0 commit 2ed6071
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import java.util.stream.Collectors;

import static org.bouncycastle.bcpg.CompressionAlgorithmTags.UNCOMPRESSED;
import static org.jreleaser.model.Signing.KEY_SKIP_SIGNING;

/**
* @author Andres Almiray
Expand Down Expand Up @@ -246,34 +247,40 @@ private static List<FilePair> collectArtifacts(JReleaserContext context, Keyring
Path signaturesDirectory = context.getSignaturesDirectory();
String extension = context.getModel().getSigning().isArmored() ? ".asc" : ".sig";

for (Artifact artifact : Artifacts.resolveFiles(context)) {
if (!artifact.isActive()) continue;
Path input = artifact.getEffectivePath(context);
Path output = signaturesDirectory.resolve(input.getFileName().toString().concat(extension));
FilePair pair = new FilePair(input, output);
pair.setValid(isValid(context, keyring, pair));
files.add(pair);
}

for (Distribution distribution : context.getModel().getActiveDistributions()) {
for (Artifact artifact : distribution.getArtifacts()) {
if (!artifact.isActive()) continue;
Path input = artifact.getEffectivePath(context, distribution);
if (context.getModel().getSigning().isFiles()) {
for (Artifact artifact : Artifacts.resolveFiles(context)) {
if (!artifact.isActive() || artifact.extraPropertyIsTrue(KEY_SKIP_SIGNING)) continue;
Path input = artifact.getEffectivePath(context);
Path output = signaturesDirectory.resolve(input.getFileName().toString().concat(extension));
FilePair pair = new FilePair(input, output);
pair.setValid(isValid(context, keyring, pair));
files.add(pair);
}
}

for (Algorithm algorithm : context.getModel().getChecksum().getAlgorithms()) {
Path checksums = context.getChecksumsDirectory()
.resolve(context.getModel().getChecksum().getResolvedName(context, algorithm));
if (Files.exists(checksums)) {
Path output = signaturesDirectory.resolve(checksums.getFileName().toString().concat(extension));
FilePair pair = new FilePair(checksums, output);
pair.setValid(isValid(context, keyring, pair));
files.add(pair);
if (context.getModel().getSigning().isArtifacts()) {
for (Distribution distribution : context.getModel().getActiveDistributions()) {
for (Artifact artifact : distribution.getArtifacts()) {
if (!artifact.isActive() || artifact.extraPropertyIsTrue(KEY_SKIP_SIGNING)) continue;
Path input = artifact.getEffectivePath(context, distribution);
Path output = signaturesDirectory.resolve(input.getFileName().toString().concat(extension));
FilePair pair = new FilePair(input, output);
pair.setValid(isValid(context, keyring, pair));
files.add(pair);
}
}
}

if (context.getModel().getSigning().isChecksums()) {
for (Algorithm algorithm : context.getModel().getChecksum().getAlgorithms()) {
Path checksums = context.getChecksumsDirectory()
.resolve(context.getModel().getChecksum().getResolvedName(context, algorithm));
if (Files.exists(checksums)) {
Path output = signaturesDirectory.resolve(checksums.getFileName().toString().concat(extension));
FilePair pair = new FilePair(checksums, output);
pair.setValid(isValid(context, keyring, pair));
files.add(pair);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,14 @@ public static Comparator<Artifact> comparatorByPlatform() {
};
}

public static Artifact of(Path resolvedPath, Map<String,Object> props) {
Artifact artifact = new Artifact();
artifact.path = resolvedPath.toAbsolutePath().toString();
artifact.resolvedPath = resolvedPath;
artifact.setExtraProperties(props);
return artifact;
}

public static Artifact of(Path resolvedPath) {
Artifact artifact = new Artifact();
artifact.path = resolvedPath.toAbsolutePath().toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Map;

import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.isTrue;
import static org.jreleaser.util.StringUtils.splitValue;

/**
Expand Down Expand Up @@ -73,4 +74,8 @@ default Map<String, Object> getResolvedExtraProperties(String prefix) {

return props;
}

default boolean extraPropertyIsTrue(String key) {
return getExtraProperties().containsKey(key) && isTrue(getExtraProperties().get(key));
}
}
66 changes: 56 additions & 10 deletions core/jreleaser-model/src/main/java/org/jreleaser/model/Signing.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
* @since 0.1.0
*/
public class Signing implements Domain, Activatable {
public static final String KEY_SKIP_SIGNING = "skipSigning";
public static final String GPG_PASSPHRASE = "GPG_PASSPHRASE";
public static final String GPG_PUBLIC_KEY = "GPG_PUBLIC_KEY";
public static final String GPG_SECRET_KEY = "GPG_SECRET_KEY";
Expand All @@ -44,6 +45,9 @@ public class Signing implements Domain, Activatable {
private String secretKey;
private String passphrase;
private Mode mode;
private Boolean artifacts;
private Boolean files;
private Boolean checksums;

void setAll(Signing signing) {
this.active = signing.active;
Expand All @@ -53,6 +57,9 @@ void setAll(Signing signing) {
this.secretKey = signing.secretKey;
this.passphrase = signing.passphrase;
this.mode = signing.mode;
this.artifacts = signing.artifacts;
this.files = signing.files;
this.checksums = signing.checksums;
}

@Override
Expand Down Expand Up @@ -153,20 +160,59 @@ public void setMode(String str) {
this.mode = Mode.of(str);
}

public boolean isArtifactsSet() {
return artifacts != null;
}

public Boolean isArtifacts() {
return artifacts == null || artifacts;
}

public void setArtifacts(Boolean artifacts) {
this.artifacts = artifacts;
}

public Boolean isFiles() {
return files == null || files;
}

public boolean isFilesSet() {
return files != null;
}

public void setFiles(Boolean files) {
this.files = files;
}

public boolean isChecksumsSet() {
return checksums != null;
}

public Boolean isChecksums() {
return checksums == null || checksums;
}

public void setChecksums(Boolean checksums) {
this.checksums = checksums;
}

@Override
public Map<String, Object> asMap(boolean full) {
if (!full && !isEnabled()) return Collections.emptyMap();

Map<String, Object> map = new LinkedHashMap<>();
map.put("enabled", isEnabled());
map.put("active", active);
map.put("armored", isArmored());
map.put("mode", mode);
map.put("publicKey", isNotBlank(publicKey) ? HIDE : UNSET);
map.put("secretKey", isNotBlank(secretKey) ? HIDE : UNSET);
map.put("passphrase", isNotBlank(passphrase) ? HIDE : UNSET);

return map;
Map<String, Object> props = new LinkedHashMap<>();
props.put("enabled", isEnabled());
props.put("active", active);
props.put("armored", isArmored());
props.put("mode", mode);
props.put("artifacts", isArtifacts());
props.put("files", isFiles());
props.put("checksums", isChecksums());
props.put("publicKey", isNotBlank(publicKey) ? HIDE : UNSET);
props.put("secretKey", isNotBlank(secretKey) ? HIDE : UNSET);
props.put("passphrase", isNotBlank(passphrase) ? HIDE : UNSET);

return props;
}

public enum Mode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import static org.jreleaser.util.StringUtils.capitalize;
import static org.jreleaser.util.StringUtils.getClassNameForLowerCaseHyphenSeparatedName;
import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isTrue;

/**
* @author Andres Almiray
Expand Down Expand Up @@ -167,8 +166,8 @@ public Map<String, String> resolveDownloadUrls(JReleaserContext context, Distrib
List<Uploader> uploaders = findAllUploaders();
for (Uploader uploader : uploaders) {
List<String> keys = uploader.resolveSkipKeys();
if (isSkip(distribution.getExtraProperties(), keys) ||
isSkip(artifact.getExtraProperties(), keys)) continue;
if (isSkip(distribution, keys) ||
isSkip(artifact, keys)) continue;
String key = prefix +
"Download" +
capitalize(uploader.getType()) +
Expand All @@ -177,8 +176,8 @@ public Map<String, String> resolveDownloadUrls(JReleaserContext context, Distrib
String url = uploader.getResolvedDownloadUrl(context, artifact);
urls.put(key, url);

if (findUploadersByType(uploader.getType()).size() == 1 && !isSkip(distribution.getExtraProperties(), keys) &&
!isSkip(artifact.getExtraProperties(), keys)) {
if (findUploadersByType(uploader.getType()).size() == 1 && !isSkip(distribution, keys) &&
!isSkip(artifact, keys)) {
key = prefix +
"Download" +
capitalize(uploader.getType()) +
Expand All @@ -191,8 +190,8 @@ public Map<String, String> resolveDownloadUrls(JReleaserContext context, Distrib
if (uploaders.size() == 1) {
Uploader uploader = uploaders.get(0);
List<String> keys = uploader.resolveSkipKeys();
if (!isSkip(distribution.getExtraProperties(), keys) &&
!isSkip(artifact.getExtraProperties(), keys)) {
if (!isSkip(distribution, keys) &&
!isSkip(artifact, keys)) {
String key = prefix + "DownloadUrl";
String url = uploader.getResolvedDownloadUrl(context, artifact);
urls.put(key, url);
Expand All @@ -202,9 +201,9 @@ public Map<String, String> resolveDownloadUrls(JReleaserContext context, Distrib
return urls;
}

private boolean isSkip(Map<String, Object> props, List<String> keys) {
private boolean isSkip(ExtraProperties props, List<String> keys) {
for (String key : keys) {
if (props.containsKey(key) && isTrue(props.get(key))) {
if (props.extraPropertyIsTrue(key)) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import static java.util.Objects.requireNonNull;
import static org.jreleaser.model.Checksum.INDIVIDUAL_CHECKSUM;
import static org.jreleaser.model.Signing.KEY_SKIP_SIGNING;
import static org.jreleaser.util.StringUtils.isTrue;

/**
Expand Down Expand Up @@ -76,15 +77,16 @@ protected void validate() {
public ReleaserBuilder<R> configureWith(JReleaserContext context) {
this.context = context;

boolean uploadIndividualChecksums = context.getModel().getChecksum().isIndividual();
List<Artifact> artifacts = new ArrayList<>();

for (Artifact artifact : Artifacts.resolveFiles(context)) {
if (!artifact.isActive()) continue;
Path path = artifact.getEffectivePath(context);
addReleaseAsset(path);
artifacts.add(Artifact.of(path, artifact.getExtraProperties()));
if (isIndividual(context, artifact)) {
for (Algorithm algorithm : context.getModel().getChecksum().getAlgorithms()) {
addReleaseAsset(context.getChecksumsDirectory()
.resolve(path.getFileName() + "." + algorithm.formatted()));
artifacts.add(Artifact.of(context.getChecksumsDirectory()
.resolve(path.getFileName() + "." + algorithm.formatted())));
}
}
}
Expand All @@ -93,12 +95,12 @@ public ReleaserBuilder<R> configureWith(JReleaserContext context) {
for (Artifact artifact : distribution.getArtifacts()) {
if (!artifact.isActive()) continue;
Path path = artifact.getEffectivePath(context, distribution);
addReleaseAsset(path);
artifacts.add(Artifact.of(path, artifact.getExtraProperties()));
if (isIndividual(context, distribution, artifact)) {
for (Algorithm algorithm : context.getModel().getChecksum().getAlgorithms()) {
addReleaseAsset(context.getChecksumsDirectory()
artifacts.add(Artifact.of(context.getChecksumsDirectory()
.resolve(distribution.getName())
.resolve(path.getFileName() + "." + algorithm.formatted()));
.resolve(path.getFileName() + "." + algorithm.formatted())));
}
}
}
Expand All @@ -108,21 +110,26 @@ public ReleaserBuilder<R> configureWith(JReleaserContext context) {
Path checksums = context.getChecksumsDirectory()
.resolve(context.getModel().getChecksum().getResolvedName(context, algorithm));
if (Files.exists(checksums)) {
addReleaseAsset(checksums);
artifacts.add(Artifact.of(checksums));
}
}

if (context.getModel().getSigning().isEnabled()) {
List<Path> assetsCopy = new ArrayList<>(assets);
for (Path asset : assetsCopy) {
List<Artifact> artifactsCopy = new ArrayList<>(artifacts);
for (Artifact artifact : artifactsCopy) {
if (artifact.extraPropertyIsTrue(KEY_SKIP_SIGNING)) continue;
Path signature = context.getSignaturesDirectory()
.resolve(asset.getFileName().toString() + (context.getModel().getSigning().isArmored() ? ".asc" : ".sig"));
.resolve(artifact.getResolvedPath().getFileName().toString() + (context.getModel().getSigning().isArmored() ? ".asc" : ".sig"));
if (Files.exists(signature)) {
addReleaseAsset(signature);
artifacts.add(Artifact.of(signature));
}
}
}

artifacts.stream()
.map(Artifact::getResolvedPath)
.forEach(this::addReleaseAsset);

return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ interface Signing {
Property<org.jreleaser.model.Signing.Mode> getMode()

void setMode(String mode)

Property<Boolean> getArtifacts()

Property<Boolean> getFiles()

Property<Boolean> getChecksums()
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class SigningImpl implements Signing {
final Property<String> publicKey
final Property<String> secretKey
final Property<org.jreleaser.model.Signing.Mode> mode
final Property<Boolean> artifacts
final Property<Boolean> files
final Property<Boolean> checksums

@Inject
SigningImpl(ObjectFactory objects) {
Expand All @@ -51,6 +54,9 @@ class SigningImpl implements Signing {
publicKey = objects.property(String).convention(Providers.notDefined())
secretKey = objects.property(String).convention(Providers.notDefined())
mode = objects.property(org.jreleaser.model.Signing.Mode).convention(org.jreleaser.model.Signing.Mode.MEMORY)
artifacts = objects.property(Boolean).convention(Providers.notDefined())
files = objects.property(Boolean).convention(Providers.notDefined())
checksums = objects.property(Boolean).convention(Providers.notDefined())
}

@Internal
Expand All @@ -59,6 +65,9 @@ class SigningImpl implements Signing {
armored.present ||
passphrase.present ||
publicKey.present ||
artifacts.present ||
files.present ||
checksums.present ||
secretKey.present
}

Expand All @@ -84,6 +93,9 @@ class SigningImpl implements Signing {
if (publicKey.present) signing.publicKey = publicKey.get()
if (secretKey.present) signing.secretKey = secretKey.get()
if (mode.present) signing.mode = mode.get()
if (artifacts.present) signing.artifacts = artifacts.get()
if (files.present) signing.files = files.get()
if (checksums.present) signing.checksums = checksums.get()
signing
}
}

0 comments on commit 2ed6071

Please sign in to comment.