Skip to content

Commit b77dbcd

Browse files
committed
Allow certain artifacts to be optionally deployed
Update `DistributeCommand` so that regex patterns can be used to mark artifacts that are optional and need not fail the release. Closes gh-22543
1 parent d69c35a commit b77dbcd

File tree

5 files changed

+153
-4
lines changed

5 files changed

+153
-4
lines changed

ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeCommand.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.nio.file.Files;
2121
import java.util.List;
2222
import java.util.Set;
23+
import java.util.regex.Pattern;
24+
import java.util.stream.Collectors;
2325

2426
import com.fasterxml.jackson.databind.ObjectMapper;
2527
import io.spring.concourse.releasescripts.ReleaseInfo;
@@ -40,6 +42,7 @@
4042
* Command used to deploy builds from Artifactory to Bintray.
4143
*
4244
* @author Madhura Bhave
45+
* @author Phillip Webb
4346
*/
4447
@Component
4548
public class DistributeCommand implements Command {
@@ -50,9 +53,14 @@ public class DistributeCommand implements Command {
5053

5154
private final ObjectMapper objectMapper;
5255

53-
public DistributeCommand(ArtifactoryService artifactoryService, ObjectMapper objectMapper) {
56+
private final List<Pattern> optionalDeployments;
57+
58+
public DistributeCommand(ArtifactoryService artifactoryService, ObjectMapper objectMapper,
59+
DistributeProperties distributeProperties) {
5460
this.artifactoryService = artifactoryService;
5561
this.objectMapper = objectMapper;
62+
this.optionalDeployments = distributeProperties.getOptionalDeployments().stream().map(Pattern::compile)
63+
.collect(Collectors.toList());
5664
}
5765

5866
@Override
@@ -80,8 +88,18 @@ public void run(ApplicationArguments args) throws Exception {
8088
}
8189
}
8290
ReleaseInfo releaseInfo = ReleaseInfo.from(buildInfo);
83-
Set<String> artifactDigests = buildInfo.getArtifactDigests((artifact) -> !artifact.getName().endsWith(".zip"));
91+
Set<String> artifactDigests = buildInfo.getArtifactDigests(this::isIncluded);
8492
this.artifactoryService.distribute(type.getRepo(), releaseInfo, artifactDigests);
8593
}
8694

95+
private boolean isIncluded(Artifact artifact) {
96+
String path = artifact.getName();
97+
for (Pattern optionalDeployment : this.optionalDeployments) {
98+
if (optionalDeployment.matcher(path).matches()) {
99+
return false;
100+
}
101+
}
102+
return true;
103+
}
104+
87105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.concourse.releasescripts.command;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import org.springframework.boot.context.properties.ConfigurationProperties;
23+
24+
/**
25+
* Distribution properties.
26+
*
27+
* @author Phillip Webb
28+
*/
29+
@ConfigurationProperties(prefix = "distribute")
30+
public class DistributeProperties {
31+
32+
private List<String> optionalDeployments = new ArrayList<>();
33+
34+
public List<String> getOptionalDeployments() {
35+
return this.optionalDeployments;
36+
}
37+
38+
public void setOptionalDeployments(List<String> optionalDeployments) {
39+
this.optionalDeployments = optionalDeployments;
40+
}
41+
42+
}

ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/DistributeCommandTests.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package io.spring.concourse.releasescripts.command;
1818

19+
import java.util.Arrays;
1920
import java.util.Set;
2021

2122
import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -42,6 +43,7 @@
4243
* Tests for {@link DistributeCommand}.
4344
*
4445
* @author Madhura Bhave
46+
* @author Phillip Webb
4547
*/
4648
class DistributeCommandTests {
4749

@@ -55,8 +57,10 @@ class DistributeCommandTests {
5557
@BeforeEach
5658
void setup() {
5759
MockitoAnnotations.initMocks(this);
60+
DistributeProperties distributeProperties = new DistributeProperties();
61+
distributeProperties.setOptionalDeployments(Arrays.asList(".*\\.zip", "demo-\\d\\.\\d\\.\\d\\.doc"));
5862
this.objectMapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
59-
this.command = new DistributeCommand(this.service, this.objectMapper);
63+
this.command = new DistributeCommand(this.service, this.objectMapper, distributeProperties);
6064
}
6165

6266
@Test
@@ -94,8 +98,30 @@ void distributeWhenReleaseTypeReleaseShouldCallService() throws Exception {
9498
assertThat(artifactDigests).containsExactly("aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy");
9599
}
96100

101+
@Test
102+
@SuppressWarnings("unchecked")
103+
void distributeWhenReleaseTypeReleaseAndFilteredShouldCallService() throws Exception {
104+
ArgumentCaptor<ReleaseInfo> releaseInfoCaptor = ArgumentCaptor.forClass(ReleaseInfo.class);
105+
ArgumentCaptor<Set<String>> artifactDigestCaptor = ArgumentCaptor.forClass(Set.class);
106+
this.command.run(new DefaultApplicationArguments("distribute", "RELEASE",
107+
getBuildInfoLocation("filtered-build-info-response.json")));
108+
verify(this.service).distribute(eq(ReleaseType.RELEASE.getRepo()), releaseInfoCaptor.capture(),
109+
artifactDigestCaptor.capture());
110+
ReleaseInfo releaseInfo = releaseInfoCaptor.getValue();
111+
assertThat(releaseInfo.getBuildName()).isEqualTo("example");
112+
assertThat(releaseInfo.getBuildNumber()).isEqualTo("example-build-1");
113+
assertThat(releaseInfo.getGroupId()).isEqualTo("org.example.demo");
114+
assertThat(releaseInfo.getVersion()).isEqualTo("2.2.0");
115+
Set<String> artifactDigests = artifactDigestCaptor.getValue();
116+
assertThat(artifactDigests).containsExactly("aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy");
117+
}
118+
97119
private String getBuildInfoLocation() throws Exception {
98-
return new ClassPathResource("build-info-response.json", ArtifactoryService.class).getFile().getAbsolutePath();
120+
return getBuildInfoLocation("build-info-response.json");
121+
}
122+
123+
private String getBuildInfoLocation(String file) throws Exception {
124+
return new ClassPathResource(file, ArtifactoryService.class).getFile().getAbsolutePath();
99125
}
100126

101127
}

ci/images/releasescripts/src/test/resources/application.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ bintray:
99
sonatype:
1010
user-token: sonatype-user
1111
password-token: sonatype-password
12+
distribute:
13+
optional-deployments:
14+
- '.*\.zip'
15+
- 'spring-boot-project-\d\.\d\.\d(?:\.RELEASE)?\.pom'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"buildInfo": {
3+
"version": "1.0.1",
4+
"name": "example",
5+
"number": "example-build-1",
6+
"started": "2019-09-10T12:18:05.430+0000",
7+
"durationMillis": 0,
8+
"artifactoryPrincipal": "user",
9+
"url": "https://my-ci.com",
10+
"modules": [
11+
{
12+
"id": "org.example.demo:demo:2.2.0",
13+
"artifacts": [
14+
{
15+
"type": "jar",
16+
"sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaaa",
17+
"sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy",
18+
"md5": "aaaaaacddea1724b0b69d8yyyyyyy",
19+
"name": "demo-2.2.0.jar"
20+
}
21+
]
22+
},
23+
{
24+
"id": "org.example.demo:demo:2.2.0:zip",
25+
"artifacts": [
26+
{
27+
"type": "zip",
28+
"sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaab",
29+
"sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyz",
30+
"md5": "aaaaaacddea1724b0b69d8yyyyyyz",
31+
"name": "demo-2.2.0.zip"
32+
}
33+
]
34+
},
35+
{
36+
"id": "org.example.demo:demo:2.2.0:doc",
37+
"artifacts": [
38+
{
39+
"type": "jar",
40+
"sha1": "ayyyya9151a22cb3145538e523dbbaaaaaaba",
41+
"sha256": "aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyzy",
42+
"md5": "aaaaaacddea1724b0b69d8yyyyyzy",
43+
"name": "demo-2.2.0.doc"
44+
}
45+
]
46+
}
47+
],
48+
"statuses": [
49+
{
50+
"status": "staged",
51+
"repository": "libs-release-local",
52+
"timestamp": "2019-09-10T12:42:24.716+0000",
53+
"user": "user",
54+
"timestampDate": 1568119344716
55+
}
56+
]
57+
},
58+
"uri": "https://my-artifactory-repo.com/api/build/example/example-build-1"
59+
}

0 commit comments

Comments
 (0)