diff --git a/ci/images/releasescripts/pom.xml b/ci/images/releasescripts/pom.xml
index d01c936aed..746f0593f7 100644
--- a/ci/images/releasescripts/pom.xml
+++ b/ci/images/releasescripts/pom.xml
@@ -19,6 +19,11 @@
0.0.26
+
+ org.bouncycastle
+ bcpg-jdk15to18
+ 1.68
+
org.springframework.boot
spring-boot-starter
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryService.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryService.java
index 811eedd636..49f51f4309 100644
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryService.java
+++ b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryService.java
@@ -17,14 +17,10 @@
package io.spring.concourse.releasescripts.artifactory;
import java.net.URI;
-import java.time.Duration;
-import java.util.Set;
import io.spring.concourse.releasescripts.ReleaseInfo;
import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-import io.spring.concourse.releasescripts.artifactory.payload.DistributionRequest;
import io.spring.concourse.releasescripts.artifactory.payload.PromotionRequest;
-import io.spring.concourse.releasescripts.bintray.BintrayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,17 +49,11 @@ public class ArtifactoryService {
private static final String BUILD_INFO_URL = ARTIFACTORY_URL + "/api/build/";
- private static final String DISTRIBUTION_URL = ARTIFACTORY_URL + "/api/build/distribute/";
-
private static final String STAGING_REPO = "libs-staging-local";
private final RestTemplate restTemplate;
- private final BintrayService bintrayService;
-
- public ArtifactoryService(RestTemplateBuilder builder, ArtifactoryProperties artifactoryProperties,
- BintrayService bintrayService) {
- this.bintrayService = bintrayService;
+ public ArtifactoryService(RestTemplateBuilder builder, ArtifactoryProperties artifactoryProperties) {
String username = artifactoryProperties.getUsername();
String password = artifactoryProperties.getPassword();
if (StringUtils.hasLength(username)) {
@@ -116,37 +106,6 @@ public class ArtifactoryService {
}
}
- /**
- * Deploy builds from Artifactory to Bintray.
- * @param sourceRepo the source repo in Artifactory.
- * @param releaseInfo the resease info
- * @param artifactDigests the artifact digests
- */
- public void distribute(String sourceRepo, ReleaseInfo releaseInfo, Set artifactDigests) {
- logger.debug("Attempting distribute via Artifactory");
- if (!this.bintrayService.isDistributionStarted(releaseInfo)) {
- startDistribute(sourceRepo, releaseInfo);
- }
- if (!this.bintrayService.isDistributionComplete(releaseInfo, artifactDigests, Duration.ofMinutes(60))) {
- throw new DistributionTimeoutException("Distribution timed out.");
- }
- }
-
- private void startDistribute(String sourceRepo, ReleaseInfo releaseInfo) {
- DistributionRequest request = new DistributionRequest(new String[] { sourceRepo });
- RequestEntity requestEntity = RequestEntity
- .post(URI.create(DISTRIBUTION_URL + releaseInfo.getBuildName() + "/" + releaseInfo.getBuildNumber()))
- .contentType(MediaType.APPLICATION_JSON).body(request);
- try {
- this.restTemplate.exchange(requestEntity, Object.class);
- logger.debug("Distribute call completed");
- }
- catch (HttpClientErrorException ex) {
- logger.info("Failed to distribute.");
- throw ex;
- }
- }
-
private PromotionRequest getPromotionRequest(String targetRepo) {
return new PromotionRequest("staged", STAGING_REPO, targetRepo);
}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayProperties.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayProperties.java
deleted file mode 100644
index 7612ff7776..0000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayProperties.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.bintray;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * {@link ConfigurationProperties @ConfigurationProperties} for the Bintray API.
- *
- * @author Madhura Bhave
- */
-@ConfigurationProperties(prefix = "bintray")
-public class BintrayProperties {
-
- private String username;
-
- private String apiKey;
-
- private String repo;
-
- private String subject;
-
- public String getUsername() {
- return this.username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getApiKey() {
- return this.apiKey;
- }
-
- public void setApiKey(String apiKey) {
- this.apiKey = apiKey;
- }
-
- public String getRepo() {
- return this.repo;
- }
-
- public void setRepo(String repo) {
- this.repo = repo;
- }
-
- public String getSubject() {
- return this.subject;
- }
-
- public void setSubject(String subject) {
- this.subject = subject;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayService.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayService.java
deleted file mode 100644
index 98a075fa5a..0000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayService.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.bintray;
-
-import java.net.URI;
-import java.time.Duration;
-import java.util.HashSet;
-import java.util.Set;
-
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.sonatype.SonatypeProperties;
-import io.spring.concourse.releasescripts.sonatype.SonatypeService;
-import org.awaitility.core.ConditionTimeoutException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.RequestEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
-import org.springframework.web.client.HttpClientErrorException;
-import org.springframework.web.client.RestTemplate;
-
-import static org.awaitility.Awaitility.waitAtMost;
-
-/**
- * Central class for interacting with Bintray's REST API.
- *
- * @author Madhura Bhave
- */
-@Component
-public class BintrayService {
-
- private static final Logger logger = LoggerFactory.getLogger(BintrayService.class);
-
- private static final String BINTRAY_URL = "https://api.bintray.com/";
-
- private static final String GRADLE_PLUGIN_REQUEST = "[ { \"name\": \"gradle-plugin\", \"values\": [\"org.springframework.boot:org.springframework.boot:spring-boot-gradle-plugin\"] } ]";
-
- private final RestTemplate restTemplate;
-
- private final BintrayProperties bintrayProperties;
-
- private final SonatypeProperties sonatypeProperties;
-
- private final SonatypeService sonatypeService;
-
- public BintrayService(RestTemplateBuilder builder, BintrayProperties bintrayProperties,
- SonatypeProperties sonatypeProperties, SonatypeService sonatypeService) {
- this.bintrayProperties = bintrayProperties;
- this.sonatypeProperties = sonatypeProperties;
- this.sonatypeService = sonatypeService;
- String username = bintrayProperties.getUsername();
- String apiKey = bintrayProperties.getApiKey();
- if (StringUtils.hasLength(username)) {
- builder = builder.basicAuthentication(username, apiKey);
- }
- this.restTemplate = builder.build();
- }
-
- public boolean isDistributionStarted(ReleaseInfo releaseInfo) {
- logger.debug("Checking if distribution is started");
- RequestEntity request = getPackageFilesRequest(releaseInfo, 1);
- try {
- logger.debug("Checking Bintray");
- this.restTemplate.exchange(request, PackageFile[].class).getBody();
- return true;
- }
- catch (HttpClientErrorException ex) {
- if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
- throw ex;
- }
- return false;
- }
- }
-
- public boolean isDistributionComplete(ReleaseInfo releaseInfo, Set requiredDigests, Duration timeout) {
- return isDistributionComplete(releaseInfo, requiredDigests, timeout, Duration.ofSeconds(20));
- }
-
- public boolean isDistributionComplete(ReleaseInfo releaseInfo, Set requiredDigests, Duration timeout,
- Duration pollInterval) {
- logger.debug("Checking if distribution is complete");
- RequestEntity request = getPackageFilesRequest(releaseInfo, 1);
- try {
- waitAtMost(timeout).with().pollDelay(Duration.ZERO).pollInterval(pollInterval).until(() -> {
- logger.debug("Checking Bintray");
- try {
- PackageFile[] published = this.restTemplate.exchange(request, PackageFile[].class).getBody();
- return hasPublishedAll(published, requiredDigests);
- }
- catch (HttpClientErrorException.NotFound ex) {
- return false;
- }
- });
- }
- catch (ConditionTimeoutException ex) {
- logger.debug("Timeout checking Bintray");
- return false;
- }
- return true;
- }
-
- private boolean hasPublishedAll(PackageFile[] published, Set requiredDigests) {
- if (published == null || published.length == 0) {
- logger.debug("Bintray returned no published files");
- return false;
- }
- Set remaining = new HashSet<>(requiredDigests);
- for (PackageFile publishedFile : published) {
- logger.debug(
- "Found published file " + publishedFile.getName() + " with digest " + publishedFile.getSha256());
- remaining.remove(publishedFile.getSha256());
- }
- if (remaining.isEmpty()) {
- logger.debug("Found all required digests");
- return true;
- }
- logger.debug(remaining.size() + " digests have not been published:");
- remaining.forEach(logger::debug);
- return false;
- }
-
- private RequestEntity getPackageFilesRequest(ReleaseInfo releaseInfo, int includeUnpublished) {
- return RequestEntity.get(URI.create(BINTRAY_URL + "packages/" + this.bintrayProperties.getSubject() + "/"
- + this.bintrayProperties.getRepo() + "/" + releaseInfo.getGroupId() + "/versions/"
- + releaseInfo.getVersion() + "/files?include_unpublished=" + includeUnpublished)).build();
- }
-
- /**
- * Add attributes to Spring Boot's Gradle plugin.
- * @param releaseInfo the release information
- */
- public void publishGradlePlugin(ReleaseInfo releaseInfo) {
- logger.debug("Publishing Gradle plugin");
- RequestEntity requestEntity = RequestEntity
- .post(URI.create(BINTRAY_URL + "packages/" + this.bintrayProperties.getSubject() + "/"
- + this.bintrayProperties.getRepo() + "/" + releaseInfo.getGroupId() + "/versions/"
- + releaseInfo.getVersion() + "/attributes"))
- .contentType(MediaType.APPLICATION_JSON).body(GRADLE_PLUGIN_REQUEST);
- try {
- this.restTemplate.exchange(requestEntity, Object.class);
- logger.debug("Publishing Gradle plugin complete");
- }
- catch (HttpClientErrorException ex) {
- logger.info("Failed to add attribute to Gradle plugin");
- throw ex;
- }
- }
-
- /**
- * Sync artifacts from Bintray to Maven Central.
- * @param releaseInfo the release information
- */
- public void syncToMavenCentral(ReleaseInfo releaseInfo) {
- logger.info("Calling Bintray to sync to Sonatype");
- if (this.sonatypeService.artifactsPublished(releaseInfo)) {
- logger.info("Artifacts already published");
- return;
- }
- RequestEntity requestEntity = RequestEntity
- .post(URI.create(String.format(BINTRAY_URL + "maven_central_sync/%s/%s/%s/versions/%s",
- this.bintrayProperties.getSubject(), this.bintrayProperties.getRepo(), releaseInfo.getGroupId(),
- releaseInfo.getVersion())))
- .contentType(MediaType.APPLICATION_JSON).body(this.sonatypeProperties);
- try {
- this.restTemplate.exchange(requestEntity, Object.class);
- logger.debug("Sync complete");
- }
- catch (HttpClientErrorException ex) {
- logger.info("Failed to sync");
- throw ex;
- }
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeCommand.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeCommand.java
deleted file mode 100644
index f8f8ea11a1..0000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeCommand.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.io.File;
-import java.nio.file.Files;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.ReleaseType;
-import io.spring.concourse.releasescripts.artifactory.ArtifactoryService;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse.Artifact;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse.BuildInfo;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-
-/**
- * Command used to deploy builds from Artifactory to Bintray.
- *
- * @author Madhura Bhave
- * @author Phillip Webb
- */
-@Component
-public class DistributeCommand implements Command {
-
- private static final Logger logger = LoggerFactory.getLogger(DistributeCommand.class);
-
- private final ArtifactoryService artifactoryService;
-
- private final ObjectMapper objectMapper;
-
- private final List optionalDeployments;
-
- public DistributeCommand(ArtifactoryService artifactoryService, ObjectMapper objectMapper,
- DistributeProperties distributeProperties) {
- this.artifactoryService = artifactoryService;
- this.objectMapper = objectMapper;
- this.optionalDeployments = distributeProperties.getOptionalDeployments().stream().map(Pattern::compile)
- .collect(Collectors.toList());
- }
-
- @Override
- public void run(ApplicationArguments args) throws Exception {
- logger.debug("Running 'distribute' command");
- List nonOptionArgs = args.getNonOptionArgs();
- Assert.state(!nonOptionArgs.isEmpty(), "No command argument specified");
- Assert.state(nonOptionArgs.size() == 3, "Release type or build info not specified");
- String releaseType = nonOptionArgs.get(1);
- ReleaseType type = ReleaseType.from(releaseType);
- if (!ReleaseType.RELEASE.equals(type)) {
- logger.info("Skipping distribution of " + type + " type");
- return;
- }
- String buildInfoLocation = nonOptionArgs.get(2);
- logger.debug("Loading build-info from " + buildInfoLocation);
- byte[] content = Files.readAllBytes(new File(buildInfoLocation).toPath());
- BuildInfoResponse buildInfoResponse = this.objectMapper.readValue(content, BuildInfoResponse.class);
- BuildInfo buildInfo = buildInfoResponse.getBuildInfo();
- logger.debug("Loading build info:");
- for (Module module : buildInfo.getModules()) {
- logger.debug(module.getId());
- for (Artifact artifact : module.getArtifacts()) {
- logger.debug(artifact.getSha256() + " " + artifact.getName());
- }
- }
- ReleaseInfo releaseInfo = ReleaseInfo.from(buildInfo);
- Set artifactDigests = buildInfo.getArtifactDigests(this::isIncluded);
- this.artifactoryService.distribute(type.getRepo(), releaseInfo, artifactDigests);
- }
-
- private boolean isIncluded(Artifact artifact) {
- String path = artifact.getName();
- for (Pattern optionalDeployment : this.optionalDeployments) {
- if (optionalDeployment.matcher(path).matches()) {
- return false;
- }
- }
- return true;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeProperties.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeProperties.java
deleted file mode 100644
index d93737e749..0000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeProperties.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2020-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * Distribution properties.
- *
- * @author Phillip Webb
- */
-@ConfigurationProperties(prefix = "distribute")
-public class DistributeProperties {
-
- private List optionalDeployments = new ArrayList<>();
-
- public List getOptionalDeployments() {
- return this.optionalDeployments;
- }
-
- public void setOptionalDeployments(List optionalDeployments) {
- this.optionalDeployments = optionalDeployments;
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishGradlePlugin.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToCentralCommand.java
similarity index 66%
rename from ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishGradlePlugin.java
rename to ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToCentralCommand.java
index aa3f42c510..23ec5a319d 100644
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishGradlePlugin.java
+++ b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/PublishToCentralCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.concourse.releasescripts.ReleaseInfo;
import io.spring.concourse.releasescripts.ReleaseType;
import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-import io.spring.concourse.releasescripts.bintray.BintrayService;
+import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse.BuildInfo;
+import io.spring.concourse.releasescripts.sonatype.SonatypeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,47 +34,46 @@ import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
/**
- * Command used to add attributes to the gradle plugin.
+ * Command used to publish a release to Maven Central.
*
- * @author Madhura Bhave
+ * @author Andy Wilkinson
*/
@Component
-public class PublishGradlePlugin implements Command {
+public class PublishToCentralCommand implements Command {
- private static final Logger logger = LoggerFactory.getLogger(PublishGradlePlugin.class);
+ private static final Logger logger = LoggerFactory.getLogger(PublishToCentralCommand.class);
- private static final String PUBLISH_GRADLE_PLUGIN_COMMAND = "publishGradlePlugin";
-
- private final BintrayService service;
+ private final SonatypeService sonatype;
private final ObjectMapper objectMapper;
- public PublishGradlePlugin(BintrayService service, ObjectMapper objectMapper) {
- this.service = service;
+ public PublishToCentralCommand(SonatypeService sonatype, ObjectMapper objectMapper) {
+ this.sonatype = sonatype;
this.objectMapper = objectMapper;
}
@Override
public String getName() {
- return PUBLISH_GRADLE_PLUGIN_COMMAND;
+ return "publishToCentral";
}
@Override
public void run(ApplicationArguments args) throws Exception {
- logger.debug("Running 'publish gradle' command");
List nonOptionArgs = args.getNonOptionArgs();
- Assert.state(!nonOptionArgs.isEmpty(), "No command argument specified");
- Assert.state(nonOptionArgs.size() == 3, "Release type or build info not specified");
+ Assert.state(nonOptionArgs.size() == 4,
+ "Release type, build info location, or artifacts location not specified");
String releaseType = nonOptionArgs.get(1);
ReleaseType type = ReleaseType.from(releaseType);
if (!ReleaseType.RELEASE.equals(type)) {
return;
}
String buildInfoLocation = nonOptionArgs.get(2);
+ logger.debug("Loading build-info from " + buildInfoLocation);
byte[] content = Files.readAllBytes(new File(buildInfoLocation).toPath());
BuildInfoResponse buildInfoResponse = this.objectMapper.readValue(content, BuildInfoResponse.class);
- ReleaseInfo releaseInfo = ReleaseInfo.from(buildInfoResponse.getBuildInfo());
- this.service.publishGradlePlugin(releaseInfo);
+ BuildInfo buildInfo = buildInfoResponse.getBuildInfo();
+ String artifactsLocation = nonOptionArgs.get(3);
+ this.sonatype.publish(ReleaseInfo.from(buildInfo), new File(artifactsLocation).toPath());
}
}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/SyncToCentralCommand.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/SyncToCentralCommand.java
deleted file mode 100644
index e2a5cab5a8..0000000000
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/SyncToCentralCommand.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.io.File;
-import java.nio.file.Files;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.ReleaseType;
-import io.spring.concourse.releasescripts.artifactory.payload.BuildInfoResponse;
-import io.spring.concourse.releasescripts.bintray.BintrayService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-
-/**
- * Command used to sync artifacts to Maven Central.
- *
- * @author Madhura Bhave
- */
-@Component
-public class SyncToCentralCommand implements Command {
-
- private static final Logger logger = LoggerFactory.getLogger(SyncToCentralCommand.class);
-
- private static final String SYNC_TO_CENTRAL_COMMAND = "syncToCentral";
-
- private final BintrayService service;
-
- private final ObjectMapper objectMapper;
-
- public SyncToCentralCommand(BintrayService service, ObjectMapper objectMapper) {
- this.service = service;
- this.objectMapper = objectMapper;
- }
-
- @Override
- public String getName() {
- return SYNC_TO_CENTRAL_COMMAND;
- }
-
- @Override
- public void run(ApplicationArguments args) throws Exception {
- logger.debug("Running 'sync to central' command");
- List nonOptionArgs = args.getNonOptionArgs();
- Assert.state(!nonOptionArgs.isEmpty(), "No command argument specified");
- Assert.state(nonOptionArgs.size() == 3, "Release type or build info not specified");
- String releaseType = nonOptionArgs.get(1);
- ReleaseType type = ReleaseType.from(releaseType);
- if (!ReleaseType.RELEASE.equals(type)) {
- return;
- }
- String buildInfoLocation = nonOptionArgs.get(2);
- byte[] content = Files.readAllBytes(new File(buildInfoLocation).toPath());
- BuildInfoResponse buildInfoResponse = this.objectMapper.readValue(content, BuildInfoResponse.class);
- ReleaseInfo releaseInfo = ReleaseInfo.from(buildInfoResponse.getBuildInfo());
- this.service.syncToMavenCentral(releaseInfo);
- }
-
-}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/ArtifactCollector.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/ArtifactCollector.java
new file mode 100644
index 0000000000..0548e75a0a
--- /dev/null
+++ b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/ArtifactCollector.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.concourse.releasescripts.sonatype;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.springframework.core.io.PathResource;
+
+/**
+ * Collects artifacts to be deployed.
+ *
+ * @author Andy Wilkinson
+ */
+class ArtifactCollector {
+
+ private final Predicate excludeFilter;
+
+ ArtifactCollector(List exclude) {
+ this.excludeFilter = excludeFilter(exclude);
+ }
+
+ private Predicate excludeFilter(List exclude) {
+ Predicate patternFilter = exclude.stream().map(Pattern::compile).map(Pattern::asPredicate)
+ .reduce((path) -> false, Predicate::or).negate();
+ return (path) -> patternFilter.test(path.toString());
+ }
+
+ Collection collectArtifacts(Path root) {
+ try (Stream artifacts = Files.walk(root)) {
+ return artifacts.filter(Files::isRegularFile).filter(this.excludeFilter)
+ .map((artifact) -> deployableArtifact(artifact, root)).collect(Collectors.toList());
+ }
+ catch (IOException ex) {
+ throw new RuntimeException("Could not read artifacts from '" + root + "'");
+ }
+ }
+
+ private DeployableArtifact deployableArtifact(Path artifact, Path root) {
+ return new DeployableArtifact(new PathResource(artifact), root.relativize(artifact).toString());
+ }
+
+}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/PackageFile.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/DeployableArtifact.java
similarity index 54%
rename from ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/PackageFile.java
rename to ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/DeployableArtifact.java
index ee7728e812..45bfa9c3d2 100644
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/PackageFile.java
+++ b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/DeployableArtifact.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2020 the original author or authors.
+ * Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,25 +14,32 @@
* limitations under the License.
*/
-package io.spring.concourse.releasescripts.bintray;
+package io.spring.concourse.releasescripts.sonatype;
+
+import org.springframework.core.io.Resource;
/**
- * Details for a single packaged file.
+ * An artifact that can be deployed.
*
- * @author Phillip Webb
+ * @author Andy Wilkinson
*/
-public class PackageFile {
+class DeployableArtifact {
+
+ private final Resource resource;
- private String name;
+ private final String path;
- private String sha256;
+ DeployableArtifact(Resource resource, String path) {
+ this.resource = resource;
+ this.path = path;
+ }
- public String getName() {
- return this.name;
+ Resource getResource() {
+ return this.resource;
}
- public String getSha256() {
- return this.sha256;
+ String getPath() {
+ return this.path;
}
-}
+}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeProperties.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeProperties.java
index 165bcfea38..4f9d0a4c54 100644
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeProperties.java
+++ b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2019 the original author or authors.
+ * Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,10 @@
package io.spring.concourse.releasescripts.sonatype;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -34,6 +38,32 @@ public class SonatypeProperties {
@JsonProperty("password")
private String passwordToken;
+ /**
+ * URL of the Nexus instance used to publish releases.
+ */
+ private String url;
+
+ /**
+ * ID of the staging profile used to publish releases.
+ */
+ private String stagingProfileId;
+
+ /**
+ * Time between requests made to determine if the closing of a staging repository has
+ * completed.
+ */
+ private Duration pollingInterval = Duration.ofSeconds(15);
+
+ /**
+ * Number of threads used to upload artifacts to the staging repository.
+ */
+ private int uploadThreads = 8;
+
+ /**
+ * Regular expression patterns of artifacts to exclude
+ */
+ private List exclude = new ArrayList<>();
+
public String getUserToken() {
return this.userToken;
}
@@ -50,4 +80,44 @@ public class SonatypeProperties {
this.passwordToken = passwordToken;
}
+ public String getUrl() {
+ return this.url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getStagingProfileId() {
+ return this.stagingProfileId;
+ }
+
+ public void setStagingProfileId(String stagingProfileId) {
+ this.stagingProfileId = stagingProfileId;
+ }
+
+ public Duration getPollingInterval() {
+ return this.pollingInterval;
+ }
+
+ public void setPollingInterval(Duration pollingInterval) {
+ this.pollingInterval = pollingInterval;
+ }
+
+ public int getUploadThreads() {
+ return this.uploadThreads;
+ }
+
+ public void setUploadThreads(int uploadThreads) {
+ this.uploadThreads = uploadThreads;
+ }
+
+ public List getExclude() {
+ return this.exclude;
+ }
+
+ public void setExclude(List exclude) {
+ this.exclude = exclude;
+ }
+
}
diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeService.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeService.java
index 789e4ba6a3..1f17dd1260 100644
--- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeService.java
+++ b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sonatype/SonatypeService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,28 @@
package io.spring.concourse.releasescripts.sonatype;
+import java.nio.file.Path;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonCreator.Mode;
+import com.fasterxml.jackson.annotation.JsonProperty;
import io.spring.concourse.releasescripts.ReleaseInfo;
+import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,23 +53,39 @@ import org.springframework.web.client.RestTemplate;
* Central class for interacting with Sonatype.
*
* @author Madhura Bhave
+ * @author Andy Wilkinson
*/
@Component
public class SonatypeService {
private static final Logger logger = LoggerFactory.getLogger(SonatypeService.class);
- private static final String SONATYPE_REPOSITORY_URI = "https://oss.sonatype.org/service/local/repositories/releases/content/org/springframework/boot/spring-boot/";
+ private static final String NEXUS_REPOSITORY_PATH = "/service/local/repositories/releases/content/org/springframework/boot/spring-boot/";
+
+ private static final String NEXUS_STAGING_PATH = "/service/local/staging/";
+
+ private final ArtifactCollector artifactCollector;
private final RestTemplate restTemplate;
+ private final String stagingProfileId;
+
+ private final Duration pollingInterval;
+
+ private final int threads;
+
public SonatypeService(RestTemplateBuilder builder, SonatypeProperties sonatypeProperties) {
String username = sonatypeProperties.getUserToken();
String password = sonatypeProperties.getPasswordToken();
if (StringUtils.hasLength(username)) {
builder = builder.basicAuthentication(username, password);
}
- this.restTemplate = builder.build();
+ this.restTemplate = builder.rootUri(sonatypeProperties.getUrl()).build();
+ this.stagingProfileId = sonatypeProperties.getStagingProfileId();
+ this.pollingInterval = sonatypeProperties.getPollingInterval();
+ this.threads = sonatypeProperties.getUploadThreads();
+
+ this.artifactCollector = new ArtifactCollector(sonatypeProperties.getExclude());
}
/**
@@ -59,7 +96,7 @@ public class SonatypeService {
public boolean artifactsPublished(ReleaseInfo releaseInfo) {
try {
ResponseEntity> entity = this.restTemplate
- .getForEntity(String.format(SONATYPE_REPOSITORY_URI + "%s/spring-boot-%s.jar.sha1",
+ .getForEntity(String.format(NEXUS_REPOSITORY_PATH + "%s/spring-boot-%s.jar.sha1",
releaseInfo.getVersion(), releaseInfo.getVersion()), byte[].class);
if (HttpStatus.OK.equals(entity.getStatusCode())) {
logger.info("Already published to Sonatype.");
@@ -72,4 +109,200 @@ public class SonatypeService {
return false;
}
+ /**
+ * Publishes the release by creating a staging repository and deploying to it the
+ * artifacts at the given {@code artifactsRoot}. The repository is then closed and,
+ * upon successfully closure, it is released.
+ * @param releaseInfo the release information
+ * @param artifactsRoot the root directory of the artifacts to stage
+ */
+ public void publish(ReleaseInfo releaseInfo, Path artifactsRoot) {
+ logger.info("Creating staging repository");
+ String buildId = releaseInfo.getBuildNumber();
+ String repositoryId = createStagingRepository(buildId);
+ Collection artifacts = this.artifactCollector.collectArtifacts(artifactsRoot);
+ logger.info("Staging repository {} created. Deploying {} artifacts", repositoryId, artifacts.size());
+ deploy(artifacts, repositoryId);
+ logger.info("Deploy complete. Closing staging repository");
+ close(repositoryId);
+ logger.info("Staging repository closed");
+ release(repositoryId, buildId);
+ logger.info("Staging repository released");
+ }
+
+ private String createStagingRepository(String buildId) {
+ Map body = new HashMap<>();
+ body.put("data", Collections.singletonMap("description", buildId));
+ PromoteResponse response = this.restTemplate.postForObject(
+ String.format(NEXUS_STAGING_PATH + "profiles/%s/start", this.stagingProfileId), body,
+ PromoteResponse.class);
+ String repositoryId = response.data.stagedRepositoryId;
+ return repositoryId;
+ }
+
+ private void deploy(Collection artifacts, String repositoryId) {
+ ExecutorService executor = Executors.newFixedThreadPool(this.threads);
+ try {
+ CompletableFuture.allOf(artifacts.stream()
+ .map((artifact) -> CompletableFuture.runAsync(() -> deploy(artifact, repositoryId), executor))
+ .toArray(CompletableFuture[]::new)).get(60, TimeUnit.MINUTES);
+ }
+ catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Interrupted during artifact deploy");
+ }
+ catch (ExecutionException ex) {
+ throw new RuntimeException("Deploy failed", ex);
+ }
+ catch (TimeoutException ex) {
+ throw new RuntimeException("Deploy timed out", ex);
+ }
+ finally {
+ executor.shutdown();
+ }
+ }
+
+ private void deploy(DeployableArtifact deployableArtifact, String repositoryId) {
+ try {
+ this.restTemplate.put(
+ NEXUS_STAGING_PATH + "deployByRepositoryId/" + repositoryId + "/" + deployableArtifact.getPath(),
+ deployableArtifact.getResource());
+ logger.info("Deloyed {}", deployableArtifact.getPath());
+ }
+ catch (HttpClientErrorException ex) {
+ logger.error("Failed to deploy {}. Error response: {}", deployableArtifact.getPath(),
+ ex.getResponseBodyAsString());
+ throw ex;
+ }
+ }
+
+ private void close(String stagedRepositoryId) {
+ Map body = new HashMap<>();
+ body.put("data", Collections.singletonMap("stagedRepositoryId", stagedRepositoryId));
+ this.restTemplate.postForEntity(String.format(NEXUS_STAGING_PATH + "profiles/%s/finish", this.stagingProfileId),
+ body, Void.class);
+ logger.info("Close requested. Awaiting result");
+ while (true) {
+ StagingRepository repository = this.restTemplate
+ .getForObject(NEXUS_STAGING_PATH + "repository/" + stagedRepositoryId, StagingRepository.class);
+ if (!repository.transitioning) {
+ if ("open".equals(repository.type)) {
+ logFailures(stagedRepositoryId);
+ throw new RuntimeException("Close failed");
+ }
+ return;
+ }
+ try {
+ Thread.sleep(this.pollingInterval.toMillis());
+ }
+ catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Interrupted while waiting for staging repository to close", ex);
+ }
+ }
+ }
+
+ private void logFailures(String stagedRepositoryId) {
+ try {
+ StagingRepositoryActivity[] activities = this.restTemplate.getForObject(
+ NEXUS_STAGING_PATH + "repository/" + stagedRepositoryId + "/activity",
+ StagingRepositoryActivity[].class);
+ List failureMessages = Stream.of(activities).flatMap((activity) -> activity.events.stream())
+ .filter((event) -> event.severity > 0).flatMap((event) -> event.properties.stream())
+ .filter((property) -> "failureMessage".equals(property.name))
+ .map((property) -> " " + property.value).collect(Collectors.toList());
+ if (failureMessages.isEmpty()) {
+ logger.error("Close failed for unknown reasons");
+ }
+ logger.error("Close failed:\n{}", Strings.join(failureMessages, '\n'));
+ }
+ catch (Exception ex) {
+ logger.error("Failed to determine causes of close failure", ex);
+ }
+ }
+
+ private void release(String stagedRepositoryId, String buildId) {
+ Map data = new HashMap<>();
+ data.put("stagedRepositoryIds", Arrays.asList(stagedRepositoryId));
+ data.put("description", "Releasing " + buildId);
+ data.put("autoDropAfterRelease", true);
+ Map body = Collections.singletonMap("data", data);
+ this.restTemplate.postForEntity(NEXUS_STAGING_PATH + "bulk/promote", body, Void.class);
+ }
+
+ private static final class PromoteResponse {
+
+ private final Data data;
+
+ @JsonCreator(mode = Mode.PROPERTIES)
+ private PromoteResponse(@JsonProperty("data") Data data) {
+ this.data = data;
+ }
+
+ private static final class Data {
+
+ private final String stagedRepositoryId;
+
+ @JsonCreator(mode = Mode.PROPERTIES)
+ Data(@JsonProperty("stagedRepositoryId") String stagedRepositoryId) {
+ this.stagedRepositoryId = stagedRepositoryId;
+ }
+
+ }
+
+ }
+
+ private static final class StagingRepository {
+
+ private final String type;
+
+ private final boolean transitioning;
+
+ private StagingRepository(String type, boolean transitioning) {
+ this.type = type;
+ this.transitioning = transitioning;
+ }
+
+ }
+
+ private static final class StagingRepositoryActivity {
+
+ private final List events;
+
+ @JsonCreator
+ private StagingRepositoryActivity(@JsonProperty("events") List events) {
+ this.events = events;
+ }
+
+ private static class Event {
+
+ private final List properties;
+
+ private final int severity;
+
+ @JsonCreator
+ public Event(@JsonProperty("name") String name, @JsonProperty("properties") List properties,
+ @JsonProperty("severity") int severity) {
+ this.properties = properties;
+ this.severity = severity;
+ }
+
+ private static class Property {
+
+ private final String name;
+
+ private final String value;
+
+ @JsonCreator
+ private Property(@JsonProperty("name") String name, @JsonProperty("value") String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ }
+
+ }
+
+ }
+
}
diff --git a/ci/images/releasescripts/src/main/resources/application.properties b/ci/images/releasescripts/src/main/resources/application.properties
index 44dc307221..56dfa61a19 100644
--- a/ci/images/releasescripts/src/main/resources/application.properties
+++ b/ci/images/releasescripts/src/main/resources/application.properties
@@ -1,4 +1,4 @@
spring.main.banner-mode=off
-distribute.optional-deployments[0]=.*\\.zip
-distribute.optional-deployments[1]=spring-boot-project-\\d+\\.\\d+\\.\\d+(?:\\.RELEASE)?\\.pom
+sonatype.exclude[0]=build-info\\.json
+sonatype.exclude[1]=org/springframework/boot/spring-boot-docs/.*
logging.level.io.spring.concourse=DEBUG
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java
index 7cf1e7f067..81b0d53ef6 100644
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java
+++ b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java
@@ -16,20 +16,13 @@
package io.spring.concourse.releasescripts.artifactory;
-import java.time.Duration;
-import java.util.Collections;
-import java.util.Set;
-
import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.bintray.BintrayService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
-import org.mockito.InOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@@ -40,13 +33,6 @@ import org.springframework.util.Base64Utils;
import org.springframework.web.client.HttpClientErrorException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
@@ -63,14 +49,9 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
@EnableConfigurationProperties(ArtifactoryProperties.class)
class ArtifactoryServiceTests {
- private static final Duration TIMEOUT = Duration.ofMinutes(60);
-
@Autowired
private ArtifactoryService service;
- @MockBean
- private BintrayService bintrayService;
-
@Autowired
private ArtifactoryProperties properties;
@@ -127,68 +108,6 @@ class ArtifactoryServiceTests {
this.server.verify();
}
- @Test
- @SuppressWarnings("unchecked")
- void distributeWhenSuccessful() throws Exception {
- ReleaseInfo releaseInfo = getReleaseInfo();
- given(this.bintrayService.isDistributionStarted(eq(releaseInfo))).willReturn(false);
- given(this.bintrayService.isDistributionComplete(eq(releaseInfo), (Set) any(), any())).willReturn(true);
- this.server.expect(requestTo("https://repo.spring.io/api/build/distribute/example-build/example-build-1"))
- .andExpect(method(HttpMethod.POST))
- .andExpect(content().json(
- "{\"sourceRepos\": [\"libs-release-local\"], \"targetRepo\" : \"spring-distributions\", \"async\":\"true\"}"))
- .andExpect(header("Authorization", "Basic " + Base64Utils.encodeToString(String
- .format("%s:%s", this.properties.getUsername(), this.properties.getPassword()).getBytes())))
- .andExpect(header("Content-Type", MediaType.APPLICATION_JSON.toString())).andRespond(withSuccess());
- Set artifactDigests = Collections.singleton("602e20176706d3cc7535f01ffdbe91b270ae5014");
- this.service.distribute("libs-release-local", releaseInfo, artifactDigests);
- this.server.verify();
- InOrder ordered = inOrder(this.bintrayService);
- ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, TIMEOUT);
- }
-
- @Test
- void distributeWhenFailure() throws Exception {
- ReleaseInfo releaseInfo = getReleaseInfo();
- this.server.expect(requestTo("https://repo.spring.io/api/build/distribute/example-build/example-build-1"))
- .andExpect(method(HttpMethod.POST))
- .andExpect(content().json(
- "{\"sourceRepos\": [\"libs-release-local\"], \"targetRepo\" : \"spring-distributions\", \"async\":\"true\"}"))
- .andExpect(header("Authorization", "Basic " + Base64Utils.encodeToString(String
- .format("%s:%s", this.properties.getUsername(), this.properties.getPassword()).getBytes())))
- .andExpect(header("Content-Type", MediaType.APPLICATION_JSON.toString()))
- .andRespond(withStatus(HttpStatus.FORBIDDEN));
- Set artifactDigests = Collections.singleton("602e20176706d3cc7535f01ffdbe91b270ae5014");
- assertThatExceptionOfType(HttpClientErrorException.class)
- .isThrownBy(() -> this.service.distribute("libs-release-local", releaseInfo, artifactDigests));
- this.server.verify();
- verify(this.bintrayService, times(1)).isDistributionStarted(releaseInfo);
- verifyNoMoreInteractions(this.bintrayService);
- }
-
- @Test
- @SuppressWarnings("unchecked")
- void distributeWhenGettingPackagesTimesOut() throws Exception {
- ReleaseInfo releaseInfo = getReleaseInfo();
- given(this.bintrayService.isDistributionComplete(eq(releaseInfo), (Set) any(), any()))
- .willReturn(false);
- given(this.bintrayService.isDistributionComplete(eq(releaseInfo), (Set) any(), any()))
- .willReturn(false);
- this.server.expect(requestTo("https://repo.spring.io/api/build/distribute/example-build/example-build-1"))
- .andExpect(method(HttpMethod.POST))
- .andExpect(content().json(
- "{\"sourceRepos\": [\"libs-release-local\"], \"targetRepo\" : \"spring-distributions\", \"async\":\"true\"}"))
- .andExpect(header("Authorization", "Basic " + Base64Utils.encodeToString(String
- .format("%s:%s", this.properties.getUsername(), this.properties.getPassword()).getBytes())))
- .andExpect(header("Content-Type", MediaType.APPLICATION_JSON.toString())).andRespond(withSuccess());
- Set artifactDigests = Collections.singleton("602e20176706d3cc7535f01ffdbe91b270ae5014");
- assertThatExceptionOfType(DistributionTimeoutException.class)
- .isThrownBy(() -> this.service.distribute("libs-release-local", releaseInfo, artifactDigests));
- this.server.verify();
- InOrder ordered = inOrder(this.bintrayService);
- ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, TIMEOUT);
- }
-
private ReleaseInfo getReleaseInfo() {
ReleaseInfo releaseInfo = new ReleaseInfo();
releaseInfo.setBuildName("example-build");
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/bintray/BintrayServiceTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/bintray/BintrayServiceTests.java
deleted file mode 100644
index 68de238c16..0000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/bintray/BintrayServiceTests.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.bintray;
-
-import java.time.Duration;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.sonatype.SonatypeProperties;
-import io.spring.concourse.releasescripts.sonatype.SonatypeService;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.client.ExpectedCount;
-import org.springframework.test.web.client.MockRestServiceServer;
-import org.springframework.test.web.client.response.DefaultResponseCreator;
-import org.springframework.util.Base64Utils;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.BDDMockito.given;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
-import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
-
-/**
- * Tests for {@link BintrayService}.
- *
- * @author Madhura Bhave
- */
-@RestClientTest(BintrayService.class)
-@EnableConfigurationProperties({ BintrayProperties.class, SonatypeProperties.class })
-class BintrayServiceTests {
-
- @Autowired
- private BintrayService service;
-
- @Autowired
- private BintrayProperties properties;
-
- @Autowired
- private SonatypeProperties sonatypeProperties;
-
- @MockBean
- private SonatypeService sonatypeService;
-
- @Autowired
- private MockRestServiceServer server;
-
- @AfterEach
- void tearDown() {
- this.server.reset();
- }
-
- @Test
- void isDistributionComplete() throws Exception {
- setupGetPackageFiles(1, "no-package-files.json");
- setupGetPackageFiles(1, "some-package-files.json");
- setupGetPackageFiles(1, "all-package-files.json");
- Set digests = new LinkedHashSet<>();
- digests.add("602e20176706d3cc7535f01ffdbe91b270ae5012");
- digests.add("602e20176706d3cc7535f01ffdbe91b270ae5013");
- digests.add("602e20176706d3cc7535f01ffdbe91b270ae5014");
- assertThat(this.service.isDistributionComplete(getReleaseInfo(), digests, Duration.ofMinutes(1), Duration.ZERO))
- .isTrue();
- this.server.verify();
- }
-
- private void setupGetPackageFiles(int includeUnpublished, String path) {
- this.server
- .expect(requestTo(String.format(
- "https://api.bintray.com/packages/%s/%s/%s/versions/%s/files?include_unpublished=%s",
- this.properties.getSubject(), this.properties.getRepo(), "example", "1.1.0.RELEASE",
- includeUnpublished)))
- .andExpect(method(HttpMethod.GET))
- .andExpect(header("Authorization", "Basic " + Base64Utils.encodeToString(
- String.format("%s:%s", this.properties.getUsername(), this.properties.getApiKey()).getBytes())))
- .andRespond(withJsonFrom(path));
- }
-
- @Test
- void publishGradlePluginWhenSuccessful() {
- this.server
- .expect(requestTo(String.format("https://api.bintray.com/packages/%s/%s/%s/versions/%s/attributes",
- this.properties.getSubject(), this.properties.getRepo(), "example", "1.1.0.RELEASE")))
- .andExpect(method(HttpMethod.POST))
- .andExpect(content().json(
- "[ { \"name\": \"gradle-plugin\", \"values\": [\"org.springframework.boot:org.springframework.boot:spring-boot-gradle-plugin\"] } ]"))
- .andExpect(header("Authorization", "Basic " + Base64Utils.encodeToString(
- String.format("%s:%s", this.properties.getUsername(), this.properties.getApiKey()).getBytes())))
- .andExpect(header("Content-Type", MediaType.APPLICATION_JSON.toString())).andRespond(withSuccess());
- this.service.publishGradlePlugin(getReleaseInfo());
- this.server.verify();
- }
-
- @Test
- void syncToMavenCentralWhenSuccessful() {
- ReleaseInfo releaseInfo = getReleaseInfo();
- given(this.sonatypeService.artifactsPublished(releaseInfo)).willReturn(false);
- this.server
- .expect(requestTo(String.format("https://api.bintray.com/maven_central_sync/%s/%s/%s/versions/%s",
- this.properties.getSubject(), this.properties.getRepo(), "example", "1.1.0.RELEASE")))
- .andExpect(method(HttpMethod.POST))
- .andExpect(content().json(String.format("{\"username\": \"%s\", \"password\": \"%s\"}",
- this.sonatypeProperties.getUserToken(), this.sonatypeProperties.getPasswordToken())))
- .andExpect(header("Authorization", "Basic " + Base64Utils.encodeToString(
- String.format("%s:%s", this.properties.getUsername(), this.properties.getApiKey()).getBytes())))
- .andExpect(header("Content-Type", MediaType.APPLICATION_JSON.toString())).andRespond(withSuccess());
- this.service.syncToMavenCentral(releaseInfo);
- this.server.verify();
- }
-
- @Test
- void syncToMavenCentralWhenArtifactsAlreadyPublished() {
- ReleaseInfo releaseInfo = getReleaseInfo();
- given(this.sonatypeService.artifactsPublished(releaseInfo)).willReturn(true);
- this.server.expect(ExpectedCount.never(),
- requestTo(String.format("https://api.bintray.com/maven_central_sync/%s/%s/%s/versions/%s",
- this.properties.getSubject(), this.properties.getRepo(), "example", "1.1.0.RELEASE")));
- this.service.syncToMavenCentral(releaseInfo);
- this.server.verify();
- }
-
- private ReleaseInfo getReleaseInfo() {
- ReleaseInfo releaseInfo = new ReleaseInfo();
- releaseInfo.setBuildName("example-build");
- releaseInfo.setBuildNumber("example-build-1");
- releaseInfo.setGroupId("example");
- releaseInfo.setVersion("1.1.0.RELEASE");
- return releaseInfo;
- }
-
- private DefaultResponseCreator withJsonFrom(String path) {
- return withSuccess(getClassPathResource(path), MediaType.APPLICATION_JSON);
- }
-
- private ClassPathResource getClassPathResource(String path) {
- return new ClassPathResource(path, getClass());
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/CommandProcessorTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/CommandProcessorTests.java
deleted file mode 100644
index c21953c559..0000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/CommandProcessorTests.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import org.junit.jupiter.api.Test;
-
-import org.springframework.boot.DefaultApplicationArguments;
-
-import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-/**
- * Tests for {@link CommandProcessor}.
- *
- * @author Madhura Bhave
- */
-class CommandProcessorTests {
-
- private static final String[] NO_ARGS = {};
-
- @Test
- void runWhenNoArgumentThrowsException() {
- CommandProcessor processor = new CommandProcessor(Collections.singletonList(mock(Command.class)));
- assertThatIllegalStateException().isThrownBy(() -> processor.run(new DefaultApplicationArguments(NO_ARGS)))
- .withMessage("No command argument specified");
- }
-
- @Test
- void runWhenUnknownCommandThrowsException() {
- Command fooCommand = mock(Command.class);
- given(fooCommand.getName()).willReturn("foo");
- CommandProcessor processor = new CommandProcessor(Collections.singletonList(fooCommand));
- DefaultApplicationArguments args = new DefaultApplicationArguments(new String[] { "bar", "go" });
- assertThatIllegalStateException().isThrownBy(() -> processor.run(args)).withMessage("Unknown command 'bar'");
- }
-
- @Test
- void runDelegatesToCommand() throws Exception {
- Command fooCommand = mock(Command.class);
- given(fooCommand.getName()).willReturn("foo");
- Command barCommand = mock(Command.class);
- given(barCommand.getName()).willReturn("bar");
- CommandProcessor processor = new CommandProcessor(Arrays.asList(fooCommand, barCommand));
- DefaultApplicationArguments args = new DefaultApplicationArguments(new String[] { "bar", "go" });
- processor.run(args);
- verify(fooCommand, never()).run(any());
- verify(barCommand).run(args);
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/DistributeCommandTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/DistributeCommandTests.java
deleted file mode 100644
index 080c10013a..0000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/DistributeCommandTests.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import java.util.Arrays;
-import java.util.Set;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.ReleaseType;
-import io.spring.concourse.releasescripts.artifactory.ArtifactoryService;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import org.springframework.boot.DefaultApplicationArguments;
-import org.springframework.core.io.ClassPathResource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-
-/**
- * Tests for {@link DistributeCommand}.
- *
- * @author Madhura Bhave
- * @author Phillip Webb
- */
-class DistributeCommandTests {
-
- @Mock
- private ArtifactoryService service;
-
- private DistributeCommand command;
-
- private ObjectMapper objectMapper;
-
- @BeforeEach
- void setup() {
- MockitoAnnotations.initMocks(this);
- DistributeProperties distributeProperties = new DistributeProperties();
- distributeProperties.setOptionalDeployments(Arrays.asList(".*\\.zip", "demo-\\d\\.\\d\\.\\d\\.doc"));
- this.objectMapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- this.command = new DistributeCommand(this.service, this.objectMapper, distributeProperties);
- }
-
- @Test
- void distributeWhenReleaseTypeNotSpecifiedShouldThrowException() {
- Assertions.assertThatIllegalStateException()
- .isThrownBy(() -> this.command.run(new DefaultApplicationArguments("distribute")));
- }
-
- @Test
- void distributeWhenReleaseTypeMilestoneShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("distribute", "M", getBuildInfoLocation()));
- verifyNoInteractions(this.service);
- }
-
- @Test
- void distributeWhenReleaseTypeRCShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("distribute", "RC", getBuildInfoLocation()));
- verifyNoInteractions(this.service);
- }
-
- @Test
- @SuppressWarnings("unchecked")
- void distributeWhenReleaseTypeReleaseShouldCallService() throws Exception {
- ArgumentCaptor releaseInfoCaptor = ArgumentCaptor.forClass(ReleaseInfo.class);
- ArgumentCaptor> artifactDigestCaptor = ArgumentCaptor.forClass(Set.class);
- this.command.run(new DefaultApplicationArguments("distribute", "RELEASE", getBuildInfoLocation()));
- verify(this.service).distribute(eq(ReleaseType.RELEASE.getRepo()), releaseInfoCaptor.capture(),
- artifactDigestCaptor.capture());
- ReleaseInfo releaseInfo = releaseInfoCaptor.getValue();
- assertThat(releaseInfo.getBuildName()).isEqualTo("example");
- assertThat(releaseInfo.getBuildNumber()).isEqualTo("example-build-1");
- assertThat(releaseInfo.getGroupId()).isEqualTo("org.example.demo");
- assertThat(releaseInfo.getVersion()).isEqualTo("2.2.0");
- Set artifactDigests = artifactDigestCaptor.getValue();
- assertThat(artifactDigests).containsExactly("aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy");
- }
-
- @Test
- @SuppressWarnings("unchecked")
- void distributeWhenReleaseTypeReleaseAndFilteredShouldCallService() throws Exception {
- ArgumentCaptor releaseInfoCaptor = ArgumentCaptor.forClass(ReleaseInfo.class);
- ArgumentCaptor> artifactDigestCaptor = ArgumentCaptor.forClass(Set.class);
- this.command.run(new DefaultApplicationArguments("distribute", "RELEASE",
- getBuildInfoLocation("filtered-build-info-response.json")));
- verify(this.service).distribute(eq(ReleaseType.RELEASE.getRepo()), releaseInfoCaptor.capture(),
- artifactDigestCaptor.capture());
- ReleaseInfo releaseInfo = releaseInfoCaptor.getValue();
- assertThat(releaseInfo.getBuildName()).isEqualTo("example");
- assertThat(releaseInfo.getBuildNumber()).isEqualTo("example-build-1");
- assertThat(releaseInfo.getGroupId()).isEqualTo("org.example.demo");
- assertThat(releaseInfo.getVersion()).isEqualTo("2.2.0");
- Set artifactDigests = artifactDigestCaptor.getValue();
- assertThat(artifactDigests).containsExactly("aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy");
- }
-
- private String getBuildInfoLocation() throws Exception {
- return getBuildInfoLocation("build-info-response.json");
- }
-
- private String getBuildInfoLocation(String file) throws Exception {
- return new ClassPathResource(file, ArtifactoryService.class).getFile().getAbsolutePath();
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PromoteCommandTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PromoteCommandTests.java
deleted file mode 100644
index f1c776094a..0000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PromoteCommandTests.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.ReleaseType;
-import io.spring.concourse.releasescripts.artifactory.ArtifactoryService;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import org.springframework.boot.DefaultApplicationArguments;
-import org.springframework.core.io.ClassPathResource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-
-/**
- * @author Madhura Bhave
- */
-class PromoteCommandTests {
-
- @Mock
- private ArtifactoryService service;
-
- private PromoteCommand command;
-
- private ObjectMapper objectMapper;
-
- @BeforeEach
- void setup() {
- MockitoAnnotations.initMocks(this);
- this.objectMapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- this.command = new PromoteCommand(this.service, this.objectMapper);
- }
-
- @Test
- void runWhenReleaseTypeNotSpecifiedShouldThrowException() {
- assertThatIllegalStateException()
- .isThrownBy(() -> this.command.run(new DefaultApplicationArguments("promote")));
- }
-
- @Test
- void runWhenReleaseTypeMilestoneShouldCallService() throws Exception {
- this.command.run(new DefaultApplicationArguments("promote", "M", getBuildInfoLocation()));
- verify(this.service).promote(eq(ReleaseType.MILESTONE.getRepo()), any(ReleaseInfo.class));
- }
-
- @Test
- void runWhenReleaseTypeRCShouldCallService() throws Exception {
- this.command.run(new DefaultApplicationArguments("promote", "RC", getBuildInfoLocation()));
- verify(this.service).promote(eq(ReleaseType.RELEASE_CANDIDATE.getRepo()), any(ReleaseInfo.class));
- }
-
- @Test
- void runWhenReleaseTypeReleaseShouldCallService() throws Exception {
- this.command.run(new DefaultApplicationArguments("promote", "RELEASE", getBuildInfoLocation()));
- verify(this.service).promote(eq(ReleaseType.RELEASE.getRepo()), any(ReleaseInfo.class));
- }
-
- @Test
- void runWhenBuildInfoNotSpecifiedShouldThrowException() {
- assertThatIllegalStateException()
- .isThrownBy(() -> this.command.run(new DefaultApplicationArguments("promote", "M")));
- }
-
- @Test
- void runShouldParseBuildInfoProperly() throws Exception {
- ArgumentCaptor captor = ArgumentCaptor.forClass(ReleaseInfo.class);
- this.command.run(new DefaultApplicationArguments("promote", "RELEASE", getBuildInfoLocation()));
- verify(this.service).promote(eq(ReleaseType.RELEASE.getRepo()), captor.capture());
- ReleaseInfo releaseInfo = captor.getValue();
- assertThat(releaseInfo.getBuildName()).isEqualTo("example");
- assertThat(releaseInfo.getBuildNumber()).isEqualTo("example-build-1");
- assertThat(releaseInfo.getGroupId()).isEqualTo("org.example.demo");
- assertThat(releaseInfo.getVersion()).isEqualTo("2.2.0");
- }
-
- private String getBuildInfoLocation() throws Exception {
- return new ClassPathResource("build-info-response.json", ArtifactoryService.class).getFile().getAbsolutePath();
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PublishGradlePluginTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PublishGradlePluginTests.java
deleted file mode 100644
index e7ceb1c8b4..0000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PublishGradlePluginTests.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.artifactory.ArtifactoryService;
-import io.spring.concourse.releasescripts.bintray.BintrayService;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import org.springframework.boot.DefaultApplicationArguments;
-import org.springframework.core.io.ClassPathResource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-
-/**
- * Tests for {@link PublishGradlePlugin}.
- *
- * @author Madhura Bhave
- */
-class PublishGradlePluginTests {
-
- @Mock
- private BintrayService service;
-
- private PublishGradlePlugin command;
-
- private ObjectMapper objectMapper;
-
- @BeforeEach
- void setup() {
- MockitoAnnotations.initMocks(this);
- this.objectMapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- this.command = new PublishGradlePlugin(this.service, objectMapper);
- }
-
- @Test
- void runWhenReleaseTypeNotSpecifiedShouldThrowException() throws Exception {
- Assertions.assertThatIllegalStateException()
- .isThrownBy(() -> this.command.run(new DefaultApplicationArguments("publishGradlePlugin")));
- }
-
- @Test
- void runWhenReleaseTypeMilestoneShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("publishGradlePlugin", "M", getBuildInfoLocation()));
- verifyNoInteractions(this.service);
- }
-
- @Test
- void runWhenReleaseTypeRCShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("publishGradlePlugin", "RC", getBuildInfoLocation()));
- verifyNoInteractions(this.service);
- }
-
- @Test
- void runWhenReleaseTypeReleaseShouldCallService() throws Exception {
- ArgumentCaptor captor = ArgumentCaptor.forClass(ReleaseInfo.class);
- this.command.run(new DefaultApplicationArguments("promote", "RELEASE", getBuildInfoLocation()));
- verify(this.service).publishGradlePlugin(captor.capture());
- ReleaseInfo releaseInfo = captor.getValue();
- assertThat(releaseInfo.getBuildName()).isEqualTo("example");
- assertThat(releaseInfo.getBuildNumber()).isEqualTo("example-build-1");
- assertThat(releaseInfo.getGroupId()).isEqualTo("org.example.demo");
- assertThat(releaseInfo.getVersion()).isEqualTo("2.2.0");
- }
-
- private String getBuildInfoLocation() throws Exception {
- return new ClassPathResource("build-info-response.json", ArtifactoryService.class).getFile().getAbsolutePath();
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PublishToSdkmanCommandTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PublishToSdkmanCommandTests.java
deleted file mode 100644
index e612650bb1..0000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/PublishToSdkmanCommandTests.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import io.spring.concourse.releasescripts.sdkman.SdkmanService;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import org.springframework.boot.DefaultApplicationArguments;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-
-/**
- * Tests for {@link PublishToSdkmanCommand}.
- *
- * @author Madhura Bhave
- */
-class PublishToSdkmanCommandTests {
-
- @Mock
- private SdkmanService service;
-
- private PublishToSdkmanCommand command;
-
- @BeforeEach
- void setup() {
- MockitoAnnotations.initMocks(this);
- this.command = new PublishToSdkmanCommand(this.service);
- }
-
- @Test
- void runWhenReleaseTypeNotSpecifiedShouldThrowException() throws Exception {
- Assertions.assertThatIllegalStateException()
- .isThrownBy(() -> this.command.run(new DefaultApplicationArguments("publishToSdkman")));
- }
-
- @Test
- void runWhenVersionNotSpecifiedShouldThrowException() throws Exception {
- Assertions.assertThatIllegalStateException()
- .isThrownBy(() -> this.command.run(new DefaultApplicationArguments("publishToSdkman", "RELEASE")));
- }
-
- @Test
- void runWhenReleaseTypeMilestoneShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("publishToSdkman", "M", "1.2.3"));
- verifyNoInteractions(this.service);
- }
-
- @Test
- void runWhenReleaseTypeRCShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("publishToSdkman", "RC", "1.2.3"));
- verifyNoInteractions(this.service);
- }
-
- @Test
- void runWhenLatestGANotSpecifiedShouldCallServiceWithMakeDefaultFalse() throws Exception {
- DefaultApplicationArguments args = new DefaultApplicationArguments("promote", "RELEASE", "1.2.3");
- testRun(args, false);
- }
-
- @Test
- void runWhenReleaseTypeReleaseShouldCallService() throws Exception {
- DefaultApplicationArguments args = new DefaultApplicationArguments("promote", "RELEASE", "1.2.3", "true");
- testRun(args, true);
- }
-
- private void testRun(DefaultApplicationArguments args, boolean makeDefault) throws Exception {
- ArgumentCaptor versionCaptor = ArgumentCaptor.forClass(String.class);
- ArgumentCaptor makeDefaultCaptor = ArgumentCaptor.forClass(Boolean.class);
- this.command.run(args);
- verify(this.service).publish(versionCaptor.capture(), makeDefaultCaptor.capture());
- String version = versionCaptor.getValue();
- Boolean makeDefaultValue = makeDefaultCaptor.getValue();
- assertThat(version).isEqualTo("1.2.3");
- assertThat(makeDefaultValue).isEqualTo(makeDefault);
- }
-
-}
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/SyncToCentralCommandTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/SyncToCentralCommandTests.java
deleted file mode 100644
index 2f79452c3a..0000000000
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/SyncToCentralCommandTests.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.concourse.releasescripts.command;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.spring.concourse.releasescripts.ReleaseInfo;
-import io.spring.concourse.releasescripts.artifactory.ArtifactoryService;
-import io.spring.concourse.releasescripts.bintray.BintrayService;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import org.springframework.boot.DefaultApplicationArguments;
-import org.springframework.core.io.ClassPathResource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-
-/**
- * Tests for {@link SyncToCentralCommand}.
- *
- * @author Madhura Bhave
- */
-class SyncToCentralCommandTests {
-
- @Mock
- private BintrayService service;
-
- private SyncToCentralCommand command;
-
- private ObjectMapper objectMapper;
-
- @BeforeEach
- void setup() {
- MockitoAnnotations.initMocks(this);
- this.objectMapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- this.command = new SyncToCentralCommand(this.service, objectMapper);
- }
-
- @Test
- void runWhenReleaseTypeNotSpecifiedShouldThrowException() throws Exception {
- Assertions.assertThatIllegalStateException()
- .isThrownBy(() -> this.command.run(new DefaultApplicationArguments("syncToCentral")));
- }
-
- @Test
- void runWhenReleaseTypeMilestoneShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("syncToCentral", "M", getBuildInfoLocation()));
- verifyNoInteractions(this.service);
- }
-
- @Test
- void runWhenReleaseTypeRCShouldDoNothing() throws Exception {
- this.command.run(new DefaultApplicationArguments("syncToCentral", "RC", getBuildInfoLocation()));
- verifyNoInteractions(this.service);
- }
-
- @Test
- void runWhenReleaseTypeReleaseShouldCallService() throws Exception {
- ArgumentCaptor captor = ArgumentCaptor.forClass(ReleaseInfo.class);
- this.command.run(new DefaultApplicationArguments("syncToCentral", "RELEASE", getBuildInfoLocation()));
- verify(this.service).syncToMavenCentral(captor.capture());
- ReleaseInfo releaseInfo = captor.getValue();
- assertThat(releaseInfo.getBuildName()).isEqualTo("example");
- assertThat(releaseInfo.getBuildNumber()).isEqualTo("example-build-1");
- assertThat(releaseInfo.getGroupId()).isEqualTo("org.example.demo");
- assertThat(releaseInfo.getVersion()).isEqualTo("2.2.0");
- }
-
- private String getBuildInfoLocation() throws Exception {
- return new ClassPathResource("build-info-response.json", ArtifactoryService.class).getFile().getAbsolutePath();
- }
-
-}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sonatype/SonatypeServiceTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sonatype/SonatypeServiceTests.java
index d8e09f70e1..c8bd5e8e7d 100644
--- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sonatype/SonatypeServiceTests.java
+++ b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sonatype/SonatypeServiceTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,17 @@
package io.spring.concourse.releasescripts.sonatype;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
import io.spring.concourse.releasescripts.ReleaseInfo;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@@ -23,11 +34,20 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
+import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.ClientHttpRequest;
+import org.springframework.test.web.client.ExpectedCount;
import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.test.web.client.RequestMatcher;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.jsonPath;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
@@ -38,7 +58,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
*
* @author Madhura Bhave
*/
-@RestClientTest(SonatypeService.class)
+@RestClientTest(components = SonatypeService.class, properties = "sonatype.url=https://nexus.example.org")
@EnableConfigurationProperties(SonatypeProperties.class)
class SonatypeServiceTests {
@@ -56,9 +76,9 @@ class SonatypeServiceTests {
@Test
void artifactsPublishedWhenPublishedShouldReturnTrue() {
this.server.expect(requestTo(String.format(
- "https://oss.sonatype.org/service/local/repositories/releases/content/org/springframework/boot/spring-boot/%s/spring-boot-%s.jar.sha1",
+ "/service/local/repositories/releases/content/org/springframework/boot/spring-boot/%s/spring-boot-%s.jar.sha1",
"1.1.0.RELEASE", "1.1.0.RELEASE"))).andExpect(method(HttpMethod.GET))
- .andRespond(withSuccess().body("ce8d8b6838ecceb68962b975b18682f4237ccf71".getBytes()));
+ .andRespond(withSuccess().body("ce8d8b6838ecceb68962b9150b18682f4237ccf71".getBytes()));
boolean published = this.service.artifactsPublished(getReleaseInfo());
assertThat(published).isTrue();
this.server.verify();
@@ -67,7 +87,7 @@ class SonatypeServiceTests {
@Test
void artifactsPublishedWhenNotPublishedShouldReturnFalse() {
this.server.expect(requestTo(String.format(
- "https://oss.sonatype.org/service/local/repositories/releases/content/org/springframework/boot/spring-boot/%s/spring-boot-%s.jar.sha1",
+ "/service/local/repositories/releases/content/org/springframework/boot/spring-boot/%s/spring-boot-%s.jar.sha1",
"1.1.0.RELEASE", "1.1.0.RELEASE"))).andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.NOT_FOUND));
boolean published = this.service.artifactsPublished(getReleaseInfo());
@@ -75,6 +95,102 @@ class SonatypeServiceTests {
this.server.verify();
}
+ @Test
+ void publishWithSuccessfulClose() throws IOException {
+ this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/start"))
+ .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andExpect(jsonPath("$.data.description").value("example-build-1"))
+ .andRespond(withStatus(HttpStatus.CREATED).contentType(MediaType.APPLICATION_JSON).body(
+ "{\"data\":{\"stagedRepositoryId\":\"example-6789\", \"description\":\"example-build\"}}"));
+ Path artifactsRoot = new File("src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo")
+ .toPath();
+ try (Stream artifacts = Files.walk(artifactsRoot)) {
+ Set uploads = artifacts.filter(Files::isRegularFile)
+ .map((artifact) -> artifactsRoot.relativize(artifact))
+ .filter((artifact) -> !artifact.startsWith("build-info.json"))
+ .map((artifact) -> requestTo(
+ "/service/local/staging/deployByRepositoryId/example-6789/" + artifact.toString()))
+ .collect(Collectors.toCollection(HashSet::new));
+ AnyOfRequestMatcher uploadRequestsMatcher = anyOf(uploads);
+ assertThat(uploadRequestsMatcher.candidates).hasSize(150);
+ this.server.expect(ExpectedCount.times(150), uploadRequestsMatcher).andExpect(method(HttpMethod.PUT))
+ .andRespond(withSuccess());
+ this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/finish"))
+ .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andRespond(withStatus(HttpStatus.CREATED));
+ this.server.expect(ExpectedCount.times(2), requestTo("/service/local/staging/repository/example-6789"))
+ .andExpect(method(HttpMethod.GET))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
+ .body("{\"type\":\"open\", \"transitioning\":true}"));
+ this.server.expect(requestTo("/service/local/staging/repository/example-6789"))
+ .andExpect(method(HttpMethod.GET))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
+ .body("{\"type\":\"closed\", \"transitioning\":false}"));
+ this.server.expect(requestTo("/service/local/staging/bulk/promote")).andExpect(method(HttpMethod.POST))
+ .andExpect(header("Content-Type", "application/json"))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andExpect(jsonPath("$.data.description").value("Releasing example-build-1"))
+ .andExpect(jsonPath("$.data.autoDropAfterRelease").value(true))
+ .andExpect(jsonPath("$.data.stagedRepositoryIds").value(equalTo(Arrays.asList("example-6789"))))
+ .andRespond(withSuccess());
+ this.service.publish(getReleaseInfo(), artifactsRoot);
+ this.server.verify();
+ assertThat(uploadRequestsMatcher.candidates).hasSize(0);
+ }
+ }
+
+ @Test
+ void publishWithCloseFailureDueToRuleViolations() throws IOException {
+ this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/start"))
+ .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andExpect(jsonPath("$.data.description").value("example-build-1"))
+ .andRespond(withStatus(HttpStatus.CREATED).contentType(MediaType.APPLICATION_JSON).body(
+ "{\"data\":{\"stagedRepositoryId\":\"example-6789\", \"description\":\"example-build\"}}"));
+ Path artifactsRoot = new File("src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo")
+ .toPath();
+ try (Stream artifacts = Files.walk(artifactsRoot)) {
+ Set uploads = artifacts.filter(Files::isRegularFile)
+ .map((artifact) -> artifactsRoot.relativize(artifact))
+ .filter((artifact) -> !"build-info.json".equals(artifact.toString()))
+ .map((artifact) -> requestTo(
+ "/service/local/staging/deployByRepositoryId/example-6789/" + artifact.toString()))
+ .collect(Collectors.toCollection(HashSet::new));
+ AnyOfRequestMatcher uploadRequestsMatcher = anyOf(uploads);
+ assertThat(uploadRequestsMatcher.candidates).hasSize(150);
+ this.server.expect(ExpectedCount.times(150), uploadRequestsMatcher).andExpect(method(HttpMethod.PUT))
+ .andRespond(withSuccess());
+ this.server.expect(requestTo("/service/local/staging/profiles/1a2b3c4d/finish"))
+ .andExpect(method(HttpMethod.POST)).andExpect(header("Content-Type", "application/json"))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andRespond(withStatus(HttpStatus.CREATED));
+ this.server.expect(ExpectedCount.times(2), requestTo("/service/local/staging/repository/example-6789"))
+ .andExpect(method(HttpMethod.GET))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
+ .body("{\"type\":\"open\", \"transitioning\":true}"));
+ this.server.expect(requestTo("/service/local/staging/repository/example-6789"))
+ .andExpect(method(HttpMethod.GET))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON)
+ .body("{\"type\":\"open\", \"transitioning\":false}"));
+ this.server.expect(requestTo("/service/local/staging/repository/example-6789/activity"))
+ .andExpect(method(HttpMethod.GET))
+ .andExpect(header("Accept", "application/json, application/*+json"))
+ .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON).body(new FileSystemResource(
+ new File("src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json"))));
+ assertThatExceptionOfType(RuntimeException.class)
+ .isThrownBy(() -> this.service.publish(getReleaseInfo(), artifactsRoot))
+ .withMessage("Close failed");
+ this.server.verify();
+ assertThat(uploadRequestsMatcher.candidates).hasSize(0);
+ }
+ }
+
private ReleaseInfo getReleaseInfo() {
ReleaseInfo releaseInfo = new ReleaseInfo();
releaseInfo.setBuildName("example-build");
@@ -84,4 +200,39 @@ class SonatypeServiceTests {
return releaseInfo;
}
-}
\ No newline at end of file
+ private AnyOfRequestMatcher anyOf(Set candidates) {
+ return new AnyOfRequestMatcher(candidates);
+ }
+
+ private static class AnyOfRequestMatcher implements RequestMatcher {
+
+ private final Object monitor = new Object();
+
+ private final Set candidates;
+
+ private AnyOfRequestMatcher(Set candidates) {
+ this.candidates = candidates;
+ }
+
+ @Override
+ public void match(ClientHttpRequest request) throws IOException, AssertionError {
+ synchronized (this.monitor) {
+ Iterator iterator = this.candidates.iterator();
+ while (iterator.hasNext()) {
+ try {
+ iterator.next().match(request);
+ iterator.remove();
+ return;
+ }
+ catch (AssertionError ex) {
+ // Continue
+ }
+ }
+ throw new AssertionError(
+ "No matching request matcher was found for request to '" + request.getURI() + "'");
+ }
+ }
+
+ }
+
+}
diff --git a/ci/images/releasescripts/src/test/resources/application.yml b/ci/images/releasescripts/src/test/resources/application.yml
index d045250905..9c2cbc9d5b 100644
--- a/ci/images/releasescripts/src/test/resources/application.yml
+++ b/ci/images/releasescripts/src/test/resources/application.yml
@@ -9,6 +9,8 @@ bintray:
sonatype:
user-token: sonatype-user
password-token: sonatype-password
+ polling-interval: 1s
+ staging-profile-id: 1a2b3c4d
sdkman:
consumer-key: sdkman-consumer-key
consumer-token: sdkman-consumer-token
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/all-package-files.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/all-package-files.json
deleted file mode 100644
index c5d5d15eab..0000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/all-package-files.json
+++ /dev/null
@@ -1,35 +0,0 @@
-[
- {
- "name": "nutcracker-1.1-sources.jar",
- "path": "org/jfrog/powerutils/nutcracker/1.1/nutcracker-1.1-sources.jar",
- "package": "jfrog-power-utils",
- "version": "1.1",
- "repo": "jfrog-jars",
- "owner": "jfrog",
- "created": "ISO8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ)",
- "size": 1234,
- "sha256": "602e20176706d3cc7535f01ffdbe91b270ae5012"
- },
- {
- "name": "nutcracker-1.1.pom",
- "path": "org/jfrog/powerutils/nutcracker/1.1/nutcracker-1.1.pom",
- "package": "jfrog-power-utils",
- "version": "1.1",
- "repo": "jfrog-jars",
- "owner": "jfrog",
- "created": "ISO8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ)",
- "size": 1234,
- "sha256": "602e20176706d3cc7535f01ffdbe91b270ae5013"
- },
- {
- "name": "nutcracker-1.1.jar",
- "path": "org/jfrog/powerutils/nutcracker/1.1/nutcracker-1.1.jar",
- "package": "jfrog-power-utils",
- "version": "1.1",
- "repo": "jfrog-jars",
- "owner": "jfrog",
- "created": "ISO8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ)",
- "size": 1234,
- "sha256": "602e20176706d3cc7535f01ffdbe91b270ae5014"
- }
-]
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/no-package-files.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/no-package-files.json
deleted file mode 100644
index 0637a088a0..0000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/no-package-files.json
+++ /dev/null
@@ -1 +0,0 @@
-[]
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/some-package-files.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/some-package-files.json
deleted file mode 100644
index 23cbd5cfe8..0000000000
--- a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/bintray/some-package-files.json
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- {
- "name": "nutcracker-1.1-sources.jar",
- "path": "org/jfrog/powerutils/nutcracker/1.1/nutcracker-1.1-sources.jar",
- "package": "jfrog-power-utils",
- "version": "1.1",
- "repo": "jfrog-jars",
- "owner": "jfrog",
- "created": "ISO8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ)",
- "size": 1234,
- "sha256": "602e20176706d3cc7535f01ffdbe91b270ae5012"
- }
-]
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json
new file mode 100644
index 0000000000..92e0e14137
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/activity.json
@@ -0,0 +1,362 @@
+[
+ {
+ "events": [
+ {
+ "name": "repositoryCreated",
+ "properties": [
+ {
+ "name": "id",
+ "value": "orgspringframework-7161"
+ },
+ {
+ "name": "user",
+ "value": "user"
+ },
+ {
+ "name": "ip",
+ "value": "127.0.0.1"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:31:13.523Z"
+ }
+ ],
+ "name": "open",
+ "started": "2021-02-08T14:31:00.662Z",
+ "stopped": "2021-02-08T14:31:14.855Z"
+ },
+ {
+ "events": [
+ {
+ "name": "rulesEvaluate",
+ "properties": [
+ {
+ "name": "id",
+ "value": "5e9e8e6f8d20a3"
+ },
+ {
+ "name": "rule",
+ "value": "no-traversal-paths-in-archive-file"
+ },
+ {
+ "name": "rule",
+ "value": "profile-target-matching-staging"
+ },
+ {
+ "name": "rule",
+ "value": "sbom-report"
+ },
+ {
+ "name": "rule",
+ "value": "checksum-staging"
+ },
+ {
+ "name": "rule",
+ "value": "javadoc-staging"
+ },
+ {
+ "name": "rule",
+ "value": "pom-staging"
+ },
+ {
+ "name": "rule",
+ "value": "signature-staging"
+ },
+ {
+ "name": "rule",
+ "value": "sources-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:31:37.327Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "no-traversal-paths-in-archive-file"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:31:41.254Z"
+ },
+ {
+ "name": "rulePassed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "no-traversal-paths-in-archive-file"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:31:47.498Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "javadoc-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:31:53.438Z"
+ },
+ {
+ "name": "rulePassed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "javadoc-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:31:54.623Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "pom-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:31:58.091Z"
+ },
+ {
+ "name": "ruleFailed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "pom-staging"
+ },
+ {
+ "name": "failureMessage",
+ "value": "Invalid POM: /org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom: Project name missing, Project description missing, Project URL missing, License information missing, SCM URL missing, Developer information missing"
+ },
+ {
+ "name": "failureMessage",
+ "value": "Invalid POM: /org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom: Project name missing, Project description missing, Project URL missing, License information missing, SCM URL missing, Developer information missing"
+ },
+ {
+ "name": "failureMessage",
+ "value": "Invalid POM: /org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom: Project name missing, Project description missing, Project URL missing, License information missing, SCM URL missing, Developer information missing"
+ }
+ ],
+ "severity": 1,
+ "timestamp": "2021-02-08T14:31:59.403Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "profile-target-matching-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:05.322Z"
+ },
+ {
+ "name": "rulePassed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "profile-target-matching-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:06.492Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "checksum-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:12.415Z"
+ },
+ {
+ "name": "rulePassed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "checksum-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:13.568Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "signature-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:18.288Z"
+ },
+ {
+ "name": "ruleFailed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "signature-staging"
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc' does not exist for 'module-one-1.0.0-javadoc.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc' does not exist for 'module-one-1.0.0.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc' does not exist for 'module-one-1.0.0-sources.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc' does not exist for 'module-one-1.0.0.module'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc' does not exist for 'module-one-1.0.0.pom'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc' does not exist for 'module-two-1.0.0.module'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc' does not exist for 'module-two-1.0.0.pom'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc' does not exist for 'module-two-1.0.0-sources.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc' does not exist for 'module-two-1.0.0.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc' does not exist for 'module-two-1.0.0-javadoc.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc' does not exist for 'module-three-1.0.0.module'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc' does not exist for 'module-three-1.0.0-javadoc.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc' does not exist for 'module-three-1.0.0-sources.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc' does not exist for 'module-three-1.0.0.jar'."
+ },
+ {
+ "name": "failureMessage",
+ "value": "Missing Signature: '/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc' does not exist for 'module-three-1.0.0.pom'."
+ }
+ ],
+ "severity": 1,
+ "timestamp": "2021-02-08T14:32:19.443Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "sources-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:24.175Z"
+ },
+ {
+ "name": "rulePassed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "sources-staging"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:28.940Z"
+ },
+ {
+ "name": "ruleEvaluate",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "sbom-report"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:34.906Z"
+ },
+ {
+ "name": "rulePassed",
+ "properties": [
+ {
+ "name": "typeId",
+ "value": "sbom-report"
+ },
+ {
+ "name": "successMessage",
+ "value": "Successfully requested SBOM report"
+ }
+ ],
+ "severity": 0,
+ "timestamp": "2021-02-08T14:32:36.520Z"
+ },
+ {
+ "name": "rulesFailed",
+ "properties": [
+ {
+ "name": "id",
+ "value": "5e9e8e6f8d20a3"
+ },
+ {
+ "name": "failureCount",
+ "value": "2"
+ }
+ ],
+ "severity": 1,
+ "timestamp": "2021-02-08T14:32:42.068Z"
+ },
+ {
+ "name": "repositoryCloseFailed",
+ "properties": [
+ {
+ "name": "id",
+ "value": "orgspringframework-7161"
+ },
+ {
+ "name": "cause",
+ "value": "com.sonatype.nexus.staging.StagingRulesFailedException: One or more rules have failed"
+ }
+ ],
+ "severity": 1,
+ "timestamp": "2021-02-08T14:32:43.218Z"
+ }
+ ],
+ "name": "close",
+ "started": "2021-02-08T14:31:34.943Z",
+ "startedByIpAddress": "127.0.0.1",
+ "startedByUserId": "user",
+ "stopped": "2021-02-08T14:32:47.138Z"
+ }
+]
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/build-info.json b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/build-info.json
new file mode 100644
index 0000000000..bfe0d3be18
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/build-info.json
@@ -0,0 +1,35 @@
+{
+ "buildInfo": {
+ "version": "1.0.1",
+ "name": "example",
+ "number": "example-build-1",
+ "started": "2019-09-10T12:18:05.430+0000",
+ "durationMillis": 0,
+ "artifactoryPrincipal": "user",
+ "url": "https://my-ci.com",
+ "modules": [
+ {
+ "id": "org.example.demo:demo:2.2.0",
+ "artifacts": [
+ {
+ "type": "jar",
+ "sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaaa",
+ "sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy",
+ "md5": "aaaaaacddea1724b0b69d8yyyyyyy",
+ "name": "demo-2.2.0.jar"
+ }
+ ]
+ }
+ ],
+ "statuses": [
+ {
+ "status": "staged",
+ "repository": "libs-release-local",
+ "timestamp": "2019-09-10T12:42:24.716+0000",
+ "user": "user",
+ "timestampDate": 1568119344716
+ }
+ ]
+ },
+ "uri": "https://my-artifactory-repo.com/api/build/example/example-build-1"
+}
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc
new file mode 100644
index 0000000000..85d6a7cb1e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
+eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
+0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
+3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
+GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
+e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
+=x/MY
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5.asc
new file mode 100644
index 0000000000..1cbf6ccffa
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
+E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
+fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
+jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
+3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
+W+QvcE7wyW2jtb22pCImLyObyZ21VA==
+=VjDv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1.asc
new file mode 100644
index 0000000000..4cd212d6e1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
+U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
+EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
+jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
+bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
+ElRgneV4HZp+LB125VoNabKuNH00bw==
+=2yDl
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256.asc
new file mode 100644
index 0000000000..e29629cbec
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
+dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
+BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
+J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
+KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
+mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
+=5oO1
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-javadoc.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc
new file mode 100644
index 0000000000..85d6a7cb1e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
+eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
+0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
+3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
+GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
+e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
+=x/MY
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5.asc
new file mode 100644
index 0000000000..1cbf6ccffa
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
+E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
+fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
+jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
+3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
+W+QvcE7wyW2jtb22pCImLyObyZ21VA==
+=VjDv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1.asc
new file mode 100644
index 0000000000..4cd212d6e1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
+U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
+EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
+jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
+bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
+ElRgneV4HZp+LB125VoNabKuNH00bw==
+=2yDl
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256.asc
new file mode 100644
index 0000000000..e29629cbec
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
+dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
+BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
+J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
+KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
+mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
+=5oO1
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0-sources.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc
new file mode 100644
index 0000000000..85d6a7cb1e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
+eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
+0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
+3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
+GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
+e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
+=x/MY
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5.asc
new file mode 100644
index 0000000000..1cbf6ccffa
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
+E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
+fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
+jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
+3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
+W+QvcE7wyW2jtb22pCImLyObyZ21VA==
+=VjDv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1.asc
new file mode 100644
index 0000000000..4cd212d6e1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
+U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
+EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
+jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
+bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
+ElRgneV4HZp+LB125VoNabKuNH00bw==
+=2yDl
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256.asc
new file mode 100644
index 0000000000..e29629cbec
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
+dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
+BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
+J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
+KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
+mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
+=5oO1
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module
new file mode 100644
index 0000000000..6a92fa0a1a
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module
@@ -0,0 +1,101 @@
+{
+ "formatVersion": "1.1",
+ "component": {
+ "group": "org.springframework.example",
+ "module": "module-one",
+ "version": "1.0.0",
+ "attributes": {
+ "org.gradle.status": "release"
+ }
+ },
+ "createdBy": {
+ "gradle": {
+ "version": "6.5.1",
+ "buildId": "mvqepqsdqjcahjl7cii6b6ucoe"
+ }
+ },
+ "variants": [
+ {
+ "name": "apiElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.jvm.version": 8,
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-api"
+ },
+ "files": [
+ {
+ "name": "module-one-1.0.0.jar",
+ "url": "module-one-1.0.0.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "runtimeElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.jvm.version": 8,
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-one-1.0.0.jar",
+ "url": "module-one-1.0.0.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "javadocElements",
+ "attributes": {
+ "org.gradle.category": "documentation",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.docstype": "javadoc",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-one-1.0.0-javadoc.jar",
+ "url": "module-one-1.0.0-javadoc.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "sourcesElements",
+ "attributes": {
+ "org.gradle.category": "documentation",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.docstype": "sources",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-one-1.0.0-sources.jar",
+ "url": "module-one-1.0.0-sources.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ }
+ ]
+}
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc
new file mode 100644
index 0000000000..54d7598382
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1HBQf/fCBHR+fpZjkcgonkAVWcGvRx5kRHlsCISs64XMw90++DTawoKxr9/TvY
+fltQlq/xaf+2O2Xzh9HIymtZBeKp7a4fWQ2AHf/ygkGyIKvy8h+mu3MGDdmHZeA4
+fn9FGjaE0a/wYJmCEHJ1qJ4GaNq47gzRTu76jzZNafnNRlq1rlyVu2txnlks6xDr
+oE8EnRT86Y67Ku8YArjkhZSHhf/tzSSwdTAgBinh6eba5tW5ueRXfsheqgtpJMov
+hiDIVxuAlJoHy2cQ8L9+8geg0OSXLwQ9BXrBsDCLvrDauU735/Hv/NGrWE95kemw
+Ay9jCXhXFWKkzCw2ps3QHTTpTK4aVw==
+=1QME
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5
new file mode 100644
index 0000000000..7da5a1024e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5
@@ -0,0 +1 @@
+b5b2aedb082633674ef9308a2ac21934
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5.asc
new file mode 100644
index 0000000000..f525064e6a
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1SLQgApB6OWW9cgtaofOu3HwgsVxaxLYPsDf057m2O5pI6uV5Ikyt97B1txjTB
+9EXcy4gsfu7rxwgRHIEPCQkQKhhZioscT1SPFN0yopCwsJEvxrJE018ojyaIem/L
+KVcbtiBVMj3GZCbS0DHpwZNx2u7yblyBqUGhCMKLkYqVL7nUHJKtECECs5jbJnb9
+xXGFe0xlZ/IbkHv5QXyStgUYCah7ayWQDvjN7UJrpJL1lmTD0rjWLilkeKsVu3/k
+11cZb5YdOmrL9a+8ql1jXPkma3HPjoIPRC5LB2BnloduwEPsiiLGG7Cs8UFEJNjQ
+m5w+l4dDd03y5ioaW8fI/meAKpBm4g==
+=gwLM
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1
new file mode 100644
index 0000000000..f4d48063e9
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1
@@ -0,0 +1 @@
+b7cb6c2ce7fbb98b8eb502c3ef8fcab0dd4880fc
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1.asc
new file mode 100644
index 0000000000..0c9e8cb570
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2y5AgAlI4H5hwDIgVmXtRq/ri7kxEJnC9L9FOv8aE9YasHAruaU1YR5m17Jncl
+4guJHc+gSd3BiSx1rsI6PNxLACabw4Vy56eCRpmiFWeIkoCETBUk8AN25Q/1tzgw
+hHmIRgOkF9PzSBWDTUNsyx/7E9P2QSiJOkMAGGuMKGDpYTR9zmaluzwfY+BI/VoW
+BbZpdzt02OGQosWmA7DlwkXUwip6iBjga79suUFIsyH0hmRW2q/nCeJ04ttzXUog
+NTNkpEwMYpZAzQXE7ks7WJJlAPkVYPWy/j5YCV7xTFb9I/56ux+/wRUaGU5fumSR
+lr3PNoYNToC/4GLX6Kc2OH0e1LXNTQ==
+=s02D
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256
new file mode 100644
index 0000000000..cdc919db3d
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256
@@ -0,0 +1 @@
+4ef7e1ba5fda72b0168c9aab4746ec6ee57fb73020c49fe2f49251187aaab074
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256.asc
new file mode 100644
index 0000000000..94ab1b8db0
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1/vwgAhUTLKjxmry4W3cVdfX/D/vxDTLAp5OxwJy36CZmJwsVuN9TLjPo4tRqq
+woiopR2oSTaJqld2pe98WlIeDJJRe4ta1Uwvg7k4Sf6YaZXm01Wufk4a835sFUwY
+BTWmnFYX0+dp5mLyXZmZjrAr5Q2bowRuqZd2DAYiNY/E5MH2T7OAJE2hCOHUpCaB
+JVeP7HcbaGYR3NX/mLq0t8+xjTPXQk/OHijuusuLQxfLZvZiaikDoOHUD6l0dlRw
+xcLTghG5+jd1q7noKAbUVgoEOshstfomCHZpPMj11c7KIuG1+3wRMdm+F67lkcJ5
+eDW2fmF+6LYr+WlEi33rDIyTk3GhlQ==
+=mHUe
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512
new file mode 100644
index 0000000000..76ab9ddba9
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512
@@ -0,0 +1 @@
+29b1bc06a150e4764826e35e2d2541933b0583ce823f5b00c02effad9f37f02f0d2eef1c81214d69eaf74220e1f77332c5e6a91eb413a3022b5a8a1d7914c4c3
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512.asc
new file mode 100644
index 0000000000..8041ff51f1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.module.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0QLAf/ffTpTfH4IebklGJIKZC8ZjRt4CgwpR431qNeWkY25cHmWFj48x2u9dmS
+ZpxN572d3PPjcMigT/9wM05omiU+4DHxGgHq/Xj6GXN1DNaENcu7uoye96thjKPv
+jz98tPIRMC9hYr3m/K1CJ3+ZG0++7JorCZRpodH/MhklRWXOvNszs81VWtgvMnpd
+h9r0PuoaYBl6bIl19o7E3JJU6dKgwfre4b+a1RSYI+A8bmJOKMgHytAKi+804r0P
+4R2WuQT4q+dSmkMtgp65vJ9giv/xuFrd1bT4n+qcDkwE8pTcWvsB4w1RkDOKs4fK
+/ta5xBQ1hiKAd6nJffke1b0MBrZOrA==
+=ZMpE
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom
new file mode 100644
index 0000000000..f9fbedf9a1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ 4.0.0
+ org.springframework.example
+ module-one
+ 1.0.0
+ module-one
+ Example module
+ https://spring.io/projects/spring-boot
+
+ Pivotal Software, Inc.
+ https://spring.io
+
+
+
+ Apache License, Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
+
+
+ Pivotal
+ info@pivotal.io
+ Pivotal Software, Inc.
+ https://www.spring.io
+
+
+
+
+ scm:git:git://github.com/spring-projects/spring-boot.git
+
+
+ scm:git:ssh://git@github.com/spring-projects/spring-boot.git
+
+ https://github.com/spring-projects/spring-boot
+
+
+ GitHub
+
+ https://github.com/spring-projects/spring-boot/issues
+
+
+
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc
new file mode 100644
index 0000000000..eba13f46b5
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT04rwgAwJHic8GGHFZ+UAJYLW/OxJOVyd0ebx4yT5zAyTjyvxnrlKmKZ6GP/NhZ
+htJQnZez85lUKA0TsMvl/6H2iEhKOns6HgqY3PLFkKNRKOq601phtD9HCkxDibWB
+UDT01I0q2xNOljD03lhfytefnSnZ96AaySol2v5DBIZsOKWGir0/8KJCpEQJHjCF
+TwNk8lNF3moGlO4zUfoBbkSZ+J0J8Bq5QI3nIAWFYxHcrZ2YGsAZd48kux8x2V3C
+c6QsYEonmztqxop76a7K8Gv+MDmo/u/vqM8z5C63/WpOoDtRG+F5vtPkhCrR6M5f
+ygubQUy5TL+dWdHE8zgA2O9hZuoHEg==
+=bkxG
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5
new file mode 100644
index 0000000000..d82ed4d3a5
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5
@@ -0,0 +1 @@
+48776112e8bc3ca36b6392b0e9d6d619
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5.asc
new file mode 100644
index 0000000000..78c3a0a5f6
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0XEAf+O9a/29MIWBtj1oLxIT1LLdzTU68qt5+qW+58SNQmMxu0MaESW4GZOc3p
+mTV0EJyxUkCLJyoqOY4/GhqBAm33mMZSY8BQtvUZPYxpbJwBo+pE8YfnH3n1v20P
+4pS4oJKekXAhTqShpx5oFjCK4J3chaz+Xc8Ldm1DXakCRc1bc/YYZ+87sy2z+PXk
+PmN3KPcc/XjH4GPjmVUR8vR1TGUjUMQGvbAdrgkjFyaCGNvyreuHLsAFWrFFbIOn
+/mB++enkXhmjWbiyvmvWQvtU0QFA4sRGYww0Lup1GRQ+00IqHF1QRMskqujAwmok
++TuB3Zc9WuAERPre+Qr1DEevClNwAQ==
+=3beu
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1
new file mode 100644
index 0000000000..28dc2dadd3
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1
@@ -0,0 +1 @@
+a5cc75e17f8eccfc4ac30bfbb09f42d5f34ecbb1
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1.asc
new file mode 100644
index 0000000000..9d1d2ea54f
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2aVAf+MQhSBr1jzcQE5mo1bMOXa4owaRr+dRir5Q4Gr7Fz4NuGoQEIzoL7XP5r
+0zIjebzworxCaw+JNyaIxniHNBeK3sPHTLeW8bCrdJLkhE9RtGdEHLyPYXwPuFin
+xVw3VQHWiA0uPM+JaekgdPDtK5wGFQ/AK3pc6vR108oT0kV4zQEqgRnvLqV9Q5zZ
+UPHBi5kypu1BmCW4upYL1dmjASWPn9Q8cNpHcX/NJPNJ9zW0yxAAtq4wLfh7PQml
+3EaHEYllsf8v1vMv00+zZNhc6O4BBP1qrRiaYHDAJhJjn6ctV9GFhJ2Ttxh/NmSy
+H679tlC2PeRjGMi8bOHBshcikn5KUw==
+=4aJI
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256
new file mode 100644
index 0000000000..8d1625bf07
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256
@@ -0,0 +1 @@
+3b31f2abf79368001e2fab02997446ac62db714b9db9cb78c4c542aa962485dc
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256.asc
new file mode 100644
index 0000000000..e572b776de
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0nDQgAlfchq7/W/wubx3IR3tQs0tKiix3nZIc97zuH6sR8+r+CJe78wbmSE9Oo
+/z96wfzeZYNIKh2v+dBLHF7OfcPGBE7tiX07jfCa6KzjjY3hFBhW+muMP/aBRb+4
+itSs6F3lkZOPW2+hpSdFQ6U8Rm81cAlZv7Zk2XswwTQkJo8GcNL1w/5wAVpNK0yG
+VinZr8YRMFs6OYQxLqGSypDLAmv9rOaJ7aCdaKnQwYES65kC7tbe0SRZGQoDe8n4
+XLzpvC8rM9MXZDEN4qI+ZAANOJNVsXUmDZLDSe4ak48u/cTOokY8I6bR2k/XOhbu
+L+D4W7oKAE9HmzlTMusosyjNOBQAmQ==
+=Wjji
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512
new file mode 100644
index 0000000000..6edd0b3e98
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512
@@ -0,0 +1 @@
+05bd8fd394a15b9dcc1bfaece0a63b0fdc2c3625a7e0aa5230fd3b5b75a8f8934a0af550b44437aa1486909058e84703e63fdec6f637d639d565b55bdaf1fa6c
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512.asc
new file mode 100644
index 0000000000..896fc8f31e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-one/1.0.0/module-one-1.0.0.pom.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT19rwf/a6sZxSDNTxN72VvsrKsHq+wMes5UUcQ+L7e5QLjaCTx2ayW2FdHMBaNi
+IDBBE9kxnxa/S6G6nSRARUjXowsEYZGUNLLvUjNZ4Z3g2R9XyGPaz3Ky9yWpRm36
+E0lFqf8aaCLpzwV2z7cfeVNYsd2gnHakphK/UiZzXFz+GYzqby/0m5Kk8Zs7rK6V
+/ji0bYWUi8t1jli8MfTHQtM8EUHG0nXRfEKilyoYkO3UsTEh/UN1VRpJ5DgcRC8L
+Zbd2zPnV15MPUzZvz3kkycUulQdhOqTDjUod9P/WoASwjDuKCG2/kquwOvnoHXJ9
+9Ju+ca0s9y0jbotIygYxJXZVev3EiA==
+=oWIp
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc
new file mode 100644
index 0000000000..85d6a7cb1e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
+eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
+0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
+3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
+GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
+e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
+=x/MY
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5.asc
new file mode 100644
index 0000000000..1cbf6ccffa
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
+E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
+fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
+jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
+3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
+W+QvcE7wyW2jtb22pCImLyObyZ21VA==
+=VjDv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1.asc
new file mode 100644
index 0000000000..4cd212d6e1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
+U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
+EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
+jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
+bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
+ElRgneV4HZp+LB125VoNabKuNH00bw==
+=2yDl
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256.asc
new file mode 100644
index 0000000000..e29629cbec
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
+dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
+BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
+J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
+KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
+mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
+=5oO1
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-javadoc.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc
new file mode 100644
index 0000000000..85d6a7cb1e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
+eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
+0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
+3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
+GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
+e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
+=x/MY
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5.asc
new file mode 100644
index 0000000000..1cbf6ccffa
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
+E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
+fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
+jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
+3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
+W+QvcE7wyW2jtb22pCImLyObyZ21VA==
+=VjDv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1.asc
new file mode 100644
index 0000000000..4cd212d6e1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
+U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
+EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
+jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
+bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
+ElRgneV4HZp+LB125VoNabKuNH00bw==
+=2yDl
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256.asc
new file mode 100644
index 0000000000..e29629cbec
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
+dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
+BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
+J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
+KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
+mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
+=5oO1
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0-sources.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc
new file mode 100644
index 0000000000..85d6a7cb1e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3qtgf8CeDvxzi7lPghlrZtmYTTjaic4FZsGRWTPky3H24i4wSRDhG0L5sj4uPK
+eLLlITr5a9j26UCas9HRSthiC8+EgIMAhSN0X482SQhUZHAW67ErIvaHlwL+ixMD
+0T5pmsW8PKN3lV1TFMhNYSEC2GRG/4GF+3yQA8LR+BgeEu/E5nmysIH8vuQMkOD6
+3pKA8VKNBml591j6UTqxoHtPX+rThaziz3Hy3+ekf5iWslllTTGPd2SWqTvnj2Ae
+GvRzsbli+FEM0Aj/v8jUQnQzOz891QSvWR+fMfCqZimiJMc+GBzJ9umbcyQsB5tY
+e26mAoYd9KEpGXMKN4biHbJZNp1GGw==
+=x/MY
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5.asc
new file mode 100644
index 0000000000..1cbf6ccffa
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
+E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
+fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
+jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
+3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
+W+QvcE7wyW2jtb22pCImLyObyZ21VA==
+=VjDv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1.asc
new file mode 100644
index 0000000000..4cd212d6e1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
+U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
+EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
+jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
+bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
+ElRgneV4HZp+LB125VoNabKuNH00bw==
+=2yDl
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256.asc
new file mode 100644
index 0000000000..e29629cbec
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0ScQf7Bip+quFq1CzDCTDxUhdTTOIpQcCfMKo1Jegpa2Hlm63XuK+6zVI9u6S+
+dBXPdYeneMOqMPQUAaw3M06ZqohaDOt8Ti1EiQFGXCdOvbonTA52Lrd4EEZxwNnK
+BdPuIh/8qCfozm5KbZe1bFyGVRAdNyf27KvzHgfBTirLtI+3MiOdL4bvNZbWRPfh
+J84Ko+Ena8jPFgyz6nJv2Q2U/V3dCooLJAXs2vEG6owwk5J9zvSysWpHaJbXas5v
+KXO9TOBBjf3+vxb1WVQa8ZYUU3+FIFes0RFVgOWghJXIooOcWrwOV2Q8z9qWXwoK
+mMZ2oLS+z/7clXibK45KeRUeCX5DvQ==
+=5oO1
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module
new file mode 100644
index 0000000000..8618f194c9
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module
@@ -0,0 +1,101 @@
+{
+ "formatVersion": "1.1",
+ "component": {
+ "group": "org.springframework.example",
+ "module": "module-three",
+ "version": "1.0.0",
+ "attributes": {
+ "org.gradle.status": "release"
+ }
+ },
+ "createdBy": {
+ "gradle": {
+ "version": "6.5.1",
+ "buildId": "mvqepqsdqjcahjl7cii6b6ucoe"
+ }
+ },
+ "variants": [
+ {
+ "name": "apiElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.jvm.version": 8,
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-api"
+ },
+ "files": [
+ {
+ "name": "module-three-1.0.0.jar",
+ "url": "module-three-1.0.0.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "runtimeElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.jvm.version": 8,
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-three-1.0.0.jar",
+ "url": "module-three-1.0.0.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "javadocElements",
+ "attributes": {
+ "org.gradle.category": "documentation",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.docstype": "javadoc",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-three-1.0.0-javadoc.jar",
+ "url": "module-three-1.0.0-javadoc.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "sourcesElements",
+ "attributes": {
+ "org.gradle.category": "documentation",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.docstype": "sources",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-three-1.0.0-sources.jar",
+ "url": "module-three-1.0.0-sources.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ }
+ ]
+}
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc
new file mode 100644
index 0000000000..f7112bc8e5
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3OcAf+OJv0t0rhNnJcF656mem5qv3fvcJKkPqyKF9I0TiP33W61/ntrGezdaDX
+tLde1MFRto3HS0/U0t6NqfMNTXYcQ5vH/qqnIRWP7Iv/t7f+mum6pOcYkxJhhXFT
+1pH0l4iqVQOBUiAJhOpUh0utLNWdZcEv+DdxgtFbFyaEDmg46Cpy9YtAH6XKEh5d
+ZZeiX/+XC+Ufx1bReDLHvFjUyQa/Lv8rEthX2eBmAXkoPwJG0LA9xF6X8leB0DI/
+9a1KiNcmRSSUarLpqV/hE6oQggGeMLVoJ+51klunRAfiXw6h2m9gRlnWikLjC+23
+/E2m+7Gb0Kc4izXIdHTqS2fYPMHsyw==
+=h486
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5
new file mode 100644
index 0000000000..c5a7b48693
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5
@@ -0,0 +1 @@
+90fa60dcc829042dd1208c174752caeb
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5.asc
new file mode 100644
index 0000000000..83f03d8779
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0xjQgAwJcUWVwcl3PI7FhRUoPaPfqaoG3bUPwLePYuf++qPCNUDOmnq0aXtqbr
+Ul9SxQRDy9D7ygCWVCTVXRjg0HHZQT/ZYB7lhaDLxMEpV25q9acJAZ4qzbn8vRAG
+FqlqYaSlIDducapPUGWAOF/xwhf5k8tIGO5p0hY4wdU3b+0YU1w5DavYOetTZ26Z
+jwVagOj/6WFIHnu6PwXGkynqxui8dnsld23eamOZYsfR19weTNh0GT3ncl8y03eP
+Wy6CkFxzN0kvSdze0nAfO9dygpRxh7nNbz/uJhTFP4pDwz5iE8FBiUXZLkxTZ8YJ
+lvIKuS+JnUTEQcd00/nAL4cncMiJIQ==
+=lQP9
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1
new file mode 100644
index 0000000000..4b25265d72
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1
@@ -0,0 +1 @@
+9090f5fcb4c79a89b3a46f2cb8071381e0787a03
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1.asc
new file mode 100644
index 0000000000..cfa8f7e888
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3urQf/W31jKnVjCIckj7XFbeucazmVr0K73LNpg0eQwqqz877KKmBDV8qn8b3o
+MTBDgUn/9LMJzUSWRFV+CkM0cgAG0s8vmzeymtH6RWv+ikHh/3Ky4sYxd9Pa3Ipo
+zeeIqyJk1dysfcLLsP1ml6ayh8VM/DK+DDc4CU9wrEGAUDeVIFiTw7DrMIB7PcdG
+ru7z6J/jcIA55RiJMDvuqhS+Obx/JUrmqDrrK8Npp9stRP+RpZpF1AKGgg1dfLo1
+bKw+KYuMhK7Kq7nIg9GqZvhr46oOKko5NF2l+GfVR14Gdb330/88t/IxwJvsUiCC
+sWQTrGJb062N5oHGtdoZ3mXLo7bnuw==
+=+snH
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256
new file mode 100644
index 0000000000..346a5ff6e4
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256
@@ -0,0 +1 @@
+2e8d3db6ece5719d7be27bcfdefa1f890da9a19f73390c7122797db1081d245b
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256.asc
new file mode 100644
index 0000000000..41d0ccfe35
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT14OggAlf9eyYFV3HRC7LoeM1Q9LrkYZUIDIUkukUxDxBTGPLf739qZtHgUl6lC
+yUCQqGswhuuwR8s7ht2MDMp8isjs1j7inpAQA3kYgHOCUMjYlIyhPdIxHtQ8WD+S
+CwW2nHtf7tXFrhKFecqolKyp+qZYWx1anMmbLggyaXWZmiIwhIHLxIogbyjVLdkD
+9qUAKCUpEvyNqogyYYtAjJERRzw9RN4lwnpm/uEkKtFQVoxui2VQr/DEbzooXu8A
+mqKkUBbgf9uxH5s+pUuUgbl+XZnPLGzJV6NcFe/jpsvEzHkUQzAsVnNnCWAPreY8
+RTfj2eGleFWESIiMFUAp6U0an5GoOQ==
+=T+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512
new file mode 100644
index 0000000000..1817ab28cb
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512
@@ -0,0 +1 @@
+ac3e2a0dfb3b8ddaa79468f85698ff97e9b88e401849e2e733073b711a1673ba2e37be61d224fd69ec2e1c59ed0342e6b3757bc3931c2e297d24bcae9370fa3b
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512.asc
new file mode 100644
index 0000000000..1f6bfda966
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.module.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1HGQgAuINmQJ5vpFWWmXbIrEVf5+fTKq72R7gXdJ9XHYgQdSyKoeUUy3FElqfI
+55gyiLk1OMMy6Pd1HKi0bczOUOlz8K34uMXcT+ctm41Lp6243FfLm4iy1x/DWlHb
+IWksIG1TRf7g0b//OiBbbaesjnc5QK1rft6T4KiEPD9NtOi/8ON7vVu0S9oERUGO
+32Zwu/wGZeKztUoXVQ/zZk5UA9hYE/7C5bX3dRBS038luv7YZKe3313PfVj29vdx
+bsfRIcH/qIe//WL3OTTbaOvSgOs8qvJHPN8NmdH70GbZ2W9jTe7KrIlb8FBEaPEj
+BbLov9td9qxXlRxyBhLYRB7MN4rsKw==
+=qIiQ
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom
new file mode 100644
index 0000000000..4467198240
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ 4.0.0
+ org.springframework.example
+ module-three
+ 1.0.0
+ module-three
+ Example module
+ https://spring.io/projects/spring-boot
+
+ Pivotal Software, Inc.
+ https://spring.io
+
+
+
+ Apache License, Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
+
+
+ Pivotal
+ info@pivotal.io
+ Pivotal Software, Inc.
+ https://www.spring.io
+
+
+
+
+ scm:git:git://github.com/spring-projects/spring-boot.git
+
+
+ scm:git:ssh://git@github.com/spring-projects/spring-boot.git
+
+ https://github.com/spring-projects/spring-boot
+
+
+ GitHub
+
+ https://github.com/spring-projects/spring-boot/issues
+
+
+
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc
new file mode 100644
index 0000000000..eb100ce746
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0T5QgAgXfcX/6hkGNWRp4xIbpC0P9wi21WBmlWeM1l1vPjlogcPB5fIQ15tnxL
+dyXVJjhdBXG70m5UkOtR5LbO+6Y7soEsocfuN/wdjNP/JUk2xW4HTj87F16r3EhV
+s1nrydd/nZxsIemTY1irOrCk4yEOWlAO91VOGFI4UoGGE6oeMiTFje6vbNidGT3Y
+RD1VrxbVasI38HHggQ+odrdp+rk8AwAUJq8g96KyRO5d+O6NQCf4cTe6S5+kJKG1
+ETQ0yASHiD5pzcpQiEQu+wclgAunVAzr5Ql/SnOcZEjUoVOLix7Ttcv5KcXjZhY9
+9VQyULZ1MzcrSEoRoOv8k8fT7swvLg==
+=KgwJ
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5
new file mode 100644
index 0000000000..e156ed0302
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5
@@ -0,0 +1 @@
+a819cb79241de23f94f3626ae83be12f
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5.asc
new file mode 100644
index 0000000000..f55b2670d4
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2Umgf+K57ogLEAGx/40dFOV0yiGmvCXwywMCVbnMXCA85Ceti0TGFY6T0EaJXy
+wF7QQ0SW56svIxX/U58IVocWuaVRJA7tCZF1u9DCvafdYDJeM4iHHVu6GzM1Tng2
+JFYV4q5MtT712rCrcf7ZH3MntYawsGjBiF9IHWwvSNUyf53W7L4VSWcpv0tfPLra
+EeC7ztnnDXgi32FSpXvu27mDPbrQLibihUZBjoZ4uuRU2wB6HICJ90JjoYtK6JoC
+ToEZY4jFLkEmQ8dy0KUa5rhUDWJ+Bq+bYHhwMXl9HQUKZuqjvlmHCRHIsJgdU+Cl
+i5NPJkXhCZOs9tD3hf3NdeD9ef72kQ==
+=PraK
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1
new file mode 100644
index 0000000000..81ed28e231
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1
@@ -0,0 +1 @@
+e562eacb5f9cf14ccbb80c8be0396710fc6a546c
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1.asc
new file mode 100644
index 0000000000..53461b47a0
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2j8QgAiciViDfKLAv2rYMyBJbyQjK29fpG78NMsKw+j3zWwJEPlPuZhIT0/KWQ
+3ipcYbtBoKYrKSG54uzPflGAQoostMYV+XtJ+0fjICsNDpKjfhuDWojaWkxnF1KD
+NcWSiapNO6iX0s62yaL/netVVsHsE5fVr//IG6WDTrJK2GEkOQAoca2W8ixI3G0s
+kTIJEmCMA9ZOUMKBwwtJ0NPEZPxe1N/R6SuGWGdkWlrqPRmA6lnY153zH3vJ6pqF
+RM1Phwpt46l3o20D5wOhqU8jvV7b5HUZ50sHV0sJOMUbwvFyrhIOzJLMixk1WJhR
+lnudbpWPssTJO3Fiv67b/iADaBaIbA==
+=4CYs
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256
new file mode 100644
index 0000000000..381f84d9d4
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256
@@ -0,0 +1 @@
+f043a098eee190d59e2b4b450c2de21dcb3b7fce224abefd89e0e5b44b939fa7
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256.asc
new file mode 100644
index 0000000000..b9b35e5371
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3Pwwf+IikjoDdjeMQfmERTN4Gjirx9+fler+Gr5JYC78OxLrB8uq0tn11wEJMQ
+ZDQe83OYjEkFQhPn6yQ5bc9edZTJztQJcGpVe7NkYffS4geo+ahuksaQWMF9opEc
+OqBB5fTWVt18qGFTI2F3CEDIo38muTgkzndFuzmcbVhAcknF5ybcVDIFpZNlnqe/
+xflD6lupXWXQC4nE4n2EVhNnmkiF9nKRJWwEJ1hoy1gwTxSYmnO/BLn8ob4tswnc
+gHnj4Yp7qoV/SnRnfNDHMPQMfzAwq1jucjjPOt3xkw17UIGBnrP1zAxeZFmarCTO
+YjJt5PUNwtqOVHlHzwgn3b3FGRJe3A==
+=AU99
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512
new file mode 100644
index 0000000000..fb6a445480
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512
@@ -0,0 +1 @@
+67549e36f07c9f4b83cfa9f00fa647705128eabd03dec3df0066177e89940652fc7e13b8c0b60652c811e167c3ffaba0ab95a4f315a10f69572c12e4e944b6e6
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512.asc
new file mode 100644
index 0000000000..71232b747c
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-three/1.0.0/module-three-1.0.0.pom.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT0bBgf+Nm9vooXNKE/z4cNeFqiHwLb+gMxvqlKnl/+03KbuFvlDUwdqSxfnHQZ3
+qfCBtIe6MN/0I5FCNRCcFxiCjCPDqSMAcvRPU5UOG2M2W0uvcqMwKO6KRGBLd65J
+MulDxoe7LrEk6KwNYfecxCtXBvLwzwQd3A10tcQOVl66neF/g+9jEc+MHJPa1xi5
+4pDOo3TQ4EpGfB8eF9Z+7YKc9hPYBFsm+n3P6SYcVAiRUiNBE8gCOvvZE9mOTQAo
+yC80AfDjXe/YBsd3a79hVW+ESQAKfK8S1RzO+c5GhIZCIJFdSJDOeww86O4U0n5g
+6hIXRNWUFUEueAvQ2dYHZujQSBxNig==
+=t5De
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc
new file mode 100644
index 0000000000..624356b34a
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT1IkAf+N8ts9K88PC/dISZMWSrgRbSugd6VRG6pto6jsp9cJBzTzQ6C8psMkXcN
+qX0fnLBn4Zn1dovxRIrA8QeT/vxHMl1X0Foe6SUTMjK34Ofq4V1FVlhuJIi0YZrP
+L7B4cKTkv1ndwSVgE23zkynfaIPiPl1uZOwDmlpArokqnjSiUq9NndtKf87NwekW
+hbf7brgfZddeDj9xhAn5hz2pHUhx/uH9tOX3JlZgE+yATZsGm6Z9BSf4Lur0W85P
+hrJ+MfuYPzZ3n7okuaQdMT3QIqe3FO+dfGZKwakw2NWfgWP3LZsQ5rbyxBlyH7CG
+JA/VAIIqe99ftHcBFRGB6C9hMn4FcA==
+=prNt
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5.asc
new file mode 100644
index 0000000000..333ba4509b
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT3jzQf8DUis2+v7616JWRpUziEnpnvms7+PkgovWttcpbO0RlLr1s0Uno0D0jAt
+7KUGNN4//n8hKsojZ6ZI+7pzsk/0NathOQRNYcdb+AFf71T3yJhef1d5GmXHA7iV
+wA6AfrFTEQ7SaimZXEGGpFXzb3rPsVnryOEbTOXno3B7nNjZTUpjkW/APkvJueUk
+BIFCWH9rL1txRKWhKg8f6YT+l6HQFn+qu1Z3/MoqxCn6HvUxExA1mwNbzfvNaDTt
+l04jNVG6NqZyGhivuDnpyonnmwKySryKVvGrWn6b5SfgPPQYQJTWK3c7npSPjKpO
+ydzWOvISS55vBKLbB7g69g8ah3FHEw==
+=fcEr
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1.asc
new file mode 100644
index 0000000000..66ae31b24c
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT0ovgf/aejEen2MEvJTF1Tjg24rK1jZAYqmgGi8H2b26h7ZEd/le2jWs6VpPmvv
+DX3pyaKFyOZXpU8SOkoPgi021VIt9LLWPlxMgcWlb6EWg8xw70PXISbUFy3IcxRi
+I14uAUXoFgIOT6jPt659kdXLNtYRsS3nQcBgJTIz6axHk2t5tD3TRf4xcLCyuVGv
+/obkTwpLr2jdPBxgTe+oDPjCnOyI6YeN0dKq4aiGBI/xECNpitbzmYQA2FQ+WvsG
+qq+1n/eAZAzAUWumxLna9ov1O0f6cY9d9hxWMTe2L4/a7B6KezF0CPnShFaC6pCV
+98aamE5QxBmSeQtmRdI75WFHJ1h0Vg==
+=0M4U
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256.asc
new file mode 100644
index 0000000000..825ed5de96
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT104Qf+NG6IUBLo7eTPtPzWyNs9bShrJR759atbY9kBOrRfyoBM/hWrcr6pG4e5
+BmBPULkuBWLVM+Ra52B2S96848oiaLLEuiWlMudWRsWCxyVknjm9EKlMHA3VdQtu
+8grrPKS4mIwSvdzAEEeqR+mwtWXHlz+jc/R9NeQhNmmcNZv1nkyzCuoNCH/HMTl4
+/ei6enpYrYNnMrNz9TOMQ67sCtZEm6TaxlqS+9h/V9TEnq6+1qXEt4c+AsqQdMWH
+3BZREzXHFocQciSEXfL6m07pnNlnvCcjsM2SAqTeTqQupEmqFGkhL2blE1VMdplW
+fDCC/ee5JYVyyUXpzydSjCYwFbO3NQ==
+=gSEv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512.asc
new file mode 100644
index 0000000000..7df8aa894e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-javadoc.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT0XdAf/feMRtW2BUz84x43aYLaERIEPx2TsqMUwVcov6sp5MWaSAJEX2vrscCRB
+K/7x4N3dxnrckc3sBF1hs+zrRwySYU1FyGVIxQxdeURnUWxCva0uOWj91jcUOIkA
+gpmOZZj51b4SkB6GZjtvN/Z3B4xzEPmTPfKFiBZPhuYW4HiC8FHM1JnlW6h2xoj6
+Bja//qoj9ccfRjiMnnI0iPgZNiyR8n8+EJGi0ykizxkiT6cWI84kZ+JQYooDHbCf
+NgPt2NjcGzd6SGrQW8/0td0N+xDRfLpTrbfTmlC5hikXmS0e79BV6W0eYcWcgDni
+r8WjbDmomHHFDhT8p1R+tGtd8p2txg==
+=BHvx
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc
new file mode 100644
index 0000000000..624356b34a
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT1IkAf+N8ts9K88PC/dISZMWSrgRbSugd6VRG6pto6jsp9cJBzTzQ6C8psMkXcN
+qX0fnLBn4Zn1dovxRIrA8QeT/vxHMl1X0Foe6SUTMjK34Ofq4V1FVlhuJIi0YZrP
+L7B4cKTkv1ndwSVgE23zkynfaIPiPl1uZOwDmlpArokqnjSiUq9NndtKf87NwekW
+hbf7brgfZddeDj9xhAn5hz2pHUhx/uH9tOX3JlZgE+yATZsGm6Z9BSf4Lur0W85P
+hrJ+MfuYPzZ3n7okuaQdMT3QIqe3FO+dfGZKwakw2NWfgWP3LZsQ5rbyxBlyH7CG
+JA/VAIIqe99ftHcBFRGB6C9hMn4FcA==
+=prNt
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5.asc
new file mode 100644
index 0000000000..1cbf6ccffa
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT1PSwf+InTdlh+BVVy3RFszEL5vN7waSPYMImXhgd5EZ1d4Lxd6EeOwtNgWNKpG
+E+Ps/Kw0jZDvoD49WJlcUjzDHBNHcE7C/L3GAWHV6WwklhtQaJ4EegsynWdSXz6k
+fqJY6r58aGKGjpKPutRWAjvfcdC170+ZRsc2oi9xrAgHCpvXzTjq4+O9Ah0t5jwW
+jcZ/Xubcw4vjsw774OucHbtwGsvRN5SDJ3IONOH8WCwhUP5vEEKvA6MYX0KGoTdS
+3wTCyZTzU3qtTWxcbTCpiJIWbYwRR7TzLB/uydWHlAMzuz6coIiBpYsGiO6wkmfg
+W+QvcE7wyW2jtb22pCImLyObyZ21VA==
+=VjDv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1.asc
new file mode 100644
index 0000000000..4cd212d6e1
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2HQgf+MTUEnwzXK4zi76VI7C5cchGan26lIA2Ebq4vtYGKDqNSISOAAdWs9+nT
+U6ZA6OIFo5qdeD6F/45s91IoDbxbhMDMFEsSijKASqiuZN5TZM1U2h2kWFAl/sEl
+EI1RTygn+xDw/ah4V3/duuMFC+jRgvJ/LgemIF4KBvECWaTQKNu0fu5d4dPXMpp+
+jrxMEZPQZsivpOvklzV8O7wAkf/ZQhJdcB2m8uOfSPlJ91a4EEtXF9/GzzkXUi1P
+bzt4NsmOag3227B3mO1Bc6yZdDBNu8wQ9apiJVCpqsxB9Dz0PCL4dHNa1u9g6Xo6
+ElRgneV4HZp+LB125VoNabKuNH00bw==
+=2yDl
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256.asc
new file mode 100644
index 0000000000..825ed5de96
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT104Qf+NG6IUBLo7eTPtPzWyNs9bShrJR759atbY9kBOrRfyoBM/hWrcr6pG4e5
+BmBPULkuBWLVM+Ra52B2S96848oiaLLEuiWlMudWRsWCxyVknjm9EKlMHA3VdQtu
+8grrPKS4mIwSvdzAEEeqR+mwtWXHlz+jc/R9NeQhNmmcNZv1nkyzCuoNCH/HMTl4
+/ei6enpYrYNnMrNz9TOMQ67sCtZEm6TaxlqS+9h/V9TEnq6+1qXEt4c+AsqQdMWH
+3BZREzXHFocQciSEXfL6m07pnNlnvCcjsM2SAqTeTqQupEmqFGkhL2blE1VMdplW
+fDCC/ee5JYVyyUXpzydSjCYwFbO3NQ==
+=gSEv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0-sources.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar
new file mode 100644
index 0000000000..a142d391c0
Binary files /dev/null and b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar differ
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc
new file mode 100644
index 0000000000..624356b34a
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT1IkAf+N8ts9K88PC/dISZMWSrgRbSugd6VRG6pto6jsp9cJBzTzQ6C8psMkXcN
+qX0fnLBn4Zn1dovxRIrA8QeT/vxHMl1X0Foe6SUTMjK34Ofq4V1FVlhuJIi0YZrP
+L7B4cKTkv1ndwSVgE23zkynfaIPiPl1uZOwDmlpArokqnjSiUq9NndtKf87NwekW
+hbf7brgfZddeDj9xhAn5hz2pHUhx/uH9tOX3JlZgE+yATZsGm6Z9BSf4Lur0W85P
+hrJ+MfuYPzZ3n7okuaQdMT3QIqe3FO+dfGZKwakw2NWfgWP3LZsQ5rbyxBlyH7CG
+JA/VAIIqe99ftHcBFRGB6C9hMn4FcA==
+=prNt
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5
new file mode 100644
index 0000000000..95fa4af164
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5
@@ -0,0 +1 @@
+e84da489be91de821c95d41b8f0e0a0a
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5.asc
new file mode 100644
index 0000000000..333ba4509b
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT3jzQf8DUis2+v7616JWRpUziEnpnvms7+PkgovWttcpbO0RlLr1s0Uno0D0jAt
+7KUGNN4//n8hKsojZ6ZI+7pzsk/0NathOQRNYcdb+AFf71T3yJhef1d5GmXHA7iV
+wA6AfrFTEQ7SaimZXEGGpFXzb3rPsVnryOEbTOXno3B7nNjZTUpjkW/APkvJueUk
+BIFCWH9rL1txRKWhKg8f6YT+l6HQFn+qu1Z3/MoqxCn6HvUxExA1mwNbzfvNaDTt
+l04jNVG6NqZyGhivuDnpyonnmwKySryKVvGrWn6b5SfgPPQYQJTWK3c7npSPjKpO
+ydzWOvISS55vBKLbB7g69g8ah3FHEw==
+=fcEr
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1
new file mode 100644
index 0000000000..2a2834e1ab
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1
@@ -0,0 +1 @@
+8992b17455ce660da9c5fe47226b7ded9e872637
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1.asc
new file mode 100644
index 0000000000..66ae31b24c
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT0ovgf/aejEen2MEvJTF1Tjg24rK1jZAYqmgGi8H2b26h7ZEd/le2jWs6VpPmvv
+DX3pyaKFyOZXpU8SOkoPgi021VIt9LLWPlxMgcWlb6EWg8xw70PXISbUFy3IcxRi
+I14uAUXoFgIOT6jPt659kdXLNtYRsS3nQcBgJTIz6axHk2t5tD3TRf4xcLCyuVGv
+/obkTwpLr2jdPBxgTe+oDPjCnOyI6YeN0dKq4aiGBI/xECNpitbzmYQA2FQ+WvsG
+qq+1n/eAZAzAUWumxLna9ov1O0f6cY9d9hxWMTe2L4/a7B6KezF0CPnShFaC6pCV
+98aamE5QxBmSeQtmRdI75WFHJ1h0Vg==
+=0M4U
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256
new file mode 100644
index 0000000000..4f27f01046
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256
@@ -0,0 +1 @@
+10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256.asc
new file mode 100644
index 0000000000..825ed5de96
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT104Qf+NG6IUBLo7eTPtPzWyNs9bShrJR759atbY9kBOrRfyoBM/hWrcr6pG4e5
+BmBPULkuBWLVM+Ra52B2S96848oiaLLEuiWlMudWRsWCxyVknjm9EKlMHA3VdQtu
+8grrPKS4mIwSvdzAEEeqR+mwtWXHlz+jc/R9NeQhNmmcNZv1nkyzCuoNCH/HMTl4
+/ei6enpYrYNnMrNz9TOMQ67sCtZEm6TaxlqS+9h/V9TEnq6+1qXEt4c+AsqQdMWH
+3BZREzXHFocQciSEXfL6m07pnNlnvCcjsM2SAqTeTqQupEmqFGkhL2blE1VMdplW
+fDCC/ee5JYVyyUXpzydSjCYwFbO3NQ==
+=gSEv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512
new file mode 100644
index 0000000000..eb02a04a89
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512
@@ -0,0 +1 @@
+2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512.asc
new file mode 100644
index 0000000000..f35b726baf
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.jar.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3d+AgAwQvlwnKQLLuiZADGL+I922/YG317N2Re1EjC6WlMRZUKXH54fckRTyPm
+4ZLyxVHy8LlUD2Q10g69opb7HRd/tV0miBJhn5OU1wIM3hqTgxNp9EFckK4md45k
+osnhQJNDsFToxJL8zPP+KRs/aWPZs+FrRcH6k26lwLl2gTfyBDsaU11HFRVEN9yi
+X41obVyKiVNlc9efSSvlLtRBSVt0VhAFhck+3t61H6D9H09QxaDGAqmduDua3Tg3
+t5eqURuDfv3TfSztYgK3JBmG/6gVMsZodCgyC+8rhDDs6vSoDG30apx5Leg2rPbj
+xuk2wi/WNzc94IgY9tVS3tAfT2k6yQ==
+=6+Cv
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module
new file mode 100644
index 0000000000..23e5ef1229
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module
@@ -0,0 +1,101 @@
+{
+ "formatVersion": "1.1",
+ "component": {
+ "group": "org.springframework.example",
+ "module": "module-two",
+ "version": "1.0.0",
+ "attributes": {
+ "org.gradle.status": "release"
+ }
+ },
+ "createdBy": {
+ "gradle": {
+ "version": "6.5.1",
+ "buildId": "mvqepqsdqjcahjl7cii6b6ucoe"
+ }
+ },
+ "variants": [
+ {
+ "name": "apiElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.jvm.version": 8,
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-api"
+ },
+ "files": [
+ {
+ "name": "module-two-1.0.0.jar",
+ "url": "module-two-1.0.0.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "runtimeElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.jvm.version": 8,
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-two-1.0.0.jar",
+ "url": "module-two-1.0.0.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "javadocElements",
+ "attributes": {
+ "org.gradle.category": "documentation",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.docstype": "javadoc",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-two-1.0.0-javadoc.jar",
+ "url": "module-two-1.0.0-javadoc.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ },
+ {
+ "name": "sourcesElements",
+ "attributes": {
+ "org.gradle.category": "documentation",
+ "org.gradle.dependency.bundling": "external",
+ "org.gradle.docstype": "sources",
+ "org.gradle.usage": "java-runtime"
+ },
+ "files": [
+ {
+ "name": "module-two-1.0.0-sources.jar",
+ "url": "module-two-1.0.0-sources.jar",
+ "size": 261,
+ "sha512": "2730ac0859e1c2f450d54647c29ece43d095eb834e2130d4949dd1151317d013c072fa8f96f5f4b49836eff7c19a2eeeb5ca7483e5dac24c368bbcd522c27a00",
+ "sha256": "10ce8a82f7e53c67f2af8d4dc4b8cdb4d0630d0e1d21818da4d5b3ca2de08385",
+ "sha1": "8992b17455ce660da9c5fe47226b7ded9e872637",
+ "md5": "e84da489be91de821c95d41b8f0e0a0a"
+ }
+ ]
+ }
+ ]
+}
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc
new file mode 100644
index 0000000000..3cf7219f09
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT2SwAf/SDu2XlOfyL+oTidHItm3DmLsRY0xU2d5siCuasxxpzIPG+O5f3o7VeNS
+pKUctb+Vbx7Za+tPYts4ztG+bqVUVZbtn9ERWCXAvuuAnbJMxIl4D7HXahZPJKtl
+UrpKgA+45p2NLB9MK5B9QkmZInxF0ex3IUkc6e3MN8pmcefcjjDpoEvWKlc+ocEA
+/ySwMcH38FRYB6XbwsAjdXm7jiLpA9ZA5MdfZzjmm3nRBDzujBjU/Pv1+PFPH4Lh
+rfAS5+HOvWLQwt5kKyr8w3GzfbWT7FF7z024x0rT6mo0chOMe33Ng/AOYSGFzisJ
+OrJieiEosNjdcFbfuvspQFsI0cRU/A==
+=dgpO
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5
new file mode 100644
index 0000000000..ef64fa1aa5
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5
@@ -0,0 +1 @@
+9a7d415ecef034f2fd4a0b251055ec4b
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5.asc
new file mode 100644
index 0000000000..a31ae245d3
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT375Af+L1KawLLikLiiC6R2BCxufjcLHEzxh0RLjgDHpHXy8s/Bh5GgkTT4x/Hn
+gGJNT3Yz18rzpZaLnvNR/J9wOFEzLxRsgl1rumvTrrwhbIjac774oj3Z8Zv+W1T8
+KN1mtfUSLDZSRbmY0YByvPVtag1+FaIifxmIIFLny+xDzRVD1OZ38gOaxz91nqmd
+pgjR2eVmeYLX3oAIApVopYdKWXNwOMzdBQbNroPRKCOesmTqQi0sjuvgN7r5JoxN
+9vVzF1SFnAKnw/LQqL0KMrRzCBd+ncUk7A6D6RB0MM0V+TB9am9CsatxflRgQY+c
+vzu/BHY8k6lh44TECvAuNuSr01CkPA==
+=awJx
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1
new file mode 100644
index 0000000000..dc6c2e7bcd
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1
@@ -0,0 +1 @@
+9df95def633421b7415f807b0b5848c6975de806
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1.asc
new file mode 100644
index 0000000000..df2673f47c
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT1ubAgAtWXXzqRDIC+DhAaY3IfHyM/Dmlj58jLhTzta4xKQe9HykEjBlpkPSscp
+9R+O2aL4xfBUmKtVLORKoGN3oUPhdU8a5vfgI2itdDPWLkOfFE64OJtIOZKp4ST4
+i00Jsqd4GFryS3r+i5FL5MCCv+zG/OkylMIfcH1XVxynvwrJVY49Do+TmW4MOIFf
+4uDOd29XmEc8vCJBd3VZu0epHqcXhdiQy0ekdl3NdUimzRuXAckNhGNMoLWYhKaw
+voErlAtfDHMbYU1DebguEaiLi98N6IxX1aO0Lleg3JNveD7pLCjEEf7AW+7TYoz1
+QBvHABpVHzZ7Rg5VhZNIIrQ38zyZdg==
+=kz39
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256
new file mode 100644
index 0000000000..dc5ad08663
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256
@@ -0,0 +1 @@
+773b2d6350eb671af0b79328bd5334fba565f9041ca823fe7b55097dadf3dcf5
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256.asc
new file mode 100644
index 0000000000..2557a7a64e
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT3njggAl61MfkbtByxMKX8fQo5Jqp+vtvyZoaDZj+6FKr0xust5Wr4Fi+4+7fkj
+KyXFCTZUTd0xokRNpC8bxeZhhVkeG0pq6DrTr5BTvJLMJwPWVvrtn+bzDN1FvMia
+iZqcOlWtbwTdcosmBxXtxwI1gavwFhHUGudBzrBs85qkMkDz9BH8Egb+z/owFfPh
+lB9NSzezj4axgr745Ov5gYCwZp44iDBTcLZDWSLGMTuC6VdrLTQVsNLxouGI/67E
+0oqLmlaqfWZEJktTMk0LHG5ymy0g40Gm8r2kuxRnFEDVJwXSfJRiTvxifB+YoEHp
+RAcpReQe8+iSStuGEKYmfwmyXTdXAA==
+=759w
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512
new file mode 100644
index 0000000000..7e12e81cba
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512
@@ -0,0 +1 @@
+6294828fb9ce277d60e92c607d00b739e9266c3ebdca173fb32881c04f2d365d43bf9d77c0a07cf1dbcd09ad302f7458e938197f59ff5614a5d1d4e4146a0cf6
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512.asc
new file mode 100644
index 0000000000..5c37a34509
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.module.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT1H5wgAnmHJRXH+f1cZLlLKqMv7JMbuSFha3XsDPeL/XIEXmD9zj/R8IE7EKmpS
+uwkswZaOeIyc95J4FasxiZm5CExxzRSTQfXtK2lOl/7Gp84D+D6XXI28CUIRnOfo
+SeOyCFk2U3a6uTsRgi1FSnJRvLCs+0tB+bByKuVgGbfQdF0mtQ9rCxlqKKVa/dz6
+ertOXtz1A7fiLV44ovZG27GOciRJbogBmWfmNGPaQ+Ry8b8ICPf3SDdNSpp/nG2i
+YZxzIyX9xabzPGg7M1d4ClhrpJQRjJD1hJRIHCkwC8f8Y544iQ/MuAwd3hNIfjWP
+GJjgOl0iYjO8LPVaRdrHFkBUntVdHQ==
+=tlE4
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom
new file mode 100644
index 0000000000..520f492762
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ 4.0.0
+ org.springframework.example
+ module-two
+ 1.0.0
+ module-two
+ Example module
+ https://spring.io/projects/spring-boot
+
+ Pivotal Software, Inc.
+ https://spring.io
+
+
+
+ Apache License, Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
+
+
+ Pivotal
+ info@pivotal.io
+ Pivotal Software, Inc.
+ https://www.spring.io
+
+
+
+
+ scm:git:git://github.com/spring-projects/spring-boot.git
+
+
+ scm:git:ssh://git@github.com/spring-projects/spring-boot.git
+
+ https://github.com/spring-projects/spring-boot
+
+
+ GitHub
+
+ https://github.com/spring-projects/spring-boot/issues
+
+
+
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc
new file mode 100644
index 0000000000..f3703ea391
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT2kvAgAoc2k0ljj7L3Pj4rPz73K1SO3pDHdf+6S6pU7E4ao9FEFZBcB7YJjEmmQ
+U724HqU15PIkaJKI/v4Z612E1gMSMIQ8A0LnsFR9yQdvrsK1Ijv+CdPCdyvZsBfP
+3MgmWaRUOToK3BAAVV5y0dfUNFUyeKKxHNclJd6H0HUK02of8I7LBn/5ULK4QRaQ
+Lm3bUIT3PtjUfND+DK3QlczZ+YgOkIwTkLywYCYxblm9XJjWCRXaZI1MdUlA6SMs
+uEqtglQ9zEJgyue/JtWsIkAlzUbdyjo34Cg5HEZJ6RNzboXlRNFm83fcKyPhSy7V
+0xikP1INbKuZSU1ZE7/rRYIQ7ChK0g==
+=96NH
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5
new file mode 100644
index 0000000000..463446fec9
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5
@@ -0,0 +1 @@
+057258909d16c0f9ed33c8a83e4ef165
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5.asc
new file mode 100644
index 0000000000..df9d49af1f
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.md5.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT1eXQgAhIYkhiSoV4lFMPT9GuN4OjkoQC+v9ev8HkmIdq8lpoB+StIYzI35hKLU
+kfm5d2aeVo7ifDdXh642p9oEXRfuDPfaLd9u8SZZBAdo4rolQZr4bl+JaUFzR79i
+nRozXQeJF1UrDUKMi0+YGQxlosTbdx7Romj2UdfEmL2ACetxxR3rQExgZl4O/OUm
+PHJtIrzO1xdbVxtKelILJ4D/PauqEqcqzC2gI5vObZJcRgxDU/wc2CVN9jruv07h
+UW+8IEFV8vexoHo+Kq/F9xaTW2b7oXnvfOJgWRbh3zGpxSluJwVINDyX39/ym/Dr
+FIO6BPWFKQPEUW2cY6C69jj7S+v8Ig==
+=PYoG
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1
new file mode 100644
index 0000000000..2b3f269aad
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1
@@ -0,0 +1 @@
+1a742c42aef877b6a2808a1b5c35fbe3189ce274
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1.asc
new file mode 100644
index 0000000000..ea7c57f9c6
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha1.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEyBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT0bmAf4+WOg0xkoyRDXf/1hFOXlimKqyF1K7I6PXx1dFokRr+tvOtfFZucCOf+f
+1hCvnBiPTQwwMPCgll0reTsH2nHfDVUcbugpxVDC3Yza0x3gHudBhPC7yv+osNIu
+sVlnMRYbG1RQGjE6BxHoBk9pdOcwgN7zk2Y4LfAbOKMTo7dhAjZavRx3aShEUwHy
+P9/kfxcWCL0tOSzWg5XpZuxFEdVMWNJvshFvP0j2/Nlr6ZL5o/AwtyZKMiZ8QcUb
+0satLj501JYI6pM2cm8N17T94+jCsQXZic/hUCNteXA4XbRcDBR2wQLd08/Ht0U4
+rHzZQNr5Ft5R5ScshTEVBwjcd/Kx
+=drUj
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256
new file mode 100644
index 0000000000..334afc1450
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256
@@ -0,0 +1 @@
+7e855e618d4aba3eb4e63bbfc9960e4da319d8bdef0cca213a11e9b2d1991635
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256.asc
new file mode 100644
index 0000000000..433766e660
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha256.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1oACgkQmix6mORX
+xT3w3QgAvHS75cBMEEZGWiCQ+lbwDMWY7rjQBwkpO1Sj6WxpKcWD2F4YmNni1z1k
+L71SDuLP0a+IbYcoDCkss7vxH6hx6Lm53e+2WwhaVGCO1A6N3a56rFyEFlATrn31
+mcRjLrN4wzysqqbeamzSt+R0UoWj7yiihtBuz7tkhjGP+df2qCrXNeuetrhukFOz
+P5RLd4PURYMMUMqqNZ8JNnRhdCVdSVUpfM+BDolNDaswDrvOI3jzjXD/6HCt0fcN
+Pt484kFDqGEx0iXvv+7shiExs31gex+fsn2ta9yOGYluF/8Rc4z+X0/59MewoCgC
+EelPT4oi4zirrIWzGp1bRF+jDi6feA==
+=stbf
+-----END PGP SIGNATURE-----
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512 b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512
new file mode 100644
index 0000000000..e7b24fdd95
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512
@@ -0,0 +1 @@
+5b06587734aa146b452e78e34abffb38b8c820abf623975409ae003b5d90aded345fa8f92ed9d7a505a16db324c0649d2e16c7597bad8dc63f0a5c00123789e1
\ No newline at end of file
diff --git a/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512.asc b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512.asc
new file mode 100644
index 0000000000..d8d2cc73e3
--- /dev/null
+++ b/ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/sonatype/artifactory-repo/org/springframework/example/module-two/1.0.0/module-two-1.0.0.pom.sha512.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQEzBAABCAAdFiEE4qywN5M83qq3v3fUmix6mORXxT0FAmAiY1sACgkQmix6mORX
+xT3p3QgAp5doWrX6eMPD1I09NHMt29LI8wFa/xld7rof8OQLHDN55TLseqOvBU4V
+E82s5cm4Uk0ndnth/VUHqsJK6SsNX8/0N2bvOtWgUWBYdClcy6ZBWXjQIDFfCdqX
+LPqQN4nOT3ZZMrzTZhLsAJkbzvVaOzEtUYZWw1ZAIT8nPkud24stuuxKUtsAxfeD
+QqcgKng/sPx6DS2+NSmmzyCF9eSL70NBcBF6+RJ+4X0YtZRtX+wsic2MnKnVAnyX
+hPejxguJYhwWbn1yRdVWknCdffpiT09IC/7AS/yc8s1DdbS6XEae8uFl0OB5z5dx
+nnaHUvlFrAjDGsrYeW5h1ZkM8VwBxA==
+=2HWi
+-----END PGP SIGNATURE-----
diff --git a/ci/parameters.yml b/ci/parameters.yml
index 752d69b9b8..5dd91782ba 100644
--- a/ci/parameters.yml
+++ b/ci/parameters.yml
@@ -10,6 +10,4 @@ branch: "2.3.x"
milestone: "2.3.x"
build-name: "spring-boot"
concourse-url: "https://ci.spring.io"
-bintray-subject: "spring"
-bintray-repo: "jars"
task-timeout: 2h00m
diff --git a/ci/pipeline.yml b/ci/pipeline.yml
index b87a56276e..221472ccbe 100644
--- a/ci/pipeline.yml
+++ b/ci/pipeline.yml
@@ -21,14 +21,11 @@ anchors:
GITHUB_PASSWORD: ((github-ci-release-token))
GITHUB_USERNAME: ((github-username))
MILESTONE: ((milestone))
- bintray-task-params: &bintray-task-params
- BINTRAY_SUBJECT: ((bintray-subject))
- BINTRAY_REPO: ((bintray-repo))
- BINTRAY_USERNAME: ((bintray-username))
- BINTRAY_API_KEY: ((bintray-api-key))
sontatype-task-params: &sonatype-task-params
SONATYPE_USER_TOKEN: ((sonatype-user-token))
SONATYPE_PASSWORD_TOKEN: ((sonatype-user-token-password))
+ SONATYPE_URL: ((sonatype-url))
+ SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
artifactory-task-params: &artifactory-task-params
ARTIFACTORY_SERVER: ((artifactory-server))
ARTIFACTORY_USERNAME: ((artifactory-username))
@@ -571,7 +568,7 @@ jobs:
trigger: false
passed: [stage-release]
params:
- download_artifacts: false
+ download_artifacts: true
save_build_info: true
- task: promote
image: ci-image
@@ -579,8 +576,8 @@ jobs:
params:
RELEASE_TYPE: RELEASE
<<: *artifactory-task-params
- <<: *bintray-task-params
-- name: sync-to-maven-central
+ <<: *sonatype-task-params
+- name: create-github-release
serial: true
plan:
- get: ci-image
@@ -591,12 +588,6 @@ jobs:
params:
download_artifacts: false
save_build_info: true
- - task: sync-to-maven-central
- image: ci-image
- file: git-repo/ci/tasks/sync-to-maven-central.yml
- params:
- <<: *bintray-task-params
- <<: *sonatype-task-params
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
@@ -614,7 +605,7 @@ jobs:
- get: ci-image
- get: git-repo
- get: artifactory-repo
- passed: [sync-to-maven-central]
+ passed: [create-github-release]
params:
download_artifacts: false
save_build_info: true
@@ -633,7 +624,7 @@ jobs:
- get: git-repo
resource: homebrew-tap-repo
- get: artifactory-repo
- passed: [sync-to-maven-central]
+ passed: [create-github-release]
params:
download_artifacts: false
save_build_info: true
@@ -650,7 +641,7 @@ groups:
- name: "builds"
jobs: ["build", "jdk11-build", "jdk15-build", "windows-build"]
- name: "releases"
- jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "sync-to-maven-central", "publish-to-sdkman", "update-homebrew-tap"]
+ jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release", "publish-to-sdkman", "update-homebrew-tap"]
- name: "ci-images"
jobs: ["build-ci-images", "detect-docker-updates", "detect-jdk-updates", "detect-ubuntu-image-updates"]
- name: "pull-requests"
diff --git a/ci/scripts/promote.sh b/ci/scripts/promote.sh
index cff0f3e86b..14ad9861e6 100755
--- a/ci/scripts/promote.sh
+++ b/ci/scripts/promote.sh
@@ -5,11 +5,9 @@ source $(dirname $0)/common.sh
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
-java -jar /spring-boot-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
-
-java -jar /spring-boot-release-scripts.jar distribute $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
+java -jar /spring-boot-release-scripts.jar publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
-java -jar /spring-boot-release-scripts.jar publishGradlePlugin $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
+java -jar /spring-boot-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
echo "Promotion complete"
echo $version > version/version
diff --git a/ci/scripts/sync-to-maven-central.sh b/ci/scripts/sync-to-maven-central.sh
deleted file mode 100755
index 32e882b5d4..0000000000
--- a/ci/scripts/sync-to-maven-central.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
-version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
-java -jar /spring-boot-release-scripts.jar syncToCentral "RELEASE" $BUILD_INFO_LOCATION || { exit 1; }
-
-echo "Sync complete"
-echo $version > version/version
diff --git a/ci/tasks/promote.yml b/ci/tasks/promote.yml
index 68821a052c..2e5f9d36b6 100644
--- a/ci/tasks/promote.yml
+++ b/ci/tasks/promote.yml
@@ -10,9 +10,8 @@ params:
ARTIFACTORY_SERVER:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:
- BINTRAY_SUBJECT:
- BINTRAY_REPO:
- BINTRAY_USERNAME:
- BINTRAY_API_KEY:
+ SONATYPE_USER_TOKEN:
+ SONATYPE_PASSWORD_TOKEN:
+ SONATYPE_STAGING_PROFILE_ID:
run:
path: git-repo/ci/scripts/promote.sh
diff --git a/ci/tasks/sync-to-maven-central.yml b/ci/tasks/sync-to-maven-central.yml
deleted file mode 100644
index a44af5af16..0000000000
--- a/ci/tasks/sync-to-maven-central.yml
+++ /dev/null
@@ -1,16 +0,0 @@
----
-platform: linux
-inputs:
-- name: git-repo
-- name: artifactory-repo
-outputs:
-- name: version
-params:
- BINTRAY_REPO:
- BINTRAY_SUBJECT:
- BINTRAY_USERNAME:
- BINTRAY_API_KEY:
- SONATYPE_USER_TOKEN:
- SONATYPE_PASSWORD_TOKEN:
-run:
- path: git-repo/ci/scripts/sync-to-maven-central.sh