Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
e137e3d1
Commit
e137e3d1
authored
Jul 24, 2020
by
Phillip Webb
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.1.x' into 2.2.x
parents
9c5e5937
f68671e1
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
167 additions
and
25 deletions
+167
-25
BintrayService.java
...ring/concourse/releasescripts/bintray/BintrayService.java
+7
-2
DistributeCommand.java
...g/concourse/releasescripts/command/DistributeCommand.java
+20
-2
DistributeProperties.java
...oncourse/releasescripts/command/DistributeProperties.java
+42
-0
application.properties
.../releasescripts/src/main/resources/application.properties
+3
-1
ArtifactoryServiceTests.java
...e/releasescripts/artifactory/ArtifactoryServiceTests.java
+8
-18
DistributeCommandTests.java
...course/releasescripts/command/DistributeCommandTests.java
+28
-2
filtered-build-info-response.json
...easescripts/artifactory/filtered-build-info-response.json
+59
-0
No files found.
ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayService.java
View file @
e137e3d1
...
...
@@ -101,8 +101,13 @@ public class BintrayService {
try
{
waitAtMost
(
timeout
).
with
().
pollDelay
(
Duration
.
ZERO
).
pollInterval
(
pollInterval
).
until
(()
->
{
logger
.
debug
(
"Checking bintray"
);
PackageFile
[]
published
=
this
.
restTemplate
.
exchange
(
request
,
PackageFile
[].
class
).
getBody
();
return
hasPublishedAll
(
published
,
requiredDigests
);
try
{
PackageFile
[]
published
=
this
.
restTemplate
.
exchange
(
request
,
PackageFile
[].
class
).
getBody
();
return
hasPublishedAll
(
published
,
requiredDigests
);
}
catch
(
HttpClientErrorException
.
NotFound
ex
)
{
return
false
;
}
});
}
catch
(
ConditionTimeoutException
ex
)
{
...
...
ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeCommand.java
View file @
e137e3d1
...
...
@@ -20,6 +20,8 @@ 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
;
...
...
@@ -40,6 +42,7 @@ 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
{
...
...
@@ -50,9 +53,14 @@ public class DistributeCommand implements Command {
private
final
ObjectMapper
objectMapper
;
public
DistributeCommand
(
ArtifactoryService
artifactoryService
,
ObjectMapper
objectMapper
)
{
private
final
List
<
Pattern
>
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
...
...
@@ -80,8 +88,18 @@ public class DistributeCommand implements Command {
}
}
ReleaseInfo
releaseInfo
=
ReleaseInfo
.
from
(
buildInfo
);
Set
<
String
>
artifactDigests
=
buildInfo
.
getArtifactDigests
(
(
artifact
)
->
!
artifact
.
getName
().
endsWith
(
".zip"
)
);
Set
<
String
>
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
;
}
}
ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/command/DistributeProperties.java
0 → 100644
View file @
e137e3d1
/*
* Copyright 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
<
String
>
optionalDeployments
=
new
ArrayList
<>();
public
List
<
String
>
getOptionalDeployments
()
{
return
this
.
optionalDeployments
;
}
public
void
setOptionalDeployments
(
List
<
String
>
optionalDeployments
)
{
this
.
optionalDeployments
=
optionalDeployments
;
}
}
ci/images/releasescripts/src/main/resources/application.properties
View file @
e137e3d1
spring.main.banner-mode
=
off
#
logging.level.io.spring.concourse
=
DEBUG
\ No newline at end of file
distribute.optional-deployments[0]=.*\\.zip
distribute.optional-deployments[1]=spring-boot-project-\\d+\\.\\d+\\.\\d+(?:\\.RELEASE)?\\.pom
logging.level.io.spring.concourse
=
DEBUG
\ No newline at end of file
ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/artifactory/ArtifactoryServiceTests.java
View file @
e137e3d1
...
...
@@ -84,9 +84,7 @@ class ArtifactoryServiceTests {
@Test
void
promoteWhenSuccessful
()
{
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/"
+
"example-build"
+
"/"
+
"example-build-1"
))
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/example-build/example-build-1"
))
.
andExpect
(
method
(
HttpMethod
.
POST
))
.
andExpect
(
content
().
json
(
"{\"status\": \"staged\", \"sourceRepo\": \"libs-staging-local\", \"targetRepo\": \"libs-milestone-local\"}"
))
...
...
@@ -99,11 +97,9 @@ class ArtifactoryServiceTests {
@Test
void
promoteWhenArtifactsAlreadyPromoted
()
{
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/"
+
"example-build"
+
"/"
+
"example-build-1"
))
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/example-build/example-build-1"
))
.
andRespond
(
withStatus
(
HttpStatus
.
CONFLICT
));
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/
"
+
"example-build"
+
"/"
+
"
example-build-1"
))
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/
example-build/
example-build-1"
))
.
andRespond
(
withJsonFrom
(
"build-info-response.json"
));
this
.
service
.
promote
(
"libs-release-local"
,
getReleaseInfo
());
this
.
server
.
verify
();
...
...
@@ -111,11 +107,9 @@ class ArtifactoryServiceTests {
@Test
void
promoteWhenCheckForArtifactsAlreadyPromotedFails
()
{
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/"
+
"example-build"
+
"/"
+
"example-build-1"
))
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/example-build/example-build-1"
))
.
andRespond
(
withStatus
(
HttpStatus
.
CONFLICT
));
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/
"
+
"example-build"
+
"/"
+
"
example-build-1"
))
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/
example-build/
example-build-1"
))
.
andRespond
(
withStatus
(
HttpStatus
.
FORBIDDEN
));
assertThatExceptionOfType
(
HttpClientErrorException
.
class
)
.
isThrownBy
(()
->
this
.
service
.
promote
(
"libs-release-local"
,
getReleaseInfo
()));
...
...
@@ -124,11 +118,9 @@ class ArtifactoryServiceTests {
@Test
void
promoteWhenPromotionFails
()
{
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/"
+
"example-build"
+
"/"
+
"example-build-1"
))
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/promote/example-build/example-build-1"
))
.
andRespond
(
withStatus
(
HttpStatus
.
CONFLICT
));
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/
"
+
"example-build"
+
"/"
+
"
example-build-1"
))
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/
example-build/
example-build-1"
))
.
andRespond
(
withJsonFrom
(
"staged-build-info-response.json"
));
assertThatExceptionOfType
(
HttpClientErrorException
.
class
)
.
isThrownBy
(()
->
this
.
service
.
promote
(
"libs-release-local"
,
getReleaseInfo
()));
...
...
@@ -158,9 +150,7 @@ class ArtifactoryServiceTests {
@Test
void
distributeWhenFailure
()
throws
Exception
{
ReleaseInfo
releaseInfo
=
getReleaseInfo
();
this
.
server
.
expect
(
requestTo
(
"https://repo.spring.io/api/build/distribute/"
+
"example-build"
+
"/"
+
"example-build-1"
))
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\"}"
))
...
...
ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/command/DistributeCommandTests.java
View file @
e137e3d1
...
...
@@ -16,6 +16,7 @@
package
io
.
spring
.
concourse
.
releasescripts
.
command
;
import
java.util.Arrays
;
import
java.util.Set
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
...
...
@@ -42,6 +43,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
* Tests for {@link DistributeCommand}.
*
* @author Madhura Bhave
* @author Phillip Webb
*/
class
DistributeCommandTests
{
...
...
@@ -55,8 +57,10 @@ class DistributeCommandTests {
@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
);
this
.
command
=
new
DistributeCommand
(
this
.
service
,
this
.
objectMapper
,
distributeProperties
);
}
@Test
...
...
@@ -94,8 +98,30 @@ class DistributeCommandTests {
assertThat
(
artifactDigests
).
containsExactly
(
"aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy"
);
}
@Test
@SuppressWarnings
(
"unchecked"
)
void
distributeWhenReleaseTypeReleaseAndFilteredShouldCallService
()
throws
Exception
{
ArgumentCaptor
<
ReleaseInfo
>
releaseInfoCaptor
=
ArgumentCaptor
.
forClass
(
ReleaseInfo
.
class
);
ArgumentCaptor
<
Set
<
String
>>
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
<
String
>
artifactDigests
=
artifactDigestCaptor
.
getValue
();
assertThat
(
artifactDigests
).
containsExactly
(
"aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyy"
);
}
private
String
getBuildInfoLocation
()
throws
Exception
{
return
new
ClassPathResource
(
"build-info-response.json"
,
ArtifactoryService
.
class
).
getFile
().
getAbsolutePath
();
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
ci/images/releasescripts/src/test/resources/io/spring/concourse/releasescripts/artifactory/filtered-build-info-response.json
0 → 100644
View file @
e137e3d1
{
"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"
}
]
},
{
"id"
:
"org.example.demo:demo:2.2.0:zip"
,
"artifacts"
:
[
{
"type"
:
"zip"
,
"sha1"
:
"ayyyya9151a22cb3145538e523dbbaaaaaaab"
,
"sha256"
:
"aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyyz"
,
"md5"
:
"aaaaaacddea1724b0b69d8yyyyyyz"
,
"name"
:
"demo-2.2.0.zip"
}
]
},
{
"id"
:
"org.example.demo:demo:2.2.0:doc"
,
"artifacts"
:
[
{
"type"
:
"jar"
,
"sha1"
:
"ayyyya9151a22cb3145538e523dbbaaaaaaba"
,
"sha256"
:
"aaaaaaaaa85f5c5093721f3ed0edda8ff8290yyyyyyyyzy"
,
"md5"
:
"aaaaaacddea1724b0b69d8yyyyyzy"
,
"name"
:
"demo-2.2.0.doc"
}
]
}
],
"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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment