Compare commits

...

549 Commits
2.4.3 ... main

Author SHA1 Message Date
Marcus Da Coregio
94e7fb859d Merge branch '3.0.x' 2023-04-06 14:02:34 -03:00
Marcus Da Coregio
f8c1fdb250 Fix javaconfig-rest sample dependency 2023-04-06 14:02:12 -03:00
Marcus Da Coregio
07b1982690 Revert "Remove spring-session-sample-javaconfig-rest"
This reverts commit b229103d8c.

Closes gh-2259
2023-04-06 14:02:12 -03:00
Yanming Zhou
588586142c Reuse StringRedisSerializer instance 2023-04-05 11:02:35 -03:00
Marcus Da Coregio
3ead79340b Merge branch '3.0.x' 2023-03-22 16:09:10 -03:00
Marcus Da Coregio
dfc331aae7 Merge branch '2.7.x' into 3.0.x 2023-03-22 16:06:02 -03:00
Jerome Prinet
51ca6c329e Update Gradle Enterprise plugins 2023-03-22 16:02:42 -03:00
Marcus Da Coregio
9aebb69d66 Next Development Version 2023-03-21 15:18:18 -03:00
Marcus Da Coregio
6f1c039665 Release 3.1.0-M1 2023-03-21 14:40:02 -03:00
Marcus Da Coregio
8015f19f5e Update to reactor-bom:2022.0.5
Closes gh-2272
2023-03-21 14:26:38 -03:00
Marcus Da Coregio
25055b05c9 Update to jackson-bom:2.14.2
Closes gh-2273
2023-03-21 14:26:22 -03:00
Marcus Da Coregio
08d11b7ba0 Update to org.springframework:spring-framework-bom:6.0.7
Closes gh-2274
2023-03-21 14:25:56 -03:00
Marcus Da Coregio
f1ea897e3d Update to spring-data-bom:2022.0.4
Closes gh-2275
2023-03-21 14:25:38 -03:00
Marcus Da Coregio
4cb2ff3ca4 Update to spring-security-bom:6.0.2
Closes gh-2276
2023-03-21 14:25:20 -03:00
Marcus Da Coregio
1b4d58711e Update to testcontainers-bom:1.17.6
Closes gh-2277
2023-03-21 14:25:01 -03:00
Marcus Da Coregio
f9dbd1a0ce Merge branch '3.0.x' 2023-03-21 14:18:48 -03:00
Marcus Da Coregio
6649205bb7 Merge branch '2.7.x' into 3.0.x 2023-03-21 14:18:02 -03:00
Marcus Da Coregio
220304faad Next Development Version 2023-03-21 11:02:13 -03:00
Marcus Da Coregio
bd81ee5a49 Next Development Version 2023-03-21 10:59:24 -03:00
Marcus Da Coregio
37d1f68766 Release 3.0.1 2023-03-21 10:33:18 -03:00
Marcus Da Coregio
d2fe7d0e74 Update org.mongodb to 4.8.2
Closes gh-2271
2023-03-21 10:32:44 -03:00
Marcus Da Coregio
380dae16d2 Update to spring-security-bom:6.0.2
Closes gh-2270
2023-03-21 10:32:37 -03:00
Marcus Da Coregio
6aa71d45f9 Update to spring-data-bom:2022.0.3
Closes gh-2269
2023-03-21 10:32:28 -03:00
Marcus Da Coregio
635a6d4dd6 Update to spring-framework-bom:6.0.6
Closes gh-2268
2023-03-21 10:32:16 -03:00
Marcus Da Coregio
a69d53c17f Update to junit-bom:5.9.2
Closes gh-2267
2023-03-21 10:32:10 -03:00
Marcus Da Coregio
0afc216d21 Update to jackson-bom:2.14.2
Closes gh-2266
2023-03-21 10:32:02 -03:00
Marcus Da Coregio
801a0057fd Update reactor-bom to 2022.0.5
Closes gh-2265
2023-03-21 10:29:14 -03:00
Marcus Da Coregio
ec6fd8a902 Release 2.7.1 2023-03-21 09:58:55 -03:00
Marcus Da Coregio
0320e60cf0 Update spring-security-bom to 5.7.7
Closes gh-2264
2023-03-21 09:55:04 -03:00
Marcus Da Coregio
90d0c1d778 Update spring-data-bom to 2021.2.9
Closes gh-2263
2023-03-21 09:55:04 -03:00
Marcus Da Coregio
058ae80419 Update spring-framework-bom to 5.3.26
Closes gh-2262
2023-03-21 09:55:04 -03:00
Marcus Da Coregio
89fb210f18 Update reactor-bom to 2020.0.30
Closes gh-2260
2023-03-21 09:55:04 -03:00
Marcus Da Coregio
cf84ac7ec9 Introduce Utility Method to Replace Default Table Name
Closes gh-2256
2023-03-15 12:02:44 -03:00
Marcus Da Coregio
ae05044c46 Next Development Version 2023-03-08 15:53:40 -03:00
Marcus Da Coregio
7d1b01daf6 Update Antora Plugin to 1.0.0
Issue gh-2234
2023-03-06 14:43:21 -03:00
Marcus Da Coregio
d7d36846a1 Merge branch '2.7.x' 2023-03-06 14:23:39 -03:00
Marcus Da Coregio
d48aa09b9c Update to mariadb-java-client 2.7.8
Closes gh-2255
2023-03-06 13:58:02 -03:00
Marcus Da Coregio
02a6dbc08a Revert "Update to mariadb-java-client 3.0.10"
This reverts commit acb59258
2023-03-06 13:55:08 -03:00
Marcus Da Coregio
e4a023fa64 Revert "Update Antora Plugin to 1.0.0"
This reverts commit 280f311677.
2023-03-06 13:52:52 -03:00
Rob Winch
1e10dfe1a3 Merge remote-tracking branch 'origin/2.7.x' 2023-02-21 17:23:51 -06:00
Rob Winch
e8837c83e9 Next Development Version 2023-02-21 17:21:56 -06:00
Rob Winch
b4b9ea8112 Release 2.7.1 2023-02-21 17:21:18 -06:00
Rob Winch
c571f7479c Update to org.postgresql:postgresql:42.3.8
Closes gh-2250
2023-02-21 17:13:06 -06:00
Rob Winch
63d7580a69 Update to MongoDB 4.6.1
Closes gh-2249
2023-02-21 17:12:19 -06:00
Rob Winch
c466aa5dd3 Update to Mockito 4.5.1
Closes gh-2248
2023-02-21 17:11:33 -06:00
Rob Winch
acb59258c3 Update to mariadb-java-client 3.0.10
Closes gh-2247
2023-02-21 17:10:44 -06:00
Rob Winch
e5022757a9 Update to mysql-connector-java 8.0.32
Closes gh-2246
2023-02-21 17:09:49 -06:00
Rob Winch
ddad8010eb Update to lettuce 6.1.10.RELEASE
Closes gh-2245
2023-02-21 17:09:01 -06:00
Rob Winch
fc3e2e1c64 Update to HikariCP:4.0.3
Closes gh-2244
2023-02-21 17:08:18 -06:00
Rob Winch
eb169f8186 Update to com.ibm.db2:jcc:11.5.8.0
Closes gh-2243
2023-02-21 17:07:23 -06:00
Rob Winch
5fd7c9ddcf Update to testcontainers 1.17.6
Closes gh-2242
2023-02-21 17:06:13 -06:00
Rob Winch
8898ceb4a7 Update to Spring Security 5.7.6
Closes gh-2241
2023-02-21 17:05:25 -06:00
Rob Winch
c4e9a93d02 Update to Spring Data 20201.2.7
Closes gh-2240
2023-02-21 17:04:17 -06:00
Rob Winch
d8ab39eba7 Update to Spring Framework 5.3.25
Closes gh-2239
2023-02-21 17:03:19 -06:00
Rob Winch
6a5f101656 Update to Jackson 2.13.4.20221013
Closes gh-2238
2023-02-21 17:02:26 -06:00
Rob Winch
88d34035a6 Update to Reactor 2020.0.27
Closes gh-2237
2023-02-21 17:01:26 -06:00
Rob Winch
81ef425b1b Spring to Boot 2.7.8
Closes gh-2236
2023-02-21 16:59:46 -06:00
Marcus Da Coregio
280f311677 Update Antora Plugin to 1.0.0
Issue gh-2234
2023-02-16 09:41:50 -03:00
Marcel Wollschläger
8da5068cac Update Redis example documentation
With the release of Spring-Boot 3.x, the application properties for Redis
changed from `spring.redis` to `spring.data.redis`.
This change will update the documentation to be consistent with the latest
changes in Spring-Boot.
2023-01-24 09:44:47 -03:00
Marcus Da Coregio
9276e1ddc6 Merge branch '2.7.x' 2023-01-23 13:59:11 -03:00
Kaoru Muta
fab1f7b38e docs: fix broken links in hazelcast documents 2023-01-23 13:57:39 -03:00
Marcus Da Coregio
a09146a2ed Merge branch '2.7.x' 2023-01-23 13:50:44 -03:00
Eddú Meléndez
0dfc97289f Polish related to testcontainers
* Use getHost instead of getContainerIpAddress
* Rely on OracleContainer and it's improvements which involve the log
wait strategy
2023-01-23 13:47:59 -03:00
Marcus Da Coregio
13c7ee54a8 Merge branch '2.7.x' 2023-01-23 12:59:31 -03:00
Marcus Da Coregio
7c927c7f38 Setup forward merge
Closes gh-2228
2023-01-23 11:52:06 -03:00
Marcus Da Coregio
c98a7be0e2 Remove System.out.println
Closes gh-2215
2022-12-01 10:17:20 -03:00
Marcus Da Coregio
8f9c69ea02 Add jakarta.servlet.jsp.jstl-api to non Spring Boot samples
Closes gh-2216
2022-12-01 09:07:19 -03:00
Rob Winch
df3f9a386e Next Development Version 2022-11-22 09:09:55 -06:00
Rob Winch
77e062b2cd Release 3.0.0 2022-11-22 09:08:17 -06:00
Rob Winch
2a3b76fee5 Update to Spring Security 6.0.0
Closes gh-2211
2022-11-22 09:06:02 -06:00
Rob Winch
d5b75228fc Update to Spring Data 2022.0.0
Closes gh-2210
2022-11-22 09:03:59 -06:00
Rob Winch
3d7c668e57 Update to Spring Framework 6.0.0
Closes gh-2209
2022-11-22 09:02:56 -06:00
Rob Winch
e83cf082c4 Merge branch '2.7.x' 2022-11-15 14:20:11 -06:00
Rob Winch
cbd1c66c13 Merge branch '2.6.x' into 2.7.x 2022-11-15 14:20:00 -06:00
Rob Winch
9f7a969a6e Fix Snapshot Deploy
This commit merges a workaround to an issue in JFrog's Gradle plugin
which causes SNAPSHOTs to be out of sync and thus prevents downloading.

Closes gh-2177
2022-11-15 14:17:26 -06:00
Rob Winch
f51310ee64 Merge branch '2.7.x' 2022-11-15 13:45:25 -06:00
Rob Winch
5f2523e211 Merge branch '2.6.x' into 2.7.x 2022-11-15 13:44:56 -06:00
Bakul Kakadiya
26986a6b7d Corrected documentation Reference Link 2022-11-15 11:49:05 -06:00
Craig Andrews
6cdb77378d Update reference site link
https://docs.spring.io/spring-session/docs/current/reference/html5/ goes to a 404 page

Use https://docs.spring.io/spring-session/reference/ instead which is the current documentation site.
2022-11-15 11:48:28 -06:00
Vedran Pavic
238416ec23 Polish HttpSessionAdapter 2022-11-15 11:47:01 -06:00
Vedran Pavic
4b99428267 Polish SessionRepositoryFilterTests 2022-11-15 11:47:01 -06:00
Dan Allen
058e4e46a5 label jpg as binary file in .gitattributes 2022-11-15 11:34:19 -06:00
Rob Winch
fd3609c6f0 Next Development Version 2022-11-09 13:09:53 -06:00
Rob Winch
a0d03adbe1 Release 3.0.0-RC2 2022-11-09 12:44:49 -06:00
Rob Winch
b229103d8c Remove spring-session-sample-javaconfig-rest
Works around a compatability issue for now.

Issue gh-2201
2022-11-09 12:44:31 -06:00
Rob Winch
94b441c676 Define websocket depenendencies
Issue gh-2204
2022-11-09 12:43:22 -06:00
Rob Winch
b2f10c6752 Next Development Version 2022-11-09 10:24:54 -06:00
Rob Winch
b3d228eb2e Release 3.0.0-RC2 2022-11-09 10:24:22 -06:00
Rob Winch
19dd3d8be1 Revert "Update for docs-build branch"
This reverts commit cd628fe5af.
2022-11-09 10:22:52 -06:00
Rob Winch
1aaffb28fc Update to Spring Security 6.0.0-RC2
Closes gh-2206
2022-11-09 09:56:24 -06:00
Rob Winch
75af61ca6c Update to Spring Data 2022.0.0-RC2
Closes gh-2205
2022-11-09 09:55:30 -06:00
Rob Winch
2fff593423 Update to Spring Framework 6.0.0-RC4
Closes gh-2204
2022-11-09 09:54:10 -06:00
Rob Winch
6a381d3226 Update to reactor-bom:2022.0.0
Closes gh-2203
2022-11-09 09:53:09 -06:00
Rob Winch
cd628fe5af Update for docs-build branch 2022-11-08 12:59:06 -06:00
Andy Wilkinson
ee4df64bb1 Align wth Servlet 6.0 API 2022-11-07 10:27:13 -06:00
Andy Wilkinson
d850762bce Avoid changing line endings of png and mmdb files 2022-11-07 10:05:58 -06:00
Vedran Pavic
f71d1d6ca4 Add Spring Session BOM module
With Spring Session Data Geode module being removed from the BOM, all of Spring Session's modules are now managed by this repository.

This means that the BOM itself can be moved to this repository, in order to simplify the overall project maintenance.

See gh-2195
2022-10-25 14:33:58 -05:00
Vedran Pavic
e5eeacec5f Update security config in samples
This commit updates security configuration in samples to:

- use AuthorizationFilter instead of FilterSecurityInterceptor
- update session creation policy in REST sample
2022-10-25 14:27:39 -05:00
Rob Winch
62ec64310b Next Development Version 2022-10-18 20:46:04 -05:00
Rob Winch
25d810eaa3 Release 3.0.0-RC1 2022-10-18 20:46:04 -05:00
Vedran Pavic
82db55c3f8 Polish SessionRepositoryFilter
This commit polishes SessionRepositoryFilter by simplifying some code paths.
2022-10-18 16:47:30 -05:00
Yanming Zhou
1f38a937bd Eliminate unnecessary sessionRepository::findById 2022-10-18 16:47:30 -05:00
Rob Winch
e027d2091b Update to Spring Security 6.0.0-RC1
Closes gh-2193
2022-10-18 16:44:06 -05:00
Vedran Pavic
bcbe53c3dd Make MongoSession package private
See gh-2170
2022-10-18 14:57:23 -05:00
Vedran Pavic
72742b52e3 Make MongoSessionUtils package private
See gh-2170
2022-10-18 14:57:23 -05:00
Vedran Pavic
1889a4c64e Use standard Spring utils in MongoDB module
This commit replaces usages of custom assert utility class with standard one from Spring Framework, and removes the custom utility.

See gh-2170
2022-10-18 14:57:23 -05:00
Jerome Prinet
3000f3198f Update Gradle Enterprise plugin to 3.11.2 2022-10-18 14:32:18 -05:00
Jerome Prinet
82a12afe93 Update Gradle Enterprise plugin to 3.11.1 2022-10-18 14:32:18 -05:00
Vedran Pavic
d2da662c3f Upgrade Gradle to 7.5.1 2022-10-18 14:31:30 -05:00
Vedran Pavic
95e2c9e42a Add .gitattributes 2022-10-18 14:31:30 -05:00
Rob Winch
ff8672b1d5 Update to mongodb 4.8.0-beta0
Closes gh-2182
2022-10-17 22:48:31 -05:00
Rob Winch
31d4a766eb Update to derby 10.16.1.1
Closes gh-2183
2022-10-17 22:48:18 -05:00
Rob Winch
ce332022de Update to lettuce 6.2.1.RELEASE
Closes gh-2184
2022-10-17 22:48:05 -05:00
Rob Winch
5c2ca6d5ac Update to hazelcast 5.1.4
Closes gh-2185
2022-10-17 22:47:54 -05:00
Rob Winch
bc93d80a17 Update to Spring Data 2022.0.0-RC1
Closes gh-2186
2022-10-17 22:47:42 -05:00
Rob Winch
fd835fd316 Update to Spring Framework 6.0.0-RC2
Closes gh-2187
2022-10-17 22:47:25 -05:00
Rob Winch
4e3ea616ba Update to Mockito 4.8.1
Closes gh-2188
2022-10-17 22:47:12 -05:00
Rob Winch
08654749ae Update to JUnit 5.9.1
Closes gh-2189
2022-10-17 22:47:07 -05:00
Rob Winch
88306d037d Update to Jackson 2.13.4.20221013
Closes gh-2190
2022-10-17 22:46:52 -05:00
Rob Winch
de32e4c501 Update to Reactor 2022.0.0-RC1
Closes gh-2191
2022-10-17 22:46:42 -05:00
Vedran Pavic
668f85788a Avoid inheritance in configuration classes
This commit restructures configuration classes to avoid inheritance, where possible. This should provide more flexibility when composing custom configurations.

Closes gh-1415
2022-10-17 21:52:58 -05:00
Vedran Pavic
fc81049cbe Upgrade Logback to 1.4.4 2022-10-17 15:05:24 -05:00
Vedran Pavic
fbb94b40e8 Fix Spring Security XML config 2022-10-17 15:05:24 -05:00
Vedran Pavic
009cb5b592 Fix max inactive interval setters backwards compatibility
This commit restores integer based max inactive interval setters across all session repositories, that were migrated to java.time in 6d74cf5f.

This change caused problems building our Spring Boot based samples, as Spring Boot auto-configuration has move to session repository customizer based approach and is therefore using max inactive interval setters directly on session repository implementations.
2022-10-07 07:56:25 -05:00
Vedran Pavic
525b841ad6 Build against Project Reactor 2022.0.0-RC1 snapshots 2022-10-06 21:52:31 -05:00
Vedran Pavic
185ea87ff4 Build against Spring Security 6.0.0-RC1 snapshots 2022-10-06 21:52:31 -05:00
Vedran Pavic
aebe5ece6f Build against Spring Data 2022.0.0-RC1 snapshots 2022-10-06 21:52:31 -05:00
Vedran Pavic
30b8e68c67 Build against Spring Framework 6.0.0-RC1 snapshots 2022-10-06 21:52:31 -05:00
Vedran Pavic
c2f8428df9 Upgrade Logback to 1.4.1 2022-10-06 10:28:41 -05:00
Vedran Pavic
b5197b8665 Polish RedisIndexedSessionRepository
This commit addresses code warnings due to nullability of return values.
2022-10-06 10:28:11 -05:00
Vedran Pavic
2406ec8302 Fix SessionCreatedEvent handling in RedisIndexedSessionRepository
At present, RedisIndexedSessionRepository publishes a SessionCreatedEvent backed by an empty MapSession instance. This happens because session delta has been cleared before publishing a message to the session created channel.

Fixes gh-1338
2022-10-06 10:28:11 -05:00
Vedran Pavic
6d74cf5f35 Use java.time in all session repositories and configurations
This commit reworks all session repository implementations and their respective configurations to use java.time for managing maxInactiveInterval and other temporal values.
2022-10-06 10:26:50 -05:00
Vedran Pavic
da8e5fbbac Ensure configuration classes can be used with @Import
This commit adds tests that verify that all Spring Session configuration classes can be used with @Import, and fixes JDBC and Hazelcast HttpSession configurations and Redis WebSession configuration.
2022-09-26 09:01:09 -05:00
Vedran Pavic
4b34f35b82 Replace JSR-250 annotations with standard Spring lifecycle callbacks 2022-09-26 08:59:06 -05:00
Vedran Pavic
954a40f5d1 Simplify expired session cleanup jobs
At present, RedisIndexedHttpSessionConfiguration and JdbcHttpSessionConfiguration include [at]EnableScheduling annotated inner configuration classes that configure expired session cleanup jobs. This approach silently opts in users into general purpose task scheduling support provided by Spring Framework, which isn't something a library should do. Ideally, session cleanup jobs should only require a single thread dedicated to their execution and also one that doesn't compete for resources with general purpose task scheduling.

This commit updates RedisIndexedSessionRepository and JdbcIndexedSessionRepository to have them manage their own ThreadPoolTaskScheduler for purposes of running expired session cleanup jobs.

Closes gh-2136
2022-09-23 15:23:29 -05:00
Vedran Pavic
fb66cf3150 Remove @Configuration meta-annotation from @Enable*Session annotations
Closes gh-1361
2022-09-22 16:13:16 -05:00
Vedran Pavic
a23090e7e5 Fix "Find by Username" sample
Spring Boot's auto-configuration support for Spring Session now uses RedisSessionRepository as the default Redis session repository, so applications that rely on indexed session repository need to opt into the previous default. One such example is our "Find by Username" sample.

This commit fixes "Find by Username" sample by opting into the indexed repository type using newly introduced spring.session.redis.repository-type property.
2022-09-22 14:33:52 -05:00
Rob Winch
beaca53d44 Fix major/minor segments 2022-09-21 14:47:06 -05:00
Marcus Da Coregio
baed403a6a Polish SessionJdbcRuntimeHints
Issue gh-2103
2022-09-21 09:12:24 -03:00
Rob Winch
cd51c36dc0 Next Development Version 2022-09-20 14:59:00 -05:00
Rob Winch
7144e626cc Release 3.0.0-M4 2022-09-20 14:57:53 -05:00
Rob Winch
0e0d0007e6 Next Development Version 2022-09-20 14:52:18 -05:00
Rob Winch
573424f2a1 Release 3.0.0-M3 2022-09-20 14:43:52 -05:00
Rob Winch
8e6e9dec53 Allow snapshot repository for samples
When a release is published Spring Boot has not been released, so
it can be beneficial to allow the samples to use the snapshot
repository. This is determined based on the springBootVersion property.
2022-09-20 14:42:49 -05:00
Rob Winch
8216be69cc Upgrade to org.postgresql:postgresql:42.5.0
Closes gh-2161
2022-09-20 14:02:52 -05:00
Rob Winch
0e1914b380 Update to org.mongodb 4.7.1
Closes gh-2162
2022-09-20 14:02:06 -05:00
Rob Winch
ec32a825d9 Upgrade to org.mariadb.jdbc:mariadb-java-client:3.0.7
Closes gh-2159
2022-09-20 14:00:45 -05:00
Rob Winch
8319435f7c Upgrade to org.hsqldb:hsqldb:2.7.0
Closes gh-2158
2022-09-20 13:59:59 -05:00
Rob Winch
45448c3075 Upgrade to org.assertj:assertj-core:3.23.1
Closes gh-2157
2022-09-20 13:59:12 -05:00
Rob Winch
efd18a9fe9 Upgrade to mysql:mysql-connector-java:8.0.30
Closes gh-156
2022-09-20 13:58:40 -05:00
Rob Winch
8cf71b27f9 Update to Upgrade to io.lettuce:lettuce-core:6.2.0.RELEASE
Closes gh-2155
2022-09-20 13:57:56 -05:00
Rob Winch
0ea5ed709d Upgrade to com.oracle.database.jdbc:ojdbc8:21.7.0.0
Closes gh-2153
2022-09-20 13:57:05 -05:00
Rob Winch
a57774bff6 Upgrade to com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre17
Closes gh-2152
2022-09-20 13:55:06 -05:00
Rob Winch
106848fcf7 Upgrade to com.ibm.db2:jcc:11.5.7.0
Closes gh-2151
2022-09-20 13:54:09 -05:00
Rob Winch
a1b87ce1e9 Upgrade to com.h2database:h2:2.1.214
Close gh-2150
2022-09-20 13:53:33 -05:00
Rob Winch
cb75ee603d Upgrade to ch.qos.logback:logback-core:1.2.11
Closes gh-2149
2022-09-20 13:52:57 -05:00
Rob Winch
2eb10a6e58 Upgrade to org.aspectj:aspectjweaver:1.9.9.1
Closes gh-2148
2022-09-20 13:52:21 -05:00
Rob Winch
5bdf5ed780 Upgrade to com.hazelcast:hazelcast:5.1.3
Closes gh-2147
2022-09-20 13:47:14 -05:00
Rob Winch
1ccd1a1eea Upgrade to org.mockito:mockito-bom:4.8.0
Closes gh-2146
2022-09-20 13:46:49 -05:00
Rob Winch
27e90b2e59 Update to spring-security-bom:6.0.0-M7
Closes gh-2145
2022-09-20 13:36:33 -05:00
Rob Winch
b8d660712e Update to spring-data-bom:2022.0.0-M4
Closes gh-2144
2022-09-20 13:35:17 -05:00
Rob Winch
f65f84a129 Update to spring-framework-bom:6.0.0-M6
Closes gh-2143
2022-09-20 13:33:49 -05:00
Rob Winch
0a0e34e248 Update to junit-bom:5.9.0
Closes gh-2142
2022-09-20 13:32:35 -05:00
Rob Winch
bb8b9444e6 Update to jackson-bom:2.13.4
Closes gh-2141
2022-09-20 13:30:19 -05:00
Rob Winch
da1fc676ae Update to reactor-bom:2022.0.0-M6
Closes gh-2140
2022-09-20 13:29:14 -05:00
Vedran Pavic
cb6f5c9588 Align dependency versions in samples
This commit aligns dependency versions used across different samples application by leveraging Spring Boot's BOM, rather than manually managing dependency versions for samples that are not Spring Boot based.
2022-09-20 10:58:05 -05:00
Vedran Pavic
4e311939c2 Use Spring Security auto-configuration in MongoDB samples 2022-09-20 10:58:05 -05:00
Vedran Pavic
e050a92fad Restructure Redis HttpSession configuration support
This commit restructures configuration support for Redis-backed
HttpSession with aim to enable users to easily select the
SessionRepository implementation they prefer to use.

This is achieved by introducing [at]EnableRedisIndexedHttpSession
annotation that can be used to configure RedisIndexedSessionRepository,
while the existing [at]EnableRedisHttpSession will going forward
configure RedisSessionRepository as the SessionRepository implementation
used by Spring Session.

Additionally, this also introduces AbstractRedisHttpSessionConfiguration
as the base configuration class that manages common aspects of
Redis-backed HttpSession support, which is then extended by more
specific configuration classes that provide specific SessionRepository
implementation.

Closes gh-2122
2022-09-07 09:46:55 -05:00
Vedran Pavic
0c1dbc7355 Revert "Use simple Redis repository by default"
This reverts commit 8582b970

See gh-2122
2022-09-07 09:46:55 -05:00
Vedran Pavic
8e8de48614 Fix deprecation warnings 2022-09-06 15:27:53 -05:00
Rob Winch
8c49d5993f Fix antora-playbook.yml
When 3.0.x was renamed to main the antora playbook should have been copied
from 2.7.x to 3.0.x.

Closes gh-2135
2022-08-30 23:04:34 -05:00
Rob Winch
d257f1779e Improve Tags/Branches Antora Processes 2022-08-30 22:58:44 -05:00
Rob Winch
a81918116d Update to Antora 3.1.0 2022-08-30 22:58:02 -05:00
Vedran Pavic
9524730ab1 Update integration tests
This commit updates Docker images used in all the integration tests. Additionally, it updates JDBC session repository Oracle integration tests to run unconditionally.
2022-08-30 21:48:39 -05:00
Vedran Pavic
7856113608 Remove unused test sources in docs
This commit removes test sources that are already present in modules/ROOT/examples path of spring-session-docs module.
2022-08-30 21:46:05 -05:00
Vedran Pavic
820c055e7e Update .gitignore
This commit updates .gitignore to include NPM files created by Antora tasks of spring-session-docs module.
2022-08-30 21:46:05 -05:00
Vedran Pavic
2817d309ac Configure nohttp to ignore docs build output
At present, project build fails with checkstyleNohttp task error if not cleaned beforehand.

This commit updates nohttp configuration so that it ignores build output of examples in spring-session-docs module.

Closes gh-2127
2022-08-30 21:46:05 -05:00
Vedran Pavic
2191c6f296 Use text blocks for SQL statements
With Java 17 now being the baseline, strings containing SQL statements
can be managed more conveniently using text blocks.
2022-08-30 21:44:38 -05:00
Vedran Pavic
87bb3df543 Upgrade Spring JavaFormat to 0.0.34 2022-08-30 21:44:38 -05:00
Vedran Pavic
38a87e093a Disable Hazelcast network join auto-detection in tests
At present, Hazelcast configurations used in tests disable multicast join but leave network join auto-detection enabled. This can cause issues with parallel test execution on machines that have bigger number of CPU cores/threads.

This commit updates Hazelcast configurations used in tests to disable network join auto-detection and thus ensure no network join method ends up being enabled.
2022-08-19 13:33:21 -05:00
Vedran Pavic
75ab31d459 Remove deprecated code in spring-session-data-mongodb 2022-08-19 13:31:44 -05:00
Vedran Pavic
9041ffb29e Remove deprecated code in spring-session-hazelcast 2022-08-19 13:31:44 -05:00
Vedran Pavic
b20b08e020 Remove deprecated code in spring-session-jdbc 2022-08-19 13:31:44 -05:00
Vedran Pavic
de57f2cd14 Remove deprecated code in spring-session-data-redis 2022-08-19 13:31:44 -05:00
Vedran Pavic
b85ec4de1a Fix Spring Security configuration in tests
As of spring-projects/spring-security#11653, Spring Security's [at]Enable*Security annotations are not meta annotated with [at]Configuration which breaks some of our tests.

This commit adds missing [at]Configuration annotations where needed.

Closes gh-2118
2022-08-19 11:20:04 -05:00
Marcus Da Coregio
812ac239c0 Fix Session Security Runtime Hints always being registered
Splits the Security and Common Session hints in two different classes and only register security hints if SecurityContextImpl is present

Issue gh-2104
2022-08-05 10:59:50 -03:00
Marcus Da Coregio
cc4a15db79 Use SQLErrorCodeSQLExceptionTranslator in JdbcTemplate
Closes gh-2108
2022-07-20 09:13:30 -03:00
Marcus Da Coregio
65b994cad1 Polish RuntimeHintsRegistrar
Add RuntimeHints suffix to classes
Make classes package-private
Use ReflectionUtilsPredicates#serialization

Closes gh-2111
Closes gh-2112
2022-07-18 09:06:57 -03:00
Marcus Da Coregio
374ea4a432 Upgrade com.hazelcast:hazelcast to 5.0.3
Closes gh-2110
2022-07-18 09:06:35 -03:00
Marcus Da Coregio
abce2eb555 Add native-image support for Core classes
Closes gh-2104
2022-07-08 11:20:54 -03:00
Marcus Da Coregio
dc2e93f198 Add native-image support for Session JDBC
Closes gh-2103
2022-07-08 11:08:33 -03:00
Marcus Da Coregio
00d248b0b5 Fix failing tests
Issue gh-2107
2022-07-08 11:07:02 -03:00
Marcus Da Coregio
13b0e5cc8a Use Spring Security 6 SNAPSHOTs
Closes gh-2106
2022-07-08 08:45:28 -03:00
Marcus Da Coregio
dd0edeaef8 Use Spring Framework 6 SNAPSHOTs
Closes gh-2105
2022-07-08 08:45:15 -03:00
Rob Winch
7fac9efc89 Next Developement Version 2022-05-18 14:58:54 -05:00
Rob Winch
8553b52431 Release 3.0.0-M3 2022-05-18 14:54:53 -05:00
Rob Winch
69d8fda4cc Update spring-data-bom:2022.0.0-M4 2022-05-18 14:41:48 -05:00
Rob Winch
a9f7a35ef3 Revert "Temporarily Disable Samples"
This reverts commit 2effbd19ab.
2022-05-18 14:41:02 -05:00
Rob Winch
679b6e57df Next Development Version 2022-05-18 13:09:22 -05:00
Rob Winch
1bc21d5187 Release 3.0.0-M2 2022-05-18 13:08:46 -05:00
Rob Winch
2effbd19ab Temporarily Disable Samples 2022-05-18 13:00:33 -05:00
Rob Winch
31275574ee Update to spring-security-bom:6.0.0-M5
Closes gh-2093
2022-05-18 12:04:25 -05:00
Rob Winch
e4201aea05 Update to spring-data-bom:2022.0.0-M3
Closes gh-9092
2022-05-18 12:04:25 -05:00
Rob Winch
3c134778d8 Update to spring-framework-bom:6.0.0-M4
Closes gh-2091
2022-05-18 12:04:25 -05:00
Rob Winch
bc51d842dc Update to jackson-bom:2.13.3
Clsoes gh-2090
2022-05-18 12:04:25 -05:00
Rob Winch
17610e7cc2 Update to reactor-bom:2020.0.19
Closes gh-2089
2022-05-18 12:04:15 -05:00
Rob Winch
58813e9d5a Next Development Version 2022-05-18 11:06:59 -05:00
Rob Winch
c66ee750f9 Release 2.7.0 2022-05-18 11:02:54 -05:00
Rob Winch
9062db3f55 Update to spring-security-bom:5.7.0
Closes gh-2084
2022-05-18 09:29:51 -05:00
Rob Winch
4bf15cda3b Update to spring-data-bom:2021.2.0
Closes gh-2085
2022-05-18 09:29:51 -05:00
Rob Winch
7f8c0387a7 Update to spring-framework-bom:5.3.20
Closes gh-2086
2022-05-18 09:29:51 -05:00
Rob Winch
3bc15c4259 Update to reactor-bom:2020.0.19
Closes gh-2087
2022-05-18 09:29:50 -05:00
Rob Winch
c9add24c77 Add .sdkmanrc
Closes gh-2088
2022-05-18 09:29:44 -05:00
Rob Winch
3ce78f6cd0 Fix formatting 2022-05-13 17:49:29 -05:00
Rob Winch
21b0f60721 Add .sdkmanrc 2022-05-13 17:41:34 -05:00
Rob Winch
0dcdf5f147 Fix Thymeleaf Samples
Thymeleaf removed support for accessing the HttpServletRequest and HttpSession
automatically, so we need to add any properties we want to access as ModelAttributes

Closes gh-2076
2022-05-13 17:37:33 -05:00
Rob Winch
a0bf6a0e62 Restore all Samples 2022-05-13 17:36:52 -05:00
Rob Winch
d23b81f300 Fix spring-session-sample-boot-mongodb-traditional 2022-05-13 17:36:52 -05:00
Rob Winch
f33c5fe19a Fix spring-session-sample-boot-websocket 2022-05-13 17:36:52 -05:00
Rob Winch
e1c4b25671 Fix spring-session-sample-boot-hazelcast 2022-05-13 17:36:52 -05:00
Rob Winch
9bf18059d2 Fix xpring-session-sample-boot-jdbc 2022-05-13 17:36:52 -05:00
Rob Winch
342198cdfb Fix spring-session-sample-boot-redis-json 2022-05-13 17:36:52 -05:00
Rob Winch
c151a97227 Fix spring-session-sample-boot-findbyusername 2022-05-13 17:36:52 -05:00
Rob Winch
0cb6e0ebc9 Fix spring-session-sample-boot-redis-simple 2022-05-13 17:36:52 -05:00
Rob Winch
b4c3cefcf4 fix spring-session-sample-boot-redis 2022-05-13 17:36:52 -05:00
Rob Winch
2a6a9cfb78 Fix Formatting 2022-05-13 17:36:23 -05:00
Greg L. Turnquist
55f9bc9c37 Replace Flapdoodle with Testcontainers for MongoDB support.
For more details on this usage of Testcontainers, see https://bsideup.github.io/posts/local_development_with_testcontainers/

Related issues: https://github.com/spring-projects/spring-boot/issues/30863
2022-05-13 17:34:43 -05:00
Eleftheria Stein
c9cf1eab7b Update Htmlunit test dependency 2022-05-13 13:13:32 -05:00
Eleftheria Stein
003335df73 Update LocalServerPort import to new package 2022-05-13 13:12:38 -05:00
Eleftheria Stein
c3b8634fb4 Use Java 17 in antora pipeline 2022-04-29 11:38:12 +02:00
Eleftheria Stein
28e1ab1d8d Upgrade to Gradle 7.4.2 in buildSrc
Issue gh-2073
2022-04-29 10:56:02 +02:00
Eleftheria Stein
ff8750e9c1 Re-enable working samples
The Spring Boot servlet samples remain disalbed because of gh-2076.
2022-04-29 10:33:32 +02:00
Eleftheria Stein
e51dd2d1b0 Upgrade test dependencies 2022-04-29 10:28:34 +02:00
Eleftheria Stein
a6f24bc27e Upgrade MongoDB to 4.6.0
Closes gh-2075
2022-04-29 10:28:01 +02:00
Eleftheria Stein
42580c3a44 Upgrade samples to Spring Boot 3.0.0-SNAPSHOT #
Closes gh-2074
2022-04-29 10:25:48 +02:00
Eleftheria Stein
ea0aef9d97 Upgrade to Gradle 7.4.2
Closes gh-2073
2022-04-29 10:21:39 +02:00
Eleftheria Stein
0d458a4a5b Update Redis docs
Issue gh-1711
2022-04-29 09:03:57 +02:00
Eleftheria Stein
102027a456 Add Caffeine community extension
Closes gh-2039
2022-04-27 09:53:55 +02:00
Eleftheria Stein
e580a97c0c Fix link to Infinispan cache 2022-04-27 09:53:55 +02:00
Eleftheria Stein
7227949afb Fix formatting 2022-04-27 09:53:55 +02:00
Greg L. Turnquist
34d59a0ed9 Switch back to unicode for the DOT substitute character.
MongoDB doesn't support "." in field names, so a Private Use Area character was used. This was originally stored in unicode format, but delomboking the code caused it to get transformed into another encoding. This causes issues on certain systems when building the software, so we are converting it back to its unicode representation. The character has been the same throughout, ensuring binary compatilibity.

See: https://www.compart.com/en/unicode/U+F607

Related: d601e270fc (diff-57190a47726099e31fdf86b12b80206e2ae24feb28aacaf494b99557583df150L47)
Closes #2053.
2022-04-27 09:53:55 +02:00
Eleftheria Stein
aaed973d27 Add Caffeine community extension
Closes gh-2039
2022-04-27 09:50:11 +02:00
Eleftheria Stein
55c4fcfd3f Fix link to Infinispan cache 2022-04-27 09:49:41 +02:00
Eleftheria Stein
2a5d6b4d2e Next development version 2022-04-19 18:39:03 +02:00
Eleftheria Stein
42aa10bfe8 Release 2.7.0-RC1 2022-04-19 18:20:16 +02:00
Eleftheria Stein
2ce570cbdc Next development version 2022-04-19 18:06:26 +02:00
Eleftheria Stein
221b48094a Upgrade test dependencies 2022-04-19 17:59:17 +02:00
Eleftheria Stein
d43b48bbb0 Revert "Upgrade test dependencies"
This reverts commit 2369b2cfb3.
2022-04-19 17:57:52 +02:00
Eleftheria Stein
840907993b Release 2.6.3 2022-04-19 17:37:41 +02:00
Eleftheria Stein
e1dea5e0a8 Revise Redis test mocks based on new Data implementation
Issue gh-2070
2022-04-19 15:53:23 +02:00
Eleftheria Stein
4db41c1caf Upgrade Spring Data to 2021.1.4
Closes gh-2058
2022-04-19 15:41:20 +02:00
Eleftheria Stein
23a32acd56 Upgrade Spring Data to 2021.2.0-RC1
Closes gh-2059
2022-04-19 15:18:55 +02:00
Eleftheria Stein
dc8cca5351 Upgrade Spring Security to 5.7.0-RC1
Closes gh-2070
2022-04-19 13:19:15 +02:00
Eleftheria Stein
2369b2cfb3 Upgrade test dependencies 2022-04-19 13:19:10 +02:00
Eleftheria Stein
e6ce56ec8b Upgrade Reactor to 2020.0.18
Closes gh-2071
2022-04-19 13:17:57 +02:00
Eleftheria Stein
36939c1b02 Upgrade Jackson to 2.13.2.20220328
Closes gh-2068
2022-04-19 13:17:25 +02:00
Eleftheria Stein
0a84f9d544 Upgrade Spring Framework to 5.3.19
Closes gh-2069
2022-04-19 13:15:32 +02:00
Eleftheria Stein
f4840e98a2 Upgrade test dependencies 2022-04-19 12:27:09 +02:00
Eleftheria Stein
8c99c9f904 Upgrade Spring Security to 5.6.3
Closes gh-2064
2022-04-19 12:26:40 +02:00
Eleftheria Stein
f70f1f20f9 Upgrade Reactor to 2020.0.18
Closes gh-2065
2022-04-19 12:25:20 +02:00
Eleftheria Stein
ac1a77e5fe Upgrade Jackson to 2.13.2.20220328
Closes gh-2066
2022-04-19 12:21:58 +02:00
Eleftheria Stein
214a556dd4 Upgrade Spring Framework to 5.3.19
Closes gh-2063
2022-04-19 12:21:22 +02:00
Eleftheria Stein
cace484fbe Upgrade samples to Spring Boot 2.6.6
Closes gh-2067
2022-04-19 12:20:16 +02:00
Eleftheria Stein
a5ec1ccf1f Fix formatting 2022-04-19 11:13:49 +02:00
Greg L. Turnquist
7fc0ae47d5 Switch back to unicode for the DOT substitute character.
MongoDB doesn't support "." in field names, so a Private Use Area character was used. This was originally stored in unicode format, but delomboking the code caused it to get transformed into another encoding. This causes issues on certain systems when building the software, so we are converting it back to its unicode representation. The character has been the same throughout, ensuring binary compatilibity.

See: https://www.compart.com/en/unicode/U+F607

Related: d601e270fc (diff-57190a47726099e31fdf86b12b80206e2ae24feb28aacaf494b99557583df150L47)
Closes #2053.
2022-04-18 09:49:57 -05:00
Eleftheria Stein
8582b9706d Use simple Redis repository by default
Closes gh-1711
2022-04-14 13:17:28 +02:00
Jerome Prinet
14ecf21c94 Update Gradle Enterprise plugin to 3.9 2022-04-14 11:11:31 +02:00
Jerome Prinet
ce2e644e04 Update Gradle Enterprise plugin to 3.9 2022-04-14 11:10:54 +02:00
John Blum
6fc4097c2e Switch to Spring Security BOM 6.0.0-SNAPSHOT 2022-04-11 15:41:24 -07:00
John Blum
a1cfbcae0c Switch to Spring Data BOM 2022.0.0-SNAPSHOT 2022-04-11 15:40:50 -07:00
John Blum
004cf6656b Switch to Spring Framework BOM 6.0.0-SNAPSHOT 2022-04-11 15:39:51 -07:00
Felix Scheinost
24c198fe98 Fix bug in JDBC SaveMode.ON_GET_ATTRIBUTE 2022-04-08 17:50:51 +02:00
Felix Scheinost
cde256e1a3 Fix bug in JDBC SaveMode.ON_GET_ATTRIBUTE
Closes gh-2040
2022-04-08 17:20:46 +02:00
Felix Scheinost
8800fb9816 Fix bug in JDBC SaveMode.ON_GET_ATTRIBUTE 2022-04-08 17:19:54 +02:00
Eleftheria Stein
63f7f7b0a9 Upgrade Spring Data to 2022.0.0-M3
Closes gh-2048
2022-04-01 18:21:23 +02:00
Eleftheria Stein
b8e94948ae Upgrade MongoDB to 4.5.1
Closes gh-2047
2022-03-30 15:24:02 +02:00
Eleftheria Stein
8d2276341f Upgrade samples to Spring Boot 2.7.0-M3
This also makes the necessary changes for the Thymeleaf Layout Dialect 3.0 update.

Closes gh-2046
2022-03-30 15:23:49 +02:00
Eleftheria Stein
2c1b79375d Upgrade samples to Spring Boot 2.6.5
This also makes the necessary changes for the Thymeleaf Layout Dialect 3.0 update.

Closes gh-1980
2022-03-29 15:33:08 +02:00
Eleftheria Stein
63f1c7bf6f Fix reference documentation redirects
Closes gh-2044
2022-03-23 10:03:32 +01:00
Eleftheria Stein
140cc75583 Make RedisSessionRepository.DEFAULT_KEY_NAMESPACE public
Closes gh-2043
2022-03-15 18:34:59 +01:00
Eleftheria Stein
e8e4ee2850 Make RedisSessionRepository.DEFAULT_KEY_NAMESPACE public
Closes gh-2043
2022-03-15 18:23:17 +01:00
Eleftheria Stein
e157700087 Update to Antora 3.0.1
Closes gh-2038
2022-03-11 15:48:26 +01:00
Eleftheria Stein
1b18d64220 Fix 2.6.2 reference docs
Closes gh-2035
2022-03-11 15:48:18 +01:00
Eleftheria Stein
9a643c8866 Update to Antora 3.0.1
Closes gh-2038
2022-03-11 15:46:19 +01:00
Eleftheria Stein
14756984fd Document release process for 3.0.x
Issueh gh-2036
2022-02-24 13:02:33 +01:00
Eleftheria Stein
282f774e07 Document release process for 2.7.x
Issue gh-2036
2022-02-24 12:46:05 +01:00
Eleftheria Stein
fba9313c6b Document release process for 2.6.x
Issue gh-2036
2022-02-23 14:22:25 +01:00
Eleftheria Stein
e6ec5765b8 Fix 2.6.2 reference docs
Closes gh-2035
2022-02-22 15:43:37 +01:00
Eleftheria Stein
c2288615bf Update antora to 2.6.3 2022-02-22 14:38:24 +01:00
Eleftheria Stein
ad52fc0297 Next development version 2022-02-22 14:13:29 +01:00
Eleftheria Stein
2516a495af Release 2.6.2 2022-02-22 10:31:00 +01:00
Eleftheria Stein
9be7ac7fa6 Upgrade test dependencies 2022-02-22 10:30:29 +01:00
Eleftheria Stein
c335a49924 Upgrade Hazelcast 4 to 4.2.4
Closes gh-2029
2022-02-22 10:29:20 +01:00
Eleftheria Stein
092e6c6607 Upgrade MongoDB to 4.4.2
Closes gh-2034
2022-02-22 10:28:02 +01:00
Eleftheria Stein
0924c9558a Upgrade Reactor to 2020.0.16
Closes gh-2031
2022-02-22 10:27:20 +01:00
Eleftheria Stein
0484781541 Upgrade Jackson to 2.13.1
Closes gh-2033
2022-02-22 10:26:38 +01:00
Eleftheria Stein
3995f8bf65 Upgrade Spring Framework to 5.3.16
Closes gh-2028
2022-02-22 10:25:32 +01:00
Eleftheria Stein
ad16f17398 Upgrade Spring Data to 2021.1.2
Closes gh-2032
2022-02-22 10:24:56 +01:00
Eleftheria Stein
11aa50e83c Upgrade Spring Security to 5.6.2
Closes gh-2030
2022-02-22 10:24:32 +01:00
Eleftheria Stein
34199baded Update Websocket sample to be compatible with H2 2.0
Closes gh-2013
2022-01-27 14:12:23 +01:00
Eleftheria Stein
ab5c727846 Update Websocket sample to be compatible with H2 2.0
Closes gh-2013
2022-01-27 14:11:26 +01:00
Eleftheria Stein
a0246a61b6 Update to jakarta.servlet-api dependency
Closes gh-1960
2022-01-25 13:26:47 +01:00
Eleftheria Stein
8f20fa328a Update to jakarta.annotation-api dependency
Closes gh-1956
2022-01-25 12:50:29 +01:00
Eleftheria Stein
44ff959c59 Include 2.6.x branch in Antora docs
Issue gh-2014
2022-01-21 10:13:52 +01:00
Eleftheria Stein
ad67a3775b Add manual trigger to antora generate workflow
Issue gh-2014
2022-01-20 13:52:11 +01:00
Eleftheria Stein
75c60b27bd Exclude 3.0.0-M1 and 2.7.0-M1 tags from antora
Closes gh-2014
2022-01-20 13:22:31 +01:00
Ruslan Molchanov
12ce8de84e Fix memory leak with null principal in Redis
Closes gh-1987
2022-01-20 10:05:05 +01:00
Ruslan Molchanov
cc5bb1f3a2 Fix memory leak with null principal in Redis 2022-01-20 09:52:44 +01:00
Ruslan Molchanov
81bd6bd261 Fix memory leak with null principal in Redis
Closes gh-1987
2022-01-19 17:31:35 +01:00
Eleftheria Stein
2e8c4292fd Next development version 2022-01-18 13:01:30 +01:00
Eleftheria Stein
315b9c9929 Release 2.7.0-M1 2022-01-18 12:51:40 +01:00
Eleftheria Stein
48cf6849fe Next development version 2022-01-18 12:30:47 +01:00
Eleftheria Stein
0940451d50 Release 3.0.0-M1 2022-01-18 11:34:31 +01:00
Eleftheria Stein
a70abd90bd Upgrade test dependencies 2022-01-18 11:29:58 +01:00
Eleftheria Stein
f13df5aa2f Revert "Upgrade test dependencies"
This reverts commit bda72c074f.
2022-01-18 11:14:02 +01:00
Eleftheria Stein
6fd68e093f Upgrade Spring Data to 2021.2.0-M2
Closes gh-1996
2022-01-18 10:47:16 +01:00
Eleftheria Stein
653d820290 Update antora tags to include 3.0 2022-01-18 10:35:06 +01:00
Eleftheria Stein
304a6762b6 Update license acceptance for test container 2022-01-18 10:11:54 +01:00
Eleftheria Stein
b6417a9c7b Upgrade Spring Security to 6.0.0-M1
Closes gh-2010
2022-01-17 17:20:38 +01:00
Jerome Prinet
02885dca6d Bump up Gradle plugin dependencies 2022-01-17 17:20:02 +01:00
Jerome Prinet
950ac50234 Bump up Gradle plugin dependencies 2022-01-17 17:05:36 +01:00
Eleftheria Stein
bda72c074f Upgrade test dependencies 2022-01-17 14:51:48 +01:00
Eleftheria Stein
fb1362aa2c Upgrade Hazelcast 4 to 4.2.4
Closes gh-2001
2022-01-17 14:51:48 +01:00
Eleftheria Stein
d5dac6629d Upgrade Spring Security to 5.7.0-M1
Closes gh-1997
2022-01-17 14:51:45 +01:00
Eleftheria Stein
04b4b9ba17 Upgrade Spring Framework to 5.3.15
Closes gh-1998
2022-01-17 14:51:18 +01:00
Eleftheria Stein
97308bdbf4 Upgrade Jackson to 2.13.1
Closes gh-2002
2022-01-17 14:50:38 +01:00
Eleftheria Stein
4ba62c71dd Upgrade MongoDB to 4.4.1
Closes gh-2000
2022-01-17 14:50:38 +01:00
Eleftheria Stein
88aa71b3f3 Upgrade test dependencies 2022-01-17 14:17:37 +01:00
Eleftheria Stein
499cb75b1b Upgrade Hazelcast to 5.0.2
Closes gh-2011
2022-01-17 14:06:55 +01:00
Eleftheria Stein
104bcefbc1 Upgrade Reactor to 2020.0.15
Closes gh-2009
2022-01-17 13:56:33 +01:00
Eleftheria Stein
265099c586 Upgrade Reactor to 2020.0.15
Closes gh-1999
2022-01-17 09:41:09 +01:00
Eleftheria Stein
029d2cf3de Upgrade MongoDB to 4.4.1
Closes gh-2004
2022-01-17 09:38:52 +01:00
Eleftheria Stein
108e108e47 Upgrade Jackson to 2.13.1
Closes gh-2003
2022-01-17 09:38:30 +01:00
Eleftheria Stein
1bc3bd2e6f Upgrade Spring Framework to 6.0.0-M2
Closes gh-2005
2022-01-14 17:18:12 +01:00
Eleftheria Stein
24a3203755 Upgrade Spring Data to 2022.0.0-M1
Closes gh-2006
2022-01-14 17:11:16 +01:00
Jerome Prinet
77230a3318 Bump up Gradle enterprise plugin to 3.7.2 2022-01-14 16:30:49 +01:00
Eleftheria Stein
b5cdb193a8 GitHub Actions uses spring-builds+github user
This is more clear than spring-builds user
2022-01-14 16:28:23 +01:00
Eleftheria Stein
88e213d6a9 Update README to include MongoDB
Issue gh-1901
2022-01-14 16:28:16 +01:00
Eleftheria Stein
2f4a0110ab Update to jakarta.servlet-api dependency
Closes gh-1960
2022-01-14 16:21:35 +01:00
Eleftheria Stein
7a1cb66dae Update to jakarta.annotation-api dependency
Closes gh-1956
2022-01-14 16:19:22 +01:00
Jerome Prinet
9bad2afa14 Bump up Gradle enterprise plugin to 3.7.2 2022-01-05 14:34:51 +01:00
Eleftheria Stein
dba22292a3 Run CI on all branches 2022-01-05 14:29:57 +02:00
Eleftheria Stein
c79173879f Run CI on all branches 2022-01-05 14:29:28 +02:00
Eleftheria Stein
2c065c0241 Next minor development version 2022-01-05 14:28:19 +02:00
Eleftheria Stein
a08c721118 Next development version 2021-12-21 16:31:16 +02:00
Eleftheria Stein
70e0c6d22d Update antora version 2021-12-21 15:44:58 +02:00
Eleftheria Stein
61bf2eca49 Release 2.6.1 2021-12-21 15:12:26 +02:00
Eleftheria Stein
59923121f0 Make gretty samples compatible with logback 1.2.9
Explicitly reference the logback.xml file to prevent gretty from configuring the defaults using groovy.
2021-12-21 11:10:33 +02:00
Eleftheria Stein
b5f8e29585 Upgrade test dependencies 2021-12-21 11:10:22 +02:00
Eleftheria Stein
307a1f0dde Upgrade Hazelcast 4 to 4.2.3
Closes gh-1979
2021-12-21 10:09:06 +02:00
Eleftheria Stein
ced2d8421c Upgrade Spring Security to 5.6.1
Closes gh-1978
2021-12-21 10:08:25 +02:00
Eleftheria Stein
d98ff97e1a Upgrade Spring Framework to 5.3.14
Closes gh-1977
2021-12-21 10:03:02 +02:00
Eleftheria Stein
757175516f Upgrade Reactor to 2020.0.14
Closes gh-1976
2021-12-21 10:02:30 +02:00
Eleftheria Stein
8ae55b7ee4 GitHub Actions uses spring-builds+github user
This is more clear than spring-builds user
2021-12-07 15:43:42 +01:00
Eleftheria Stein
1eb53ead9d Update README to include MongoDB
Issue gh-1901
2021-11-26 17:37:12 +01:00
Eleftheria Stein
ec9db3fb5e Upgrade MongoDB to 4.4.0
Closes gh-1967
2021-11-19 17:25:14 +01:00
Guillaume Husta
91f20ca58c Doc : typo on Username _user-
user should be in italic
2021-11-19 15:14:58 +01:00
Eleftheria Stein
dc7a52b350 Update to Gradle 7.3
Closes gh-1959
2021-11-19 15:13:41 +01:00
Guillaume Husta
72159794f4 Doc : typo on Username _user-
user should be in italic
2021-11-19 14:56:56 +01:00
Eleftheria Stein
aaf122f3a6 Include 2.6.0 and 3.0 snapshots in reference docs 2021-11-17 11:28:54 +01:00
Eleftheria Stein
6f823805f2 Include 2.6.8 release in docs 2021-11-17 11:04:55 +01:00
Eleftheria Stein
7807aa9f3c Next development version 2021-11-16 18:56:49 +01:00
Eleftheria Stein
76924bc923 Release 2.6.0 2021-11-16 14:21:51 +01:00
Eleftheria Stein
134f89dd41 Upgrade test dependencies 2021-11-16 13:57:45 +01:00
Eleftheria Stein
33812f7197 Upgrade MongoDB to 4.4.0
Closes gh-1967
2021-11-16 13:56:44 +01:00
Eleftheria Stein
bcf17ba3b7 Upgrade samples to Spring Boot 2.5.6
Closes gh-1966
2021-11-16 13:37:41 +01:00
Eleftheria Stein
98f656ad46 Upgrade Jackson to 2.13.0
Closes gh-1965
2021-11-16 13:11:51 +01:00
Eleftheria Stein
7832942752 Upgrade Spring Security to 5.6.0
Closes gh-1964
2021-11-16 13:07:43 +01:00
Eleftheria Stein
722069a5f8 Upgrade Spring Data to 2021.1.0
Closes gh-1963
2021-11-16 13:06:41 +01:00
Eleftheria Stein
addbdbc1a2 Upgrade Spring Framework to 5.3.13
Closes gh-1962
2021-11-16 13:05:51 +01:00
Eleftheria Stein
004466ed07 Upgrade Reactor to 2020.0.13
Closes gh-1961
2021-11-16 13:04:32 +01:00
Eleftheria Stein
aeb5bc545c Update to Gradle 7.3
Closes gh-1959
2021-11-15 09:59:22 +01:00
Eleftheria Stein
979598e3c3 Re-enable Hazelcast support
Closes gh-1958
2021-11-12 16:43:30 +01:00
Eleftheria Stein
2113c32ed0 Upgrade to Hazelcast 5
Closes gh-1957
2021-11-12 16:43:02 +01:00
Eleftheria Stein
73149d2130 Enable CI 2021-11-12 12:16:21 +01:00
Eleftheria Stein
20e1fa10d9 Use JDK 11 in buildSrc 2021-11-12 12:05:36 +01:00
Eleftheria Stein
43e3c27169 Use Java 17 in deploy reference workflow
Issue gh-1945
2021-11-12 11:44:31 +01:00
Eleftheria Stein
f93d0be10e Correct version in antora.yml 2021-11-12 11:36:02 +01:00
Eleftheria Stein
d5ebb14f8d Temporarily remove unsupported samples
Closes gh-1955
2021-11-12 11:18:00 +01:00
Eleftheria Stein
00ba1b2028 Temporarily remove Hazelcast support
Closes gh-1954
2021-11-12 11:14:47 +01:00
Eleftheria Stein
cc1fd826ac Remove unnecessary code from samples
Remove code that is not necessary to demonstrate Spring Session functionality and is not compatible with the Java 17 / Jakarta EE 9 upgrades.

Issue gh-1949
2021-11-12 10:42:23 +01:00
Eleftheria Stein
fc5f875036 Upgrade Javaconfig samples to Gretty 4
Closes gh-1953
2021-11-12 10:42:14 +01:00
Eleftheria Stein
8e8cc7b1f0 Upgrade to Spring Security 6
Closes gh-1952
2021-11-12 10:34:27 +01:00
Eleftheria Stein
c2ed6a31be Upgrade to Spring Data 2022.1
Closes gh-1951
2021-11-12 10:34:27 +01:00
Eleftheria Stein
a9b9ae347f Upgrade to Spring Framework 6.0
Closes gh-1950
2021-11-12 10:34:27 +01:00
Eleftheria Stein
f697850d23 Remove Hazelcast 3 support
Closes gh-1947
2021-11-12 10:34:11 +01:00
Eleftheria Stein
182d24219c Migrate to Jakarta EE 9
Closes gh-1949
2021-11-11 18:21:26 +01:00
Eleftheria Stein
712e7d5a41 Upgrade to Java 17 baseline
Closes gh-1945
2021-11-11 18:05:15 +01:00
Eleftheria Stein
09ea3e4d39 Update to Spring Session 3.0 2021-11-11 18:02:38 +01:00
Rob Winch
37451d945c Update Algolia index to uses reference 2021-11-11 10:06:13 -06:00
Rob Winch
9e5b1951d5 Antora /reference/ suffix to site URL 2021-11-11 09:48:38 -06:00
Rob Winch
406f11c9ab Antora Fix site url 2021-11-11 09:43:11 -06:00
Rob Winch
beeb8769a6 rsync --delete old files 2021-11-11 09:40:16 -06:00
Rob Winch
a60b54812a Fix Antora version
- 2.6.0
- prelease -SNAPSHOT
2021-11-11 09:32:18 -06:00
Rob Winch
59bfa6bbc7 Antora component name to ROOT 2021-11-11 09:31:42 -06:00
Rob Winch
353f635470 Use correct output directory for docs deploy 2021-11-10 17:40:23 -06:00
Rob Winch
dd63b760bc Use ALGOLIA_WRITE_API_KEY 2021-11-10 15:33:24 -06:00
Rob Winch
d8347bcdb1 Deploy Docs 2021-11-10 14:13:05 -06:00
Rob Winch
a51f1e1679 Add Algolia Index 2021-11-10 14:13:05 -06:00
Rob Winch
98a07a16d3 Generate and Request Reference Build 2021-11-10 14:13:05 -06:00
Rob Winch
d756446015 Add playbook to Spring Session 2021-11-10 14:13:05 -06:00
Eleftheria Stein
147ea82a43 Use BDD mockito style
Issue gh-1946
2021-11-09 14:36:53 +01:00
Eleftheria Stein
b4bbbe8bd6 Fix Javadoc tag order
Issue gh-1946
2021-11-09 14:36:53 +01:00
Eleftheria Stein
ea1c619918 Fix whitespace
Issue gh-1946
2021-11-09 14:36:53 +01:00
Eleftheria Stein
5c2eb3af1c Remove unnecessary non-Javadoc keyword
Issue gh-1946
2021-11-09 14:36:53 +01:00
Eleftheria Stein
09a74bf165 Upgrade checkstyle to 0.0.29
Closes gh-1946
2021-11-09 13:41:50 +01:00
Rob Winch
619ad95ef7 Add spring-boot-version to docs 2021-11-08 13:46:27 -06:00
Rob Winch
6e6695bad9 Direct Mapping of Documentation Version 2021-11-08 09:51:54 -06:00
Eleftheria Stein
5fdbfce4c2 Update Gradle to 7.2
Closes gh-1944
2021-11-02 14:28:31 +01:00
Eleftheria Stein
a5033f721c Use local propdeps plugin
Issue gh-1944
2021-11-02 14:12:19 +01:00
Eleftheria Stein
23882acf97 Remove dependency on JUnit 4
Closes gh-1879
2021-11-01 10:37:18 +01:00
Eleftheria Stein
2110ef0c2d Fix scm attributes in maven pom.xml
Closes gh-1897
2021-10-29 15:40:06 +02:00
Eleftheria Stein
e5bc746e37 Update GitHub Actions to use publishArtifacts
Closes gh-1943
2021-10-29 14:10:24 +02:00
Eleftheria Stein
84fab2e2a9 Add buildSrc including build conventions plugins
Closes gh-1942
2021-10-29 13:30:29 +02:00
Eleftheria Stein
b6f90640a6 Use updated version names in docs
Issue gh-1942
2021-10-29 13:27:12 +02:00
Eleftheria Stein
327e7fb9b7 Add missing method for docs
Issue gh-1942
2021-10-28 11:19:48 +02:00
Eleftheria Stein
d3a19efb89 Resolve versions in docs from classpath
Issue gh-1942
2021-10-28 10:56:24 +02:00
Rob Winch
0004664603 Fix symlink to not end in / 2021-10-27 16:05:13 -05:00
Rob Winch
1cdf77330c Fix missing attribute
- Use spring-session-data-mongodb-dir
- Update example to use symlink location
2021-10-26 20:50:57 -05:00
Rob Winch
517c767bf6 Use dynamic version 2021-10-26 16:36:37 -05:00
Eleftheria Stein
b79b069178 Fix API link in docs
Closes gh-1940
2021-10-26 10:17:36 +02:00
Rob Winch
fee6878ef1 Extract the branch name for generated docs 2021-10-25 16:10:56 -05:00
Rob Winch
31caeb24f7 Fix version to have space in yml 2021-10-21 12:07:40 -05:00
Rob Winch
7798d6bbf2 Use version in URLs 2021-10-21 11:07:31 -05:00
Eleftheria Stein
cb16e2ff9e Next development version 2021-10-20 13:40:30 +02:00
Eleftheria Stein
e02a38965f Release 2.5.0-RC2 2021-10-20 12:56:36 +02:00
Greg L. Turnquist
bf139dbbb3 Introduce Spring Session MongoDB
* Migrate the module's code back into this project.
* Fold the documentation in.
* Update to current Gradle conventions.
* Reformat to match styling.
2021-10-20 11:57:27 +02:00
Eleftheria Stein
d10c18eb88 Next development version 2021-10-19 11:51:02 +02:00
Eleftheria Stein
8af09781a0 Release 2.6.0-RC1 2021-10-19 11:38:25 +02:00
Eleftheria Stein
845c7aca84 Upgrade test dependencies 2021-10-19 11:14:03 +02:00
Eleftheria Stein
b05575722c Upgrade samples to Spring Boot 2.5.5
Closes gh-1929
2021-10-19 10:54:01 +02:00
Eleftheria Stein
ee0e03b91e Upgrade Spring Security to 5.6.0-RC1
Closes gh-1928
2021-10-19 10:39:06 +02:00
Eleftheria Stein
7864f9c4cc Upgrade Spring Framework to 5.3.11
Closes gh-1927
2021-10-19 10:37:19 +02:00
Eleftheria Stein
227aee8e3a Upgrade Reactor to 2020.0.12
Closes gh-1925
2021-10-19 10:36:09 +02:00
Eleftheria Stein
bf2aaa0033 Upgrade Spring Data to 2021.1.0-RC1
Closes gh-1926
2021-10-19 10:35:39 +02:00
Eleftheria Stein
eb9f62a437 Update principal index on session ID change
Closes gh-1791
2021-10-14 17:49:56 +02:00
Rob Winch
418cb60f39 Add antora gradle plugin
You can now run the following to generate the antora site

./gradlew antora

It will appear at build/site/index.html
2021-10-11 09:17:50 -05:00
Rob Winch
4339b8ae9d Fix local-antora-playbook.yml
- Point to generated content
- Point to remote antora-ui-spring
2021-10-11 09:16:55 -05:00
Eleftheria Stein
63f706dbf9 Fix Hazelcast session with flush mode immediate
Closes gh-1921
2021-10-05 10:59:06 +02:00
Eleftheria Stein
beb7b334c4 Fix link to Spring Security remember-me docs
Closes gh-1915
2021-10-04 16:34:52 +02:00
Eleftheria Stein
a64a11ba03 Tests for Hazelcast flush mode immediate
Closes gh-1801
2021-10-01 17:02:33 +02:00
slondono
661ecaf371 Store Principal Name Index in the Hazelcast Session delta
Issue gh-1801
2021-10-01 17:02:33 +02:00
Rob Winch
378ba6db2c Use GH_ACTIONS_REPO_TOKEN 2021-09-27 13:22:20 -05:00
zhaokai
9659f1f571 Modify to support negative numbers 2021-09-27 14:40:16 +02:00
Eleftheria Stein
919a2a5c49 Upgrade back to Spring Boot 2.5.3 2021-09-24 16:46:32 +02:00
Rob Winch
4dee8063c6 Use Antora
Closes gh-1237
2021-09-23 16:44:39 -05:00
Eleftheria Stein
9ad871a30b Add setter for autowired field in SpringWebSessionConfiguration
Closes gh-1918
2021-09-23 14:54:22 +02:00
Eleftheria Stein
e7d58f6b03 Increase session timeout in Hazelcast tests
It's possible that the session is expiring before the assertions can be made in the tests, causing them to fail.

Issue gh-1912
2021-09-08 12:04:26 +02:00
Rob Winch
3d118242ee Better hiearchy with Samples nav 2021-08-31 10:38:54 -05:00
Rob Winch
0c00ff0598 Fix Samples nav 2021-08-30 19:12:50 -05:00
Rob Winch
3d93bfc28b Fix Boot Samples Nav 2021-08-30 19:08:46 -05:00
Rob Winch
297ff83775 Added missing versions 2021-08-30 19:07:17 -05:00
Rob Winch
1fc2c430f1 Fix antora name 2021-08-30 19:01:52 -05:00
Rob Winch
5757e94658 Generated antora.yml 2021-08-30 18:55:11 -05:00
Rob Winch
8cc22a1712 Use versionless URL 2021-08-30 17:17:34 -05:00
Vedran Pavic
79fbca24eb Make Hazelcast session repository bean factory return type more specific
The declared return type of Hazelcast session repository bean factory method (i.e. HazelcastHttpSessionConfiguration#sessionRepository) was changed to SessionRepository<?> when support for Hazelcast 4 was added. This breaks Spring Boot's ability to auto-configure sessions endpoint, which is @ConditionalOnBean(FindByIndexNameSessionRepository.class), as the current return type is not specific enough to satisfy this condition.

This commit changes the return type of Hazelcast session repository bean factory method to FindByIndexNameSessionRepository<?>.

Closes: gh-1905
2021-08-27 01:51:55 +02:00
Vedran Pavic
5b7aee7199 Fix Spring Boot based Hazelcast samples
This commit removes unused Hazelcast client dependencies and test support from Spring Boot based Hazelcast samples.

Closes: gh-1902
2021-08-27 00:46:23 +02:00
Andreas Kasparek
c5bffde790 Always set time-to-live within entry processor
Closes gh-1899
2021-08-25 13:16:08 +02:00
Rob Winch
aee65ffec8 Remove :toc: left
This causes an extra toc that covers the left navigation
2021-08-20 14:29:21 -05:00
Rob Winch
00abd345ac Add Dispatch to build reference 2021-08-18 11:27:45 -05:00
Rob Winch
0864140dda Clean up introduction 2021-08-18 11:19:21 -05:00
Rob Winch
7babddf15f Fix default xref text 2021-08-18 11:16:36 -05:00
Rob Winch
764fc4eea6 <<>> to xref 2021-08-18 11:15:27 -05:00
Rob Winch
26419e2149 Cleanup Antora 2021-08-18 11:10:33 -05:00
Eleftheria Stein
585d3695ad Point to spring-session tag in GitHub issue template
Issue: gh-1897
2021-08-18 14:06:12 +02:00
Eleftheria Stein
db8a3aa604 Next development version 2021-08-17 15:52:29 +02:00
Eleftheria Stein
d0fabc0a35 Release 2.6.0-M1 2021-08-17 15:50:52 +02:00
Eleftheria Stein
cae8b51eab Upgrade test dependencies 2021-08-17 15:14:03 +02:00
Eleftheria Stein
2236449635 Revert "Upgrade test dependencies"
This reverts commit 9fde87c11b.
2021-08-17 14:07:13 +02:00
Eleftheria Stein
d862836d41 Upgrade Hazelcast 4 to 4.2.2
Closes gh-1887
2021-08-17 13:45:48 +02:00
Eleftheria Stein
4008afe47b Upgrade Spring Security to 5.6.0-M2
Closes gh-1884
2021-08-17 13:29:58 +02:00
Eleftheria Stein
9fde87c11b Upgrade test dependencies 2021-08-17 13:23:08 +02:00
Rob Winch
faa6c441fa Antora 2021-08-16 15:44:15 -05:00
Eleftheria Stein
93c62104ee Make Websocket sample compatible with Spring Boot 2.5.3
Closes gh-1886
2021-08-16 15:08:38 +02:00
Eleftheria Stein
8fdcfc28bc Upgrade samples to Spring Boot 2.5.3
Closes gh-1885
2021-08-16 15:08:09 +02:00
Eleftheria Stein
1f6445999f Upgrade Spring Framework to 5.3.9
Closes gh-1882
2021-08-16 14:00:02 +02:00
Eleftheria Stein
cf4aeae02a Upgrade Spring Data to 2021.1.0-M2
Closes gh-1883
2021-08-16 13:59:25 +02:00
Eleftheria Stein
f8dcee7304 Upgrade Reactor to 2020.0.10
Closes gh-1881
2021-08-16 13:57:00 +02:00
Eleftheria Stein
971a2d17d9 Set cookie path to context path without trailing slash
Closes gh-1863
2021-07-20 10:00:53 +02:00
Ellie Bahadori
8b5b3701da Prevent builds from running on forks
Resolves gh-1678
2021-07-06 17:19:30 +02:00
Eleftheria Stein
21c9fb0cfa Point "What's New" section to Wiki
Closes gh-1878
2021-06-29 16:08:03 +02:00
Jay Bryant
33993b2ff6 Add links to Mongo and Geode docs
Spring Session for MongoDB and Geodo have their own reference guides.
This PR adds links to them.
2021-06-14 13:34:36 +02:00
Jay Bryant
9f4a723160 Add links to the other documentation format
Add a link from the HTML to the PDF and vice-versa.
2021-06-04 08:55:57 +02:00
Eleftheria Stein
25032fbd61 Use GPG_PRIVATE_KEY directly in build
Closes gh-1861
2021-05-31 15:42:16 +03:00
Eleftheria Stein
d195579ced Next development version 2021-05-19 00:41:23 +02:00
Eleftheria Stein
b1d68c0731 Release 2.5.0 2021-05-19 00:13:33 +02:00
Eleftheria Stein
7ec5add1bd Configure user name for Gradle CI builds
This reverts commit e41ebd8a77.
2021-05-19 00:13:17 +02:00
Eleftheria Stein
05e103d9c5 Use GPG_PRIVATE_KEY_NO_HEADER secret in CI
Issue gh-1812
2021-05-19 00:09:26 +02:00
Eleftheria Stein
8190072d3f Revert "Release 2.5.0"
This reverts commit ce16374c15.
2021-05-19 00:08:02 +02:00
Eleftheria Stein
ce16374c15 Release 2.5.0 2021-05-18 22:24:46 +02:00
Eleftheria Stein
e41ebd8a77 Revert "Configure user name for Gradle CI builds"
This reverts commit ce938fd2fe.
2021-05-18 22:22:37 +02:00
Eleftheria Stein
8550aeca5c Revert "Release 2.5.0"
This reverts commit 5cb8a6b79a.
2021-05-18 22:22:21 +02:00
Eleftheria Stein
5cb8a6b79a Release 2.5.0 2021-05-18 13:28:56 +02:00
Eleftheria Stein
5b48e7e8e7 Upgrade Spring Security to 5.5.0
Closes gh-1856
2021-05-18 10:00:37 +02:00
Eleftheria Stein
9e2b729d62 Upgrade test dependencies 2021-05-17 17:45:47 +02:00
Eleftheria Stein
524ee0d9bc Upgrade samples to Spring Boot 2.4.5
Closes gh-1855
2021-05-17 17:20:46 +02:00
Eleftheria Stein
26be3218fb Upgrade Spring Framework to 5.3.7
Closes gh-1853
2021-05-17 17:12:53 +02:00
Eleftheria Stein
8d4fd80add Upgrade Spring Data to 2021.0.1
Closes gh-1854
2021-05-17 17:12:25 +02:00
Eleftheria Stein
6969ea0049 Upgrade Reactor to 2020.0.7
Closes gh-1852
2021-05-17 17:11:01 +02:00
Eleftheria Stein
ce938fd2fe Configure user name for Gradle CI builds
Closes gh-1851
2021-05-14 12:32:29 +02:00
weix sun
98d7448b40 Fix broken Framework link in reference docs 2021-05-11 11:18:52 +02:00
Eleftheria Stein
4bb2bd6fda JDBC session with negative timeout should never expire
Closes gh-1847
2021-05-10 16:38:30 +02:00
Eleftheria Stein
0e5dd1863f Rename master branch to main
Closes gh-1846
2021-04-28 17:19:52 +02:00
Eleftheria Stein
548b58ee55 Next development version 2021-04-13 12:43:12 +02:00
Eleftheria Stein
bb28af9934 Release 2.5.0-RC1 2021-04-13 12:28:27 +02:00
Eleftheria Stein
dee8402473 Upgrade test dependencies 2021-04-13 12:12:17 +02:00
Eleftheria Stein
7bd0b45f29 Upgrade samples to Spring Boot 2.4.4
Closes gh-1822
2021-04-13 12:01:37 +02:00
Eleftheria Stein
b42b01af9b Upgrade Hazelcast 4 to 4.2
Closes gh-1821
2021-04-13 11:31:58 +02:00
Eleftheria Stein
6744fee3cb Upgrade Hazelcast to 3.12.12
Closes gh-1820
2021-04-13 11:22:00 +02:00
Eleftheria Stein
6811f25565 Upgrade Spring Security to 5.5.0-RC1
Closes gh-1819
2021-04-13 11:21:10 +02:00
Eleftheria Stein
47817c46e1 Upgrade Spring Data to 2021.0.0-RC1
Closes gh-1818
2021-04-13 11:20:20 +02:00
Eleftheria Stein
4f7c6406ad Upgrade Spring Framework to 5.3.5
Closes gh-1817
2021-04-13 11:19:27 +02:00
Eleftheria Stein
34cc1d1171 Upgrade Reactor to 2020.0.6
Closes gh-1816
2021-04-13 11:18:29 +02:00
Josh Cummings
9e7d9912e5 Change to GPG_PRIVATE_KEY_NO_HEADER
Closes gh-1812
2021-03-30 13:32:28 -06:00
Eleftheria Stein
d2960b570f Polish gh-1798
- Should throw IllegalStateException
2021-03-25 09:55:32 +02:00
Eleftheria Stein
8bd4374909 Throw exception if session created after response
Closes gh-1798
2021-03-25 09:27:27 +02:00
Eleftheria Stein
15f29f8adf Fix README formatting 2021-03-22 12:48:34 +02:00
Eleftheria Stein
74d53e8bfc Add additional information to README 2021-03-22 12:45:51 +02:00
Eleftheria Stein
77deb63373 Fix SessionRepositoryFilter Javadoc 2021-03-17 16:39:45 +01:00
Stefan Wurzinger
69285f2a9a Fix Redis session expiration entry deletion
Closes gh-585
2021-03-12 16:24:48 +01:00
Eleftheria Stein
c93513f18f Fix typo in reference docs 2021-02-09 16:12:51 +01:00
Eleftheria Stein
27044c8766 Make Hazelcast tests independent of ordering
Closes gh-1787
2021-02-02 13:24:24 +01:00
Eleftheria Stein
b198844671 Use io.spring.gradle-enterprise-conventions
Adds support for build cache and build scans

Closes gh-1713
2021-02-01 18:14:28 +01:00
Eleftheria Stein
0f27bbaff7 Update to gradle 6.8.1
Closes gh-1785
2021-02-01 17:32:09 +01:00
Eleftheria Stein
62ad3e1bab Replace deprecated verifyZeroInteractions in tests 2021-01-29 17:00:03 +01:00
Eleftheria Stein
7eed8427a5 Use spring-build-conventions:0.0.37 2021-01-27 11:09:43 +01:00
Eleftheria Stein
4cbb253c11 Resolve artifacts from Maven Central first
- Use spring-build-conventions:0.0.36
- Add https://repo.spring.io/release to reference

Closes gh-1778
2021-01-22 15:27:06 +01:00
Eleftheria Stein
3fe03c60f3 Add manual trigger to CI workflow
Closes gh-1777
2021-01-19 17:37:18 +01:00
Eleftheria Stein
d95652dcb3 Next development version 2021-01-19 14:19:49 +01:00
Eleftheria Stein
cfc1a1e7ce Release 2.5.0-M1 2021-01-19 13:55:51 +01:00
Eleftheria Stein
e17d0cc1d9 Upgrade test dependencies 2021-01-18 12:54:54 +01:00
Eleftheria Stein
0a0766e4a8 Upgrade Hazelcast 4 to 4.1.1
Closes gh-1761
2021-01-18 12:43:34 +01:00
Eleftheria Stein
4108c77797 Upgrade Hazelcast to 3.12.11
Closes gh-1760
2021-01-18 12:41:02 +01:00
Eleftheria Stein
c015a69a4a Upgrade Spring Data to 2021.0.0-M2
Closes gh-1759
2021-01-18 12:39:30 +01:00
Eleftheria Stein
293cf3f730 Upgrade Spring Security to 5.5.0-M1
Closes gh-1758
2021-01-18 12:37:49 +01:00
Eleftheria Stein
6f79e87c8f Upgrade Spring Framework to 5.3.3
Closes gh-1757
2021-01-18 12:35:29 +01:00
Eleftheria Stein
d74c5b1445 Upgrade Reactor to 2020.0.3
Closes gh-1755
2021-01-18 12:34:01 +01:00
Eleftheria Stein
6075089691 Upgrade samples to Spring Boot 2.4.2
Closes gh-1756
2021-01-18 12:31:54 +01:00
Eleftheria Stein
e7a0924904 Upgrade test dependencies 2021-01-12 13:34:47 +01:00
daisuzz
319f0a97ad Fix example in RedisIndexedSessionRepository and Storage Details section
* Fix example in JavaDocs of RedisIndexedSessionRepository

* Fix example in Storage Details section of documentation
2021-01-04 09:32:44 +01:00
Eleftheria Stein
95de199aa4 Upgrade samples to Spring Boot 2.4.1
Closes gh-1744
2020-12-14 09:56:17 +01:00
Eleftheria Stein
db589b7c29 Update community extensions section of reference manual
Closes gh-1736
2020-12-09 13:02:30 +01:00
Vedran Pavic
2aae51b1a1 Rationalize JDBC integration tests
This commit reduces the JDBC integration tests to only single (latest) version per RDBMS vendor, due to a growing number of integration tests. Additionally, the configuration of most containers is simplified due to improved defaults within the Testcontainers library.
2020-11-28 00:26:17 +01:00
Vedran Pavic
e721efeb85 Optimize insert attribute statement in JdbcIndexedSessionRepository
At present, the SQL statement used to insert a session attribute record contains a nested select statement that verifies the existence of parent record in the session table. Such approach can be susceptible to deadlocks on certain RDMBSs.

This commit optimizes the SQL statement used to insert session attribute so that it doesn't perform a nested select statement.

Closes: #1550
2020-11-28 00:26:17 +01:00
Vedran Pavic
0111c6e686 Provide database specific JdbcIndexedSessionRepository customizers
This commit provides JdbcIndexedSessionRepository customizers for the following SQL dialects:

- PostgreSQL
- MySQL (also used by MariaDB)
- SQL Server
- IBM DB2
- Oracle

These customizers are intended to address the concurrency issues occurring on insert of new session attribute by applying SQL dialect specific SQL upsert/merge statement instead of a generic insert.

Closes: #1213
2020-11-27 23:54:03 +01:00
Eleftheria Stein
07058c0cdf Add artifactory credentials to build 2020-11-17 13:59:06 +01:00
Thomas Heigl
5f5168814d Delay allocating Strings for message channel and body 2020-11-10 08:03:57 -05:00
Vedran Pavic
55502f336d Harmonize Redis key namespace configurations
At present, the RedisSessionRepository#setKeyNamespace expects users to provide the trailing colon (:) character that is used as separator between namespace segments. This is unlike RedisIndexedSessionRepository and ReactiveRedisSessionRepository that apply the separator implicitly in their respective #setRedisKeyNamespace methods.

This commit harmonizes the Redis key namespaces configurations across all Redis-backed session repository implementations.
2020-11-10 06:55:19 -05:00
Eleftheria Stein
0e83e3f1e0 Next development version 2020-11-10 11:48:27 +01:00
544 changed files with 21114 additions and 7817 deletions

6
.gitattributes vendored Normal file
View File

@@ -0,0 +1,6 @@
* text eol=lf
*.bat text eol=crlf
*.jar binary
*.jpg binary
*.png binary
*.mmdb binary

17
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,17 @@
<!--
!!! For Security Vulnerabilities, please go to https://spring.io/security-policy !!!
-->
**Affects:** \<Spring Framework version>
---
<!--
Thanks for taking the time to create an issue. Please read the following:
- Questions should be asked on Stack Overflow.
- For bugs, specify affected versions and explain what you are trying to do.
- For enhancements, provide context and describe the problem.
Issue or Pull Request? Create only one, not both. GitHub treats them as the same.
If unsure, start with an issue, and if you submit a pull request later, the
issue will be closed as superseded.
-->

View File

@@ -1,5 +1,5 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: Community Support - name: Community Support
url: https://stackoverflow.com/questions/tagged/spring-security url: https://stackoverflow.com/questions/tagged/spring-session
about: Please ask and answer questions on StackOverflow with the tag spring-session about: Please ask and answer questions on StackOverflow with the tag spring-session

View File

@@ -2,23 +2,25 @@ name: CI
on: on:
push: push:
branches:
- master
schedule: schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC - cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch: # Manual trigger
env: env:
GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }} GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }}
GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'spring-projects/spring-session'
strategy: strategy:
matrix: matrix:
jdk: [8, 11] jdk: [17]
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@@ -26,55 +28,64 @@ jobs:
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: ${{ matrix.jdk }} java-version: ${{ matrix.jdk }}
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle
echo 'systemProp.user.name=spring-builds+github' >> ~/.gradle/gradle.properties
- name: Cache Gradle packages - name: Cache Gradle packages
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ~/.gradle/caches path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Build with Gradle - name: Build with Gradle
run: | run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew clean build --no-daemon --stacktrace ./gradlew clean build -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --no-daemon --stacktrace
artifacts: artifacts:
name: Deploy Artifacts name: Deploy Artifacts
needs: [build] needs: [build]
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'spring-projects/spring-session'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: '8' java-version: '17'
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle
echo 'systemProp.user.name=spring-builds+github' >> ~/.gradle/gradle.properties
- name: Deploy artifacts - name: Deploy artifacts
run: | run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
export VERSION_HEADER=$'Version: GnuPG v2\n\n' ./gradlew publishArtifacts finalizeDeployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace
export ORG_GRADLE_PROJECT_signingKey=${GPG_PRIVATE_KEY#"$VERSION_HEADER"}
export ORG_GRADLE_PROJECT_signingPassword="$GPG_PASSPHRASE"
./gradlew deployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
./gradlew finalizeDeployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
env: env:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }}
OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_TOKEN_USERNAME }} OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }}
OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_TOKEN_PASSWORD }} OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
docs: docs:
name: Deploy Docs name: Deploy Docs
needs: [build] needs: [build]
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'spring-projects/spring-session'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: '8' java-version: '17'
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle
echo 'systemProp.user.name=spring-builds+github' >> ~/.gradle/gradle.properties
- name: Deploy Docs - name: Deploy Docs
run: | run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"

30
.github/workflows/deploy-docs.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Deploy Docs
on:
push:
branches-ignore: [ gh-pages ]
tags: '**'
repository_dispatch:
types: request-build-reference # legacy
workflow_dispatch:
permissions: read-all
jobs:
build:
runs-on: ubuntu-latest
if: github.repository_owner == 'spring-projects'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: docs-build
fetch-depth: 1
- name: Dispatch (partial build)
if: github.ref_type == 'branch'
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }}
- name: Dispatch (full build)
if: github.ref_type == 'tag'
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD)

View File

@@ -0,0 +1,10 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1

View File

@@ -6,9 +6,10 @@ jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'spring-projects/spring-session'
strategy: strategy:
matrix: matrix:
jdk: [8, 11] jdk: [17]
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@@ -0,0 +1,20 @@
name: Rebuild Search Index
on:
schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch:
permissions: read-all
jobs:
build:
if: github.repository_owner == 'spring-projects'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: docs-build
fetch-depth: 1
- name: Dispatch
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
run: gh workflow run rebuild-search-index.yml -r $(git rev-parse --abbrev-ref HEAD)

2
.gitignore vendored
View File

@@ -14,3 +14,5 @@ out
!etc/eclipse/.checkstyle !etc/eclipse/.checkstyle
!**/src/**/build !**/src/**/build
.DS_Store .DS_Store
spring-session-docs/package-lock.json
spring-session-docs/node_modules/

6
.sdkmanrc Normal file
View File

@@ -0,0 +1,6 @@
# Use sdkman to run "sdk env" to initialize with correct JDK version
# Enable auto-env through the sdkman_auto_env config
# See https://sdkman.io/usage#config
# A summary is to add the following to ~/.sdkman/etc/config
# sdkman_auto_env=true
java=17.0.2-tem

View File

@@ -6,7 +6,7 @@ something, or simply want to hack on the code this document should help you get
== Code of Conduct == Code of Conduct
Please see our https://github.com/spring-projects/.github/blob/master/CODE_OF_CONDUCT.md[code of conduct] Please see our https://github.com/spring-projects/.github/blob/main/CODE_OF_CONDUCT.md[code of conduct].
== Reporting Security Vulnerabilities == Reporting Security Vulnerabilities
@@ -25,6 +25,12 @@ If you are reporting a bug, please help to speed up problem diagnosis by providi
information as possible. Ideally, that would include a small sample project that information as possible. Ideally, that would include a small sample project that
reproduces the problem. reproduces the problem.
== Create your branch from the oldest maintenance branch
Create your topic branch to be submitted as a pull request from the oldest impacted and supported maintenance branch.
You can find the supported versions by looking at the https://github.com/spring-projects/spring-session/milestones[milestones page].
Switch to a branch named `<major>.<minor>.x` from the smallest milestone in the format of `<major>.<minor>.<patch>(-<prerelease>)`.
The spring team will ensure the code gets merged forward into additional branches.
== Sign the Contributor License Agreement == Sign the Contributor License Agreement

View File

@@ -2,7 +2,7 @@
image:https://badges.gitter.im/spring-projects/spring-session.svg[link="https://gitter.im/spring-projects/spring-session?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] image:https://badges.gitter.im/spring-projects/spring-session.svg[link="https://gitter.im/spring-projects/spring-session?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
image:https://github.com/spring-projects/spring-session/workflows/CI/badge.svg?branch=master["Build Status", link="https://github.com/spring-projects/spring-session/actions?query=workflow%3ACI"] image:https://github.com/spring-projects/spring-session/workflows/CI/badge.svg?branch=main["Build Status", link="https://github.com/spring-projects/spring-session/actions?query=workflow%3ACI"]
Spring Session provides an API and implementations for managing a user's session information, while also making it trivial to support clustered sessions without being tied to an application container specific solution. Spring Session provides an API and implementations for managing a user's session information, while also making it trivial to support clustered sessions without being tied to an application container specific solution.
It also provides transparent integration with: It also provides transparent integration with:
@@ -13,27 +13,61 @@ It also provides transparent integration with:
== Modules == Modules
Spring Session consists of the following modules: This Spring Session repository consists of the following modules:
* Spring Session Core - provides core Spring Session functionalities and APIs * Spring Session Core - provides core Spring Session functionalities and APIs
* Spring Session Data Redis - provides `SessionRepository` and `ReactiveSessionRepository` implementation backed by Redis and configuration support * Spring Session Data Redis - provides `SessionRepository` and `ReactiveSessionRepository` implementation backed by Redis and configuration support
* Spring Session JDBC - provides `SessionRepository` implementation backed by a relational database and configuration support * Spring Session JDBC - provides `SessionRepository` implementation backed by a relational database and configuration support
* Spring Session Hazelcast - provides `SessionRepository` implementation backed by Hazelcast and configuration support * Spring Session Hazelcast - provides `SessionRepository` implementation backed by Hazelcast and configuration support
* Spring Session MongoDB - provides `SessionRepository` implementation backed by MongoDB and configuration support
Additional Spring Session modules can be found in the https://github.com/spring-projects/spring-session-data-geode[spring-session-data-geode] repository.
== Getting Started
We recommend you visit the https://docs.spring.io/spring-session/docs/current/reference/html5/#samples[Spring Session Reference] and look through the "Samples and Guides" section to see which one best suits your needs.
== Samples
Spring Session samples are available in the https://github.com/spring-projects/spring-session/tree/main/spring-session-samples[spring-session-samples] directory.
== Contributing
Please see our https://github.com/spring-projects/spring-session/blob/main/CONTRIBUTING.adoc[Contributing guidelines]
for information on how to report issues, enhancements or security vulnerabilities.
== Building from Source
Spring Session uses a https://gradle.org[Gradle]-based build system.
In the instructions below, `./gradlew` is invoked from the root of the source tree and serves as
a cross-platform, self-contained bootstrap mechanism for the build.
Check out sources
----
git clone git@github.com:spring-projects/spring-session.git
----
Install all spring-\* jars into your local Maven cache
----
./gradlew install
----
Compile and test; build all jars, distribution zips, and docs
----
./gradlew build
----
== Documentation
You can find the documentation, samples, and guides for using Spring Session on the https://projects.spring.io/spring-session/[Spring Session project site].
For more in depth information, visit the https://docs.spring.io/spring-session/reference/[Spring Session Reference].
== Code of Conduct == Code of Conduct
Please see our https://github.com/spring-projects/.github/blob/master/CODE_OF_CONDUCT.md[code of conduct] Please see our https://github.com/spring-projects/.github/blob/main/CODE_OF_CONDUCT.md[code of conduct].
== Reporting Security Vulnerabilities
Please see our https://github.com/spring-projects/spring-session/security/policy[Security policy].
== Spring Session Project Site
You can find the documentation, issue management, support, samples, and guides for using Spring Session at https://projects.spring.io/spring-session/
== License == License

110
RELEASE.adoc Normal file
View File

@@ -0,0 +1,110 @@
== 1. Update Dependencies
Dependencies are declared in `gradle/dependency-management.gradle`.
Update Spring Framework, Spring Security and Spring Data at a minimum.
Run all the checks:
[source,bash]
----
$ ./gradlew check
----
Create separate issues for each dependency update, aside from test dependencies which can be combined into a single commit.
== 2. Check All Issues are Closed
You can manually check at https://github.com/spring-projects/spring-session/milestones
== 3. Update Release Version
Update the version number in `gradle.properties` for the release, for example `3.0.0-M1`, `3.0.0-RC1`, `3.0.4`
== 4. Update Antora Version
You will need to update the antora.yml version.
For milestone / release candidate releases you should follow this format:
----
version: '3.0.0-RC1'
prerelease: 'true'
display_version: '3.0.0-RC1'
----
== 5. Build Locally
Run the build using
[source,bash]
----
$ ./gradlew check
----
== 6. Push the Release Commit
Push the commit and GitHub actions will build and deploy the artifacts.
Wait for the artifact to appear in https://repo1.maven.org/maven2/org/springframework/session/spring-session-core/
== 7. Tag the release
Tag the release and then push the tag
....
git tag 3.0.0-RC1
git push origin 3.0.0-RC1
....
== 8. Update to Next Development Version
Update `gradle.properties` version to next `+SNAPSHOT+` version, update antora.yml and then push
== 9. Update version on project pages
Update the versions on https://spring.io/projects for Spring Session Core, Spring Session Data Redis, Spring Session JDBC, Spring Session Hazelcast, and Spring Session MongoDB.
== 10. Update Release Notes on GitHub
Download
https://github.com/spring-io/github-changelog-generator/releases/latest[the
GitHub release notes generator]
* Generate the release notes
....
java -jar github-changelog-generator.jar \
--changelog.repository=spring-projects/spring-session \
$MILESTONE release-notes
....
Note 1: `+$MILESTONE+` is something like `+3.0.4+` or `+3.0.0-M1+`. +
Note 2: This will create a file on your filesystem
called `+release-notes+`.
* Copy the release notes to your clipboard (your mileage may vary with
the following command)
....
cat release-notes | xclip -selection clipboard
....
* Create the
https://github.com/spring-projects/spring-session/releases[release on
GitHub], associate it with the tag, and paste the generated notes.
== 11. Close / Create Milestone
* In
https://github.com/spring-projects/spring-session/milestones[GitHub
Milestones], create a new milestone for the next release version.
* Move any open issues from the existing milestone you just released to
the new milestone.
* Close the milestone for the release.
Note: Spring Session typically releases only one milestone (M1) and one release candidate (RC1).
== 12. Announce the release
* Announce via Slack on https://pivotal.slack.com/messages/spring-session[#spring-session], and tag any downstream Spring Session projects (e.g Spring Session for Apache Geode).
Note: Do not post on #spring-release or create a blog post. Those steps happen after the Spring Session BOM is released.

View File

@@ -4,17 +4,24 @@ buildscript {
snapshotBuild = version.endsWith('SNAPSHOT') snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild) milestoneBuild = !(releaseBuild || snapshotBuild)
springBootVersion = '2.4.0-M4' springBootVersion = '3.0.0-SNAPSHOT'
} }
repositories { repositories {
gradlePluginPortal() gradlePluginPortal()
maven { url 'https://repo.spring.io/plugins-release/' } maven { url 'https://repo.spring.io/plugins-release/' }
maven { url 'https://repo.spring.io/plugins-snapshot' } maven {
url = 'https://repo.spring.io/plugins-snapshot'
if (project.hasProperty('artifactoryUsername')) {
credentials {
username "$artifactoryUsername"
password "$artifactoryPassword"
}
}
}
} }
dependencies { dependencies {
classpath 'io.spring.gradle:spring-build-conventions:0.0.34.RELEASE'
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion" classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
} }
} }
@@ -28,10 +35,16 @@ subprojects {
apply plugin: 'io.spring.javaformat' apply plugin: 'io.spring.javaformat'
plugins.withType(JavaPlugin) { plugins.withType(JavaPlugin) {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_17
} }
tasks.withType(Test) { tasks.withType(Test) {
useJUnitPlatform() useJUnitPlatform()
} }
} }
nohttp {
source.exclude "buildSrc/build/**"
source.exclude "spring-session-docs/.gradle/nodejs/**"
source.exclude "spring-session-docs/modules/ROOT/examples/**/build/**"
}

92
buildSrc/build.gradle Normal file
View File

@@ -0,0 +1,92 @@
plugins {
id "java-gradle-plugin"
id "java"
id "groovy"
}
sourceCompatibility = JavaVersion.VERSION_11
repositories {
jcenter()
gradlePluginPortal()
mavenCentral()
maven { url 'https://repo.spring.io/plugins-release/' }
}
sourceSets {
main {
java {
srcDirs = []
}
groovy {
srcDirs += ["src/main/java"]
}
}
}
gradlePlugin {
plugins {
checkAntoraVersion {
id = "org.springframework.antora.check-version"
implementationClass = "org.springframework.gradle.antora.AntoraVersionPlugin"
}
managementConfiguration {
id = "io.spring.convention.management-configuration"
implementationClass = "io.spring.gradle.convention.ManagementConfigurationPlugin"
}
sagan {
id = "org.springframework.security.sagan"
implementationClass = "org.springframework.gradle.sagan.SaganPlugin"
}
githubMilestone {
id = "org.springframework.github.milestone"
implementationClass = "org.springframework.gradle.github.milestones.GitHubMilestonePlugin"
}
propdeps {
id = "org.springframework.propdeps"
implementationClass = "org.springframework.gradle.propdeps.PropDepsPlugin"
}
}
}
configurations {
implementation {
exclude module: 'groovy-all'
}
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
implementation 'net.sourceforge.saxon:saxon:9.1.0.8'
implementation 'org.yaml:snakeyaml:1.30'
implementation localGroovy()
implementation 'io.github.gradle-nexus:publish-plugin:1.1.0'
implementation 'io.spring.gradle:dependency-management-plugin:1.0.10.RELEASE'
implementation 'io.projectreactor:reactor-core:3.4.11'
implementation 'com.apollographql.apollo:apollo-runtime:2.4.5'
implementation 'com.github.ben-manes:gradle-versions-plugin:0.38.0'
implementation 'com.github.spullara.mustache.java:compiler:0.9.10'
implementation 'io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.34'
implementation 'io.spring.nohttp:nohttp-gradle:0.0.9'
implementation 'net.sourceforge.htmlunit:htmlunit:2.37.0'
implementation 'org.hidetake:gradle-ssh-plugin:2.10.1'
implementation 'org.jfrog.buildinfo:build-info-extractor-gradle:4.29.0'
implementation 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1'
testImplementation platform('org.junit:junit-bom:5.8.1')
testImplementation "org.junit.jupiter:junit-jupiter-api"
testImplementation "org.junit.jupiter:junit-jupiter-params"
testImplementation "org.junit.jupiter:junit-jupiter-engine"
testImplementation 'org.apache.commons:commons-io:1.3.2'
testImplementation 'org.assertj:assertj-core:3.21.0'
testImplementation 'org.mockito:mockito-core:3.12.4'
testImplementation 'org.mockito:mockito-junit-jupiter:3.12.4'
testImplementation 'com.squareup.okhttp3:mockwebserver:3.14.9'
}
test {
onlyIf { !project.hasProperty("buildSrc.skipTests") }
useJUnitPlatform()
}

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2002-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.gradle
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked
import groovy.transform.TypeCheckingMode
import org.gradle.api.DefaultTask
import org.gradle.api.Task
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
/**
* Checkout a project template from a git repository.
*
* @author Marcus Da Coregio
*/
@CompileStatic
abstract class IncludeRepoTask extends DefaultTask {
private static final String DEFAULT_URI_PREFIX = 'https://github.com/'
/**
* Git repository to use. Will be prefixed with {@link #DEFAULT_URI_PREFIX} if it isn't already
* @return
*/
@Input
abstract Property<String> getRepository();
/**
* Git reference to use.
*/
@Input
abstract Property<String> getRef()
/**
* Directory where the project template should be copied.
*/
@OutputDirectory
final File outputDirectory = project.file("$project.buildDir/$name")
@TaskAction
void checkoutAndCopy() {
outputDirectory.deleteDir()
File checkoutDir = checkout(this, getRemoteUri(), ref.get())
moveToOutputDir(checkoutDir, outputDirectory)
}
private static File cleanTemporaryDir(Task task, File tmpDir) {
if (tmpDir.exists()) {
task.project.delete(tmpDir)
}
return tmpDir
}
static File checkout(Task task, String remoteUri, String ref) {
checkout(task, remoteUri, ref, task.getTemporaryDir())
}
@TypeChecked(TypeCheckingMode.SKIP)
static File checkout(Task task, String remoteUri, String ref, File checkoutDir) {
cleanTemporaryDir(task, checkoutDir)
task.project.exec {
commandLine = ["git", "clone", "--no-checkout", remoteUri, checkoutDir.absolutePath]
errorOutput = System.err
}
task.project.exec {
commandLine = ["git", "checkout", ref]
workingDir = checkoutDir
errorOutput = System.err
}
return checkoutDir
}
private static void moveToOutputDir(File tmpDir, File outputDirectory) {
File baseDir = tmpDir
baseDir.renameTo(outputDirectory)
}
private String getRemoteUri() {
String remoteUri = this.repository.get()
if (remoteUri.startsWith(DEFAULT_URI_PREFIX)) {
return remoteUri
}
return DEFAULT_URI_PREFIX + remoteUri
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2002-2016 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.gradle.convention;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.GroovyPlugin;
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.PluginManager;
import org.gradle.plugins.ide.eclipse.EclipseWtpPlugin;
import org.gradle.plugins.ide.idea.IdeaPlugin;
import org.springframework.gradle.CopyPropertiesPlugin
import org.springframework.gradle.propdeps.PropDepsEclipsePlugin
import org.springframework.gradle.propdeps.PropDepsIdeaPlugin
import org.springframework.gradle.propdeps.PropDepsPlugin;
/**
* @author Rob Winch
*/
public abstract class AbstractSpringJavaPlugin implements Plugin<Project> {
@Override
public final void apply(Project project) {
initialPlugins(project);
PluginManager pluginManager = project.getPluginManager();
pluginManager.apply(JavaPlugin.class);
pluginManager.apply(ManagementConfigurationPlugin.class)
if (project.file("src/main/groovy").exists()
|| project.file("src/test/groovy").exists()
|| project.file("src/integration-test/groovy").exists()) {
pluginManager.apply(GroovyPlugin.class);
}
pluginManager.apply("io.spring.convention.repository");
pluginManager.apply(EclipseWtpPlugin);
pluginManager.apply(IdeaPlugin);
pluginManager.apply(PropDepsPlugin);
pluginManager.apply(PropDepsEclipsePlugin);
pluginManager.apply(PropDepsIdeaPlugin);
pluginManager.apply("io.spring.convention.tests-configuration");
pluginManager.apply("io.spring.convention.integration-test");
pluginManager.apply("io.spring.convention.springdependencymangement");
pluginManager.apply("io.spring.convention.javadoc-options");
pluginManager.apply("io.spring.convention.checkstyle");
pluginManager.apply(CopyPropertiesPlugin);
project.jar {
manifest.attributes["Created-By"] =
"${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})"
manifest.attributes["Implementation-Title"] = project.name
manifest.attributes["Implementation-Version"] = project.version
manifest.attributes["Automatic-Module-Name"] = project.name.replace('-', '.')
}
project.test {
useJUnitPlatform()
}
additionalPlugins(project);
}
protected void initialPlugins(Project project) {}
protected abstract void additionalPlugins(Project project);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2002-2017 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.gradle.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
class ArtifactoryPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.plugins.apply('com.jfrog.artifactory')
String name = Utils.getProjectName(project);
boolean isSnapshot = Utils.isSnapshot(project);
boolean isMilestone = Utils.isMilestone(project);
project.artifactory {
contextUrl = 'https://repo.spring.io'
publish {
repository {
repoKey = isSnapshot ? 'libs-snapshot-local' : isMilestone ? 'libs-milestone-local' : 'libs-release-local'
if(project.hasProperty('artifactoryUsername')) {
username = artifactoryUsername
password = artifactoryPassword
}
}
}
}
project.plugins.withType(MavenPublishPlugin) {
project.artifactory {
publish {
defaults {
publications('mavenJava')
}
}
}
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2016-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.gradle.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
/**
* Adds and configures Checkstyle plugin.
*
* @author Vedran Pavic
*/
class CheckstylePlugin implements Plugin<Project> {
final CHECKSTYLE_DIR = 'etc/checkstyle'
@Override
void apply(Project project) {
project.plugins.withType(JavaPlugin) {
def checkstyleDir = project.rootProject.file(CHECKSTYLE_DIR)
if (checkstyleDir.exists() && checkstyleDir.directory) {
project.getPluginManager().apply('checkstyle')
project.dependencies.add('checkstyle', 'io.spring.javaformat:spring-javaformat-checkstyle:0.0.29')
project.dependencies.add('checkstyle', 'io.spring.nohttp:nohttp-checkstyle:0.0.3.RELEASE')
project.checkstyle {
configDirectory = checkstyleDir
toolVersion = '8.21'
}
}
}
}
}

View File

@@ -0,0 +1,61 @@
package io.spring.gradle.convention
import org.gradle.api.Project
import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.Properties;
import org.gradle.api.DefaultTask;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.tasks.TaskAction;
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension;
public class DependencyManagementExportTask extends DefaultTask {
@Internal
def projects;
@Input
String getProjectNames() {
return projects*.name
}
@TaskAction
public void dependencyManagementExport() throws IOException {
def projects = this.projects ?: project.subprojects + project
def configurations = projects*.configurations*.findAll { ['testRuntime','integrationTestRuntime','grettyRunnerTomcat8','ajtools'].contains(it.name) }
def dependencyResults = configurations*.incoming*.resolutionResult*.allDependencies.flatten()
def moduleVersionVersions = dependencyResults.findAll { r -> r.requested instanceof ModuleComponentSelector }.collect { r-> r.selected.moduleVersion }
def projectDependencies = projects.collect { p-> "${p.group}:${p.name}:${p.version}".toString() } as Set
def dependencies = moduleVersionVersions.collect { d ->
"${d.group}:${d.name}:${d.version}".toString()
}.sort() as Set
println ''
println ''
println 'dependencyManagement {'
println '\tdependencies {'
dependencies.findAll { d-> !projectDependencies.contains(d)}.each {
println "\t\tdependency '$it'"
}
println '\t}'
println '}'
println ''
println ''
println 'TIP Use this to find duplicates:\n$ sort gradle/dependency-management.gradle| uniq -c | grep -v \'^\\s*1\''
println ''
println ''
}
void setOutputFile(File file) throws IOException {
this.output = new FileOutputStream(file);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2002-2017 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.gradle.convention
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.Plugin
import org.gradle.api.Project
public class DeployDocsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPluginManager().apply('org.hidetake.ssh')
project.ssh.settings {
knownHosts = allowAnyHosts
}
project.remotes {
docs {
role 'docs'
if (project.hasProperty('deployDocsHost')) {
host = project.findProperty('deployDocsHost')
} else {
host = 'docs.af.pivotal.io'
}
retryCount = 5 // retry 5 times (default is 0)
retryWaitSec = 10 // wait 10 seconds between retries (default is 0)
user = project.findProperty('deployDocsSshUsername')
if (project.hasProperty('deployDocsSshKeyPath')) {
identity = project.file(project.findProperty('deployDocsSshKeyPath'))
} else if (project.hasProperty('deployDocsSshKey')) {
identity = project.findProperty('deployDocsSshKey')
}
if(project.hasProperty('deployDocsSshPassphrase')) {
passphrase = project.findProperty('deployDocsSshPassphrase')
}
}
}
project.task('deployDocs') {
dependsOn 'docsZip'
doFirst {
project.ssh.run {
session(project.remotes.docs) {
def now = System.currentTimeMillis()
def name = project.rootProject.name
def version = project.rootProject.version
def tempPath = "/tmp/${name}-${now}-docs/".replaceAll(' ', '_')
execute "mkdir -p $tempPath"
project.tasks.docsZip.outputs.each { o ->
put from: o.files, into: tempPath
}
execute "unzip $tempPath*.zip -d $tempPath"
def extractPath = "/var/www/domains/spring.io/docs/htdocs/autorepo/docs/${name}/${version}/"
execute "rm -rf $extractPath"
execute "mkdir -p $extractPath"
execute "mv $tempPath/docs/* $extractPath"
execute "chmod -R g+w $extractPath"
}
}
}
}
}
}

View File

@@ -0,0 +1,45 @@
package io.spring.gradle.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.PluginManager
import org.gradle.api.tasks.bundling.Zip
/**
* Aggregates asciidoc, javadoc, and deploying of the docs into a single plugin
*/
public class DocsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
PluginManager pluginManager = project.getPluginManager();
pluginManager.apply(BasePlugin);
pluginManager.apply(DeployDocsPlugin);
pluginManager.apply(JavadocApiPlugin);
Task docsZip = project.tasks.create('docsZip', Zip) {
dependsOn 'api'
group = 'Distribution'
archiveBaseName = project.rootProject.name
archiveClassifier = 'docs'
description = "Builds -${classifier} archive containing all " +
"Docs for deployment at docs.spring.io"
from(project.tasks.api.outputs) {
into 'api'
}
into 'docs'
duplicatesStrategy 'exclude'
}
Task docs = project.tasks.create("docs") {
group = 'Documentation'
description 'An aggregator task to generate all the documentation'
dependsOn docsZip
}
project.tasks.assemble.dependsOn docs
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2002-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.gradle.convention
import io.spring.gradle.IncludeRepoTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.Property
import org.gradle.api.tasks.GradleBuild
import org.gradle.api.tasks.TaskProvider
/**
* Adds a set of tasks that make easy to clone a remote repository and perform some task
*
* @author Marcus Da Coregio
*/
class IncludeCheckRemotePlugin implements Plugin<Project> {
@Override
void apply(Project project) {
IncludeCheckRemoteExtension extension = project.extensions.create('includeCheckRemote', IncludeCheckRemoteExtension)
TaskProvider<IncludeRepoTask> includeRepoTask = project.tasks.register('includeRepo', IncludeRepoTask) { IncludeRepoTask it ->
it.repository = extension.repository
it.ref = extension.ref
}
project.tasks.register('checkRemote', GradleBuild) {
it.dependsOn 'includeRepo'
it.dir = includeRepoTask.get().outputDirectory
it.tasks = extension.getTasks()
}
}
abstract static class IncludeCheckRemoteExtension {
/**
* Git repository to clone
*/
String repository;
/**
* Git ref to checkout
*/
String ref
/**
* Task to run in the repository
*/
List<String> tasks = ['check']
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright 2016-2018 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.gradle.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.plugins.GroovyPlugin
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.testing.Test
import org.gradle.plugins.ide.eclipse.EclipsePlugin
import org.gradle.plugins.ide.idea.IdeaPlugin
import org.springframework.gradle.propdeps.PropDepsPlugin
/**
*
* Adds support for integration tests to java projects.
*
* <ul>
* <li>Adds integrationTestCompile and integrationTestRuntime configurations</li>
* <li>A new source test folder of src/integration-test/java has been added</li>
* <li>A task to run integration tests named integrationTest is added</li>
* <li>If Groovy plugin is added a new source test folder src/integration-test/groovy is added</li>
* </ul>
*
* @author Rob Winch
*/
public class IntegrationTestPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.plugins.withType(JavaPlugin.class) {
applyJava(project)
}
}
private applyJava(Project project) {
if(!project.file('src/integration-test/').exists()) {
// ensure we don't add if no tests to avoid adding Gretty
return
}
project.configurations {
integrationTestCompile {
extendsFrom testImplementation
}
integrationTestRuntime {
extendsFrom integrationTestCompile, testRuntime, testRuntimeOnly
}
}
project.sourceSets {
integrationTest {
java.srcDir project.file('src/integration-test/java')
resources.srcDir project.file('src/integration-test/resources')
compileClasspath = project.sourceSets.main.output + project.sourceSets.test.output + project.configurations.integrationTestCompile
runtimeClasspath = output + compileClasspath + project.configurations.integrationTestRuntime
}
}
Task integrationTestTask = project.tasks.create("integrationTest", Test) {
group = 'Verification'
description = 'Runs the integration tests.'
dependsOn 'jar'
testClassesDirs = project.sourceSets.integrationTest.output.classesDirs
classpath = project.sourceSets.integrationTest.runtimeClasspath
shouldRunAfter project.tasks.test
useJUnitPlatform()
}
project.tasks.check.dependsOn integrationTestTask
project.plugins.withType(IdeaPlugin) {
project.idea {
module {
testSourceDirs += project.file('src/integration-test/java')
scopes.TEST.plus += [ project.configurations.integrationTestCompile ]
}
}
}
project.plugins.withType(GroovyPlugin) {
project.sourceSets {
integrationTest {
groovy.srcDirs project.file('src/integration-test/groovy')
}
}
project.plugins.withType(IdeaPlugin) {
project.idea {
module {
testSourceDirs += project.file('src/integration-test/groovy')
}
}
}
}
project.plugins.withType(PropDepsPlugin) {
project.configurations {
integrationTestCompile {
extendsFrom optional, provided
}
}
}
project.plugins.withType(EclipsePlugin) {
project.eclipse.classpath {
plusConfigurations += [ project.configurations.integrationTestCompile ]
}
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2016-2018 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.gradle.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
/**
* Adds a version of jacoco to use and makes check depend on jacocoTestReport.
*
* @author Rob Winch
*/
class JacocoPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.plugins.withType(JavaPlugin) {
project.getPluginManager().apply("jacoco")
project.tasks.check.dependsOn project.tasks.jacocoTestReport
project.jacoco {
toolVersion = '0.8.7'
}
}
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright 2002-2016 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.gradle.convention;
import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import org.gradle.api.Action;
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.javadoc.Javadoc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Rob Winch
*/
public class JavadocApiPlugin implements Plugin<Project> {
Logger logger = LoggerFactory.getLogger(getClass());
Set<Pattern> excludes = Collections.singleton(Pattern.compile("test"));
@Override
public void apply(Project project) {
logger.info("Applied");
Project rootProject = project.getRootProject();
//Task docs = project.getTasks().findByPath("docs") ?: project.getTasks().create("docs");
Javadoc api = project.getTasks().create("api", Javadoc);
api.setGroup("Documentation");
api.setDescription("Generates aggregated Javadoc API documentation.");
api.doLast {
if (JavaVersion.current().isJava11Compatible()) {
project.copy({ copy -> copy
.from(api.destinationDir)
.into(api.destinationDir)
.include("element-list")
.rename("element-list", "package-list")
});
}
}
Set<Project> subprojects = rootProject.getSubprojects();
for (Project subproject : subprojects) {
addProject(api, subproject);
}
if (subprojects.isEmpty()) {
addProject(api, project);
}
api.setMaxMemory("1024m");
api.setDestinationDir(new File(project.getBuildDir(), "api"));
project.getPluginManager().apply("io.spring.convention.javadoc-options");
}
public void setExcludes(String... excludes) {
if(excludes == null) {
this.excludes = Collections.emptySet();
}
this.excludes = new HashSet<Pattern>(excludes.length);
for(String exclude : excludes) {
this.excludes.add(Pattern.compile(exclude));
}
}
private void addProject(final Javadoc api, final Project project) {
for(Pattern exclude : excludes) {
if(exclude.matcher(project.getName()).matches()) {
logger.info("Skipping {} because it is excluded by {}", project, exclude);
return;
}
}
logger.info("Try add sources for {}", project);
project.getPlugins().withType(SpringModulePlugin.class).all(new Action<SpringModulePlugin>() {
@Override
public void execute(SpringModulePlugin plugin) {
logger.info("Added sources for {}", project);
JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class);
SourceSet mainSourceSet = java.getSourceSets().getByName("main");
api.setSource(api.getSource().plus(mainSourceSet.getAllJava()));
project.getTasks().withType(Javadoc.class).all(new Action<Javadoc>() {
@Override
public void execute(Javadoc projectJavadoc) {
api.setClasspath(api.getClasspath().plus(projectJavadoc.getClasspath()));
}
});
}
});
}
}

View File

@@ -0,0 +1,15 @@
package io.spring.gradle.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.javadoc.Javadoc
public class JavadocOptionsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getTasks().withType(Javadoc).all { t->
t.options.addStringOption('Xdoclint:none', '-quiet')
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2002-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.gradle.convention;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaTestFixturesPlugin;
import org.gradle.api.plugins.PluginContainer;
import org.gradle.api.publish.PublishingExtension;
import org.gradle.api.publish.maven.MavenPublication;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
import org.springframework.gradle.propdeps.PropDepsPlugin;
/**
* Creates a Management configuration that is appropriate for adding a platform to that is not exposed externally. If
* the JavaPlugin is applied, the compileClasspath, runtimeClasspath, testCompileClasspath, and testRuntimeClasspath
* will extend from it.
* @author Rob Winch
*/
public class ManagementConfigurationPlugin implements Plugin<Project> {
public static final String MANAGEMENT_CONFIGURATION_NAME = "management";
@Override
public void apply(Project project) {
ConfigurationContainer configurations = project.getConfigurations();
configurations.create(MANAGEMENT_CONFIGURATION_NAME, (management) -> {
management.setVisible(false);
management.setCanBeConsumed(false);
management.setCanBeResolved(false);
PluginContainer plugins = project.getPlugins();
plugins.withType(JavaPlugin.class, (javaPlugin) -> {
configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management);
configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management);
configurations.getByName(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management);
configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management);
});
plugins.withType(JavaTestFixturesPlugin.class, (javaTestFixturesPlugin) -> {
configurations.getByName("testFixturesCompileClasspath").extendsFrom(management);
configurations.getByName("testFixturesRuntimeClasspath").extendsFrom(management);
});
plugins.withType(MavenPublishPlugin.class, (mavenPublish) -> {
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
publishing.getPublications().withType(MavenPublication.class, (mavenPublication -> {
mavenPublication.versionMapping((versions) ->
versions.allVariants(versionMapping -> versionMapping.fromResolutionResult())
);
}));
});
plugins.withType(PropDepsPlugin.class, (propDepsPlugin -> {
configurations.getByName("optional").extendsFrom(management);
configurations.getByName("provided").extendsFrom(management);
}));
});
}
}

View File

@@ -0,0 +1,18 @@
package io.spring.gradle.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlatformPlugin
import org.sonarqube.gradle.SonarQubePlugin
import org.springframework.gradle.CopyPropertiesPlugin
import org.springframework.gradle.maven.SpringMavenPlugin
public class MavenBomPlugin implements Plugin<Project> {
static String MAVEN_BOM_TASK_NAME = "mavenBom"
public void apply(Project project) {
project.plugins.apply(JavaPlatformPlugin)
project.plugins.apply(SpringMavenPlugin)
project.plugins.apply(CopyPropertiesPlugin)
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright 2016-2018 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.gradle.convention;
import org.gradle.api.Plugin
import org.gradle.api.Project
class RepositoryConventionPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
String[] forceMavenRepositories = ((String) project.findProperty("forceMavenRepositories"))?.split(',')
boolean isImplicitSnapshotRepository = forceMavenRepositories == null && Utils.isSnapshot(project)
boolean isImplicitMilestoneRepository = forceMavenRepositories == null && Utils.isMilestone(project)
boolean isSnapshot = isImplicitSnapshotRepository || forceMavenRepositories?.contains('snapshot')
boolean isMilestone = isImplicitMilestoneRepository || forceMavenRepositories?.contains('milestone')
project.repositories {
if (forceMavenRepositories?.contains('local')) {
mavenLocal()
}
mavenCentral()
jcenter() {
content {
includeGroup "org.gretty"
}
}
if (isSnapshot) {
maven {
name = 'artifactory-snapshot'
if (project.hasProperty('artifactoryUsername')) {
credentials {
username project.artifactoryUsername
password project.artifactoryPassword
}
}
url = 'https://repo.spring.io/snapshot/'
}
}
if (isSnapshot || isMilestone) {
maven {
name = 'artifactory-milestone'
if (project.hasProperty('artifactoryUsername')) {
credentials {
username project.artifactoryUsername
password project.artifactoryPassword
}
}
url = 'https://repo.spring.io/milestone/'
}
}
maven {
name = 'artifactory-release'
if (project.hasProperty('artifactoryUsername')) {
credentials {
username project.artifactoryUsername
password project.artifactoryPassword
}
}
url = 'https://repo.spring.io/release/'
}
maven {
name = 'shibboleth'
url = 'https://build.shibboleth.net/nexus/content/repositories/releases/'
}
}
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2016-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.gradle.convention
import io.spring.nohttp.gradle.NoHttpPlugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.PluginManager
import org.springframework.gradle.maven.SpringNexusPublishPlugin
class RootProjectPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
PluginManager pluginManager = project.getPluginManager()
pluginManager.apply(BasePlugin)
pluginManager.apply(SchemaPlugin)
pluginManager.apply(NoHttpPlugin)
pluginManager.apply(SpringNexusPublishPlugin)
pluginManager.apply(ArtifactoryPlugin)
pluginManager.apply("org.sonarqube")
project.repositories.mavenCentral()
project.allprojects {
configurations.all {
resolutionStrategy {
cacheChangingModulesFor 0, "seconds"
cacheDynamicVersionsFor 0, "seconds"
}
}
}
String projectName = Utils.getProjectName(project)
project.sonarqube {
properties {
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.projectName", projectName
property "sonar.jacoco.reportPath", "${project.buildDir.name}/jacoco.exec"
property "sonar.links.homepage", "https://spring.io/${projectName}"
property "sonar.links.ci", "https://jenkins.spring.io/job/${projectName}/"
property "sonar.links.issue", "https://github.com/spring-projects/${projectName}/issues"
property "sonar.links.scm", "https://github.com/spring-projects/${projectName}"
property "sonar.links.scm_dev", "https://github.com/spring-projects/${projectName}.git"
}
}
project.tasks.create("dependencyManagementExport", DependencyManagementExportTask)
def finalizeDeployArtifacts = project.task("finalizeDeployArtifacts")
if (Utils.isRelease(project) && project.hasProperty("ossrhUsername")) {
finalizeDeployArtifacts.dependsOn project.tasks.closeAndReleaseOssrhStagingRepository
}
}
}

View File

@@ -0,0 +1,71 @@
package io.spring.gradle.convention
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.Plugin
import org.gradle.api.Project
public class SchemaDeployPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPluginManager().apply('org.hidetake.ssh')
project.ssh.settings {
knownHosts = allowAnyHosts
}
project.remotes {
docs {
role 'docs'
if (project.hasProperty('deployDocsHost')) {
host = project.findProperty('deployDocsHost')
} else {
host = 'docs.af.pivotal.io'
}
retryCount = 5 // retry 5 times (default is 0)
retryWaitSec = 10 // wait 10 seconds between retries (default is 0)
user = project.findProperty('deployDocsSshUsername')
if(project.hasProperty('deployDocsSshKeyPath')) {
identity = project.file(project.findProperty('deployDocsSshKeyPath'))
} else if (project.hasProperty('deployDocsSshKey')) {
identity = project.findProperty('deployDocsSshKey')
}
if(project.hasProperty('deployDocsSshPassphrase')) {
passphrase = project.findProperty('deployDocsSshPassphrase')
}
}
}
project.task('deploySchema') {
dependsOn 'schemaZip'
doFirst {
project.ssh.run {
session(project.remotes.docs) {
def now = System.currentTimeMillis()
def name = project.rootProject.name
def version = project.rootProject.version
def tempPath = "/tmp/${name}-${now}-schema/".replaceAll(' ', '_')
execute "mkdir -p $tempPath"
project.tasks.schemaZip.outputs.each { o ->
println "Putting $o.files"
put from: o.files, into: tempPath
}
execute "unzip $tempPath*.zip -d $tempPath"
def extractPath = "/var/www/domains/spring.io/docs/htdocs/autorepo/schema/${name}/${version}/"
execute "rm -rf $extractPath"
execute "mkdir -p $extractPath"
execute "rm -f $tempPath*.zip"
execute "rm -rf $extractPath*"
execute "mv $tempPath/* $extractPath"
execute "chmod -R g+w $extractPath"
}
}
}
}
}
}

View File

@@ -0,0 +1,15 @@
package io.spring.gradle.convention
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.Plugin
import org.gradle.api.Project
public class SchemaPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPluginManager().apply(SchemaZipPlugin)
project.getPluginManager().apply(SchemaDeployPlugin)
}
}

View File

@@ -0,0 +1,43 @@
package io.spring.gradle.convention
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.Plugin
import org.gradle.api.Project
public class SchemaZipPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
Zip schemaZip = project.tasks.create('schemaZip', Zip)
schemaZip.group = 'Distribution'
schemaZip.archiveBaseName = project.rootProject.name
schemaZip.archiveClassifier = 'schema'
schemaZip.description = "Builds -${schemaZip.archiveClassifier} archive containing all " +
"XSDs for deployment at static.springframework.org/schema."
project.rootProject.subprojects.each { module ->
module.getPlugins().withType(JavaPlugin.class).all {
def Properties schemas = new Properties();
module.sourceSets.main.resources.find {
it.path.endsWith('META-INF/spring.schemas')
}?.withInputStream { schemas.load(it) }
for (def key : schemas.keySet()) {
def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
assert shortName != key
File xsdFile = module.sourceSets.main.resources.find {
it.path.endsWith(schemas.get(key))
}
assert xsdFile != null
schemaZip.into (shortName) {
duplicatesStrategy 'exclude'
from xsdFile.path
}
}
}
}
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2002-2017 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.gradle.convention;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
/**
* A Properties which sorts they keys so that they can be written to a File with
* the keys sorted.
*
* @author Rob Winch
*
*/
class SortedProperties extends Properties {
private static final long serialVersionUID = -6199017589626540836L;
public Enumeration<Object> keys() {
Enumeration<Object> keysEnum = super.keys();
List<Object> keyList = new ArrayList<Object>();
while (keysEnum.hasMoreElements()) {
keyList.add(keysEnum.nextElement());
}
Collections.sort(keyList, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
});
return Collections.enumeration(keyList);
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2016-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.gradle.convention
import io.spring.gradle.dependencymanagement.DependencyManagementPlugin
import org.gradle.api.Plugin
import org.gradle.api.Project
/**
* Adds and configures {@link DependencyManagementPlugin}.
* <p>
* Additionally, if 'gradle/dependency-management.gradle' file is present it will be
* automatically applied file for configuring the dependencies.
*/
class SpringDependencyManagementConventionPlugin implements Plugin<Project> {
static final String DEPENDENCY_MANAGEMENT_RESOURCE = "gradle/dependency-management.gradle"
@Override
void apply(Project project) {
project.getPluginManager().apply(ManagementConfigurationPlugin)
project.getPluginManager().apply(DependencyManagementPlugin)
project.dependencyManagement {
resolutionStrategy {
cacheChangingModulesFor 0, "seconds"
}
}
File rootDir = project.rootDir
List<File> dependencyManagementFiles = [project.rootProject.file(DEPENDENCY_MANAGEMENT_RESOURCE)]
for (File dir = project.projectDir; dir != rootDir; dir = dir.parentFile) {
dependencyManagementFiles.add(new File(dir, DEPENDENCY_MANAGEMENT_RESOURCE))
}
dependencyManagementFiles.each { f ->
if (f.exists()) {
project.apply from: f.absolutePath
}
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2016-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.gradle.convention;
import org.gradle.api.Project
import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.plugins.MavenPlugin;
import org.gradle.api.plugins.PluginManager
import org.springframework.gradle.maven.SpringMavenPlugin;
/**
* @author Rob Winch
*/
class SpringModulePlugin extends AbstractSpringJavaPlugin {
@Override
void additionalPlugins(Project project) {
PluginManager pluginManager = project.getPluginManager();
pluginManager.apply(JavaLibraryPlugin.class)
pluginManager.apply(SpringMavenPlugin.class);
pluginManager.apply("io.spring.convention.jacoco");
def deployArtifacts = project.task("deployArtifacts")
deployArtifacts.group = 'Deploy tasks'
deployArtifacts.description = "Deploys the artifacts to either Artifactory or Maven Central"
if (!Utils.isRelease(project)) {
deployArtifacts.dependsOn project.tasks.artifactoryPublish
}
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2002-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.gradle.convention
import org.gradle.api.Project
import org.gradle.api.plugins.PluginManager
/**
* @author Rob Winch
*/
public class SpringSampleBootPlugin extends SpringSamplePlugin {
@Override
public void additionalPlugins(Project project) {
super.additionalPlugins(project);
PluginManager pluginManager = project.getPluginManager();
pluginManager.apply("org.springframework.boot");
project.repositories {
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2002-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.gradle.convention;
import org.gradle.api.Project
import org.sonarqube.gradle.SonarQubePlugin;
/**
* @author Rob Winch
*/
public class SpringSamplePlugin extends AbstractSpringJavaPlugin {
@Override
public void additionalPlugins(Project project) {
project.plugins.withType(SonarQubePlugin) {
project.sonarqube.skipProject = true
}
}
@Override
protected void initialPlugins(Project project) {
if (project.hasProperty('springBootVersion')) {
String springBootVersion = project.springBootVersion
if (Utils.isSnapshot(springBootVersion)) {
project.ext.forceMavenRepositories = 'snapshot'
}
else if (Utils.isMilestone(springBootVersion)) {
project.ext.forceMavenRepositories = 'milestone'
}
}
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2016-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.gradle.convention
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.plugins.PluginManager
import org.gradle.api.tasks.testing.Test
/**
* @author Rob Winch
*/
public class SpringSampleWarPlugin extends SpringSamplePlugin {
@Override
public void additionalPlugins(Project project) {
super.additionalPlugins(project);
PluginManager pluginManager = project.getPluginManager();
pluginManager.apply("war");
pluginManager.apply("org.gretty");
project.gretty {
servletContainer = 'tomcat10'
contextPath = '/'
fileLogEnabled = false
}
Task prepareAppServerForIntegrationTests = project.tasks.create('prepareAppServerForIntegrationTests') {
group = 'Verification'
description = 'Prepares the app server for integration tests'
doFirst {
project.gretty {
httpPort = getRandomFreePort()
httpsPort = getRandomPort()
}
}
}
project.tasks.matching { it.name == "appBeforeIntegrationTest" }.all { task ->
task.dependsOn prepareAppServerForIntegrationTests
}
project.tasks.withType(Test).all { task ->
if("integrationTest".equals(task.name)) {
applyForIntegrationTest(project, task)
}
}
}
def applyForIntegrationTest(Project project, Task integrationTest) {
project.gretty.integrationTestTask = integrationTest.name
integrationTest.doFirst {
def gretty = project.gretty
String host = project.gretty.host ?: 'localhost'
boolean isHttps = gretty.httpsEnabled
Integer httpPort = integrationTest.systemProperties['gretty.httpPort']
Integer httpsPort = integrationTest.systemProperties['gretty.httpsPort']
int port = isHttps ? httpsPort : httpPort
String contextPath = project.gretty.contextPath
String httpBaseUrl = "http://${host}:${httpPort}${contextPath}"
String httpsBaseUrl = "https://${host}:${httpsPort}${contextPath}"
String baseUrl = isHttps ? httpsBaseUrl : httpBaseUrl
integrationTest.systemProperty 'app.port', port
integrationTest.systemProperty 'app.httpPort', httpPort
integrationTest.systemProperty 'app.httpsPort', httpsPort
integrationTest.systemProperty 'app.baseURI', baseUrl
integrationTest.systemProperty 'app.httpBaseURI', httpBaseUrl
integrationTest.systemProperty 'app.httpsBaseURI', httpsBaseUrl
integrationTest.systemProperty 'geb.build.baseUrl', baseUrl
integrationTest.systemProperty 'geb.build.reportsDir', 'build/geb-reports'
}
}
def getRandomPort() {
ServerSocket ss = new ServerSocket(0)
int port = ss.localPort
ss.close()
return port
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2002-2016 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.gradle.convention;
import org.gradle.api.Project;
/**
* @author Rob Winch
*/
public class SpringTestPlugin extends AbstractSpringJavaPlugin {
@Override
public void additionalPlugins(Project project) {
project.sonarqube.skipProject = true
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2002-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.gradle.convention;
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
import org.gradle.jvm.tasks.Jar
/**
* Adds the ability to depends on the test jar within other projects using:
*
* <code>
* testImplementation project(path: ':foo', configuration: 'tests')
* </code>
*
* @author Rob Winch
*/
public class TestsConfigurationPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.plugins.withType(JavaPlugin) {
applyJavaProject(project)
}
}
private void applyJavaProject(Project project) {
project.configurations {
tests.extendsFrom testRuntime, testRuntimeClasspath
}
project.tasks.create('testJar', Jar) {
classifier = 'test'
from project.sourceSets.test.output
}
project.artifacts {
tests project.testJar
}
}
}

View File

@@ -0,0 +1,47 @@
package io.spring.gradle.convention;
import org.gradle.api.Project;
public class Utils {
static String getProjectName(Project project) {
String projectName = project.getRootProject().getName();
if(projectName.endsWith("-build")) {
projectName = projectName.substring(0, projectName.length() - "-build".length());
}
return projectName;
}
static boolean isSnapshot(Project project) {
String projectVersion = projectVersion(project)
return isSnapshot(projectVersion)
}
static boolean isMilestone(Project project) {
String projectVersion = projectVersion(project)
return isMilestone(projectVersion)
}
static boolean isRelease(Project project) {
String projectVersion = projectVersion(project)
return isRelease(projectVersion)
}
static boolean isSnapshot(String projectVersion) {
return projectVersion.matches('^.*([.-]BUILD)?-SNAPSHOT$')
}
static boolean isMilestone(String projectVersion) {
return projectVersion.matches('^.*[.-]M\\d+$') || projectVersion.matches('^.*[.-]RC\\d+$')
}
static boolean isRelease(String projectVersion) {
return !(isSnapshot(projectVersion) || isMilestone(projectVersion))
}
private static String projectVersion(Project project) {
return String.valueOf(project.getVersion());
}
private Utils() {}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2002-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 org.springframework.gradle;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
public class CopyPropertiesPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
copyPropertyFromRootProjectTo("group", project);
copyPropertyFromRootProjectTo("version", project);
copyPropertyFromRootProjectTo("description", project);
}
private void copyPropertyFromRootProjectTo(String propertyName, Project project) {
Project rootProject = project.getRootProject();
Object property = rootProject.findProperty(propertyName);
if(property != null) {
project.setProperty(propertyName, property);
}
}
}

View File

@@ -0,0 +1,71 @@
package org.springframework.gradle.antora;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.language.base.plugins.LifecycleBasePlugin;
public class AntoraVersionPlugin implements Plugin<Project> {
public static final String ANTORA_CHECK_VERSION_TASK_NAME = "antoraCheckVersion";
@Override
public void apply(Project project) {
TaskProvider<CheckAntoraVersionTask> antoraCheckVersion = project.getTasks().register(ANTORA_CHECK_VERSION_TASK_NAME, CheckAntoraVersionTask.class, new Action<CheckAntoraVersionTask>() {
@Override
public void execute(CheckAntoraVersionTask antoraCheckVersion) {
antoraCheckVersion.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP);
antoraCheckVersion.setDescription("Checks the antora.yml version properties match the Gradle version");
antoraCheckVersion.getAntoraVersion().convention(project.provider(() -> getDefaultAntoraVersion(project)));
antoraCheckVersion.getAntoraPrerelease().convention(project.provider(() -> getDefaultAntoraPrerelease(project)));
antoraCheckVersion.getAntoraDisplayVersion().convention(project.provider(() -> getDefaultAntoraDisplayVersion(project)));
antoraCheckVersion.getAntoraYmlFile().fileProvider(project.provider(() -> project.file("antora.yml")));
}
});
project.getPlugins().withType(LifecycleBasePlugin.class, new Action<LifecycleBasePlugin>() {
@Override
public void execute(LifecycleBasePlugin lifecycleBasePlugin) {
project.getTasks().named(LifecycleBasePlugin.CHECK_TASK_NAME).configure(new Action<Task>() {
@Override
public void execute(Task check) {
check.dependsOn(antoraCheckVersion);
}
});
}
});
project.getTasks().register("antoraUpdateVersion", UpdateAntoraVersionTask.class, new Action<UpdateAntoraVersionTask>() {
@Override
public void execute(UpdateAntoraVersionTask antoraUpdateVersion) {
antoraUpdateVersion.setGroup("Release");
antoraUpdateVersion.setDescription("Updates the antora.yml version properties to match the Gradle version");
antoraUpdateVersion.getAntoraYmlFile().fileProvider(project.provider(() -> project.file("antora.yml")));
}
});
}
private static String getDefaultAntoraVersion(Project project) {
String projectVersion = getProjectVersion(project);
return AntoraVersionUtils.getDefaultAntoraVersion(projectVersion);
}
private static String getDefaultAntoraPrerelease(Project project) {
String projectVersion = getProjectVersion(project);
return AntoraVersionUtils.getDefaultAntoraPrerelease(projectVersion);
}
private static String getDefaultAntoraDisplayVersion(Project project) {
String projectVersion = getProjectVersion(project);
return AntoraVersionUtils.getDefaultAntoraDisplayVersion(projectVersion);
}
private static String getProjectVersion(Project project) {
Object projectVersion = project.getVersion();
if (projectVersion == null) {
throw new GradleException("Please define antoraVersion and antoraPrerelease on " + ANTORA_CHECK_VERSION_TASK_NAME + " or provide a Project version so they can be defaulted");
}
return String.valueOf(projectVersion);
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2019-2022 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 org.springframework.gradle.antora;
public class AntoraVersionUtils {
public static String getDefaultAntoraVersion(String projectVersion) {
int preReleaseIndex = getSnapshotIndex(projectVersion);
return isSnapshot(projectVersion) ? projectVersion.substring(0, preReleaseIndex) : projectVersion;
}
public static String getDefaultAntoraPrerelease(String projectVersion) {
if (isSnapshot(projectVersion)) {
int preReleaseIndex = getSnapshotIndex(projectVersion);
return projectVersion.substring(preReleaseIndex);
}
if (isPreRelease(projectVersion)) {
return Boolean.TRUE.toString();
}
return null;
}
public static String getDefaultAntoraDisplayVersion(String projectVersion) {
if (!isSnapshot(projectVersion) && isPreRelease(projectVersion)) {
return getDefaultAntoraVersion(projectVersion);
}
return null;
}
private static boolean isSnapshot(String projectVersion) {
return getSnapshotIndex(projectVersion) >= 0;
}
private static int getSnapshotIndex(String projectVersion) {
return projectVersion.lastIndexOf("-SNAPSHOT");
}
private static boolean isPreRelease(String projectVersion) {
return projectVersion.lastIndexOf("-") >= 0;
}
}

View File

@@ -0,0 +1,96 @@
package org.springframework.gradle.antora;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.representer.Representer;
public abstract class CheckAntoraVersionTask extends DefaultTask {
@TaskAction
public void check() throws FileNotFoundException {
File antoraYmlFile = getAntoraYmlFile().getAsFile().get();
String expectedAntoraVersion = getAntoraVersion().get();
String expectedAntoraPrerelease = getAntoraPrerelease().getOrElse(null);
String expectedAntoraDisplayVersion = getAntoraDisplayVersion().getOrElse(null);
Representer representer = new Representer();
representer.getPropertyUtils().setSkipMissingProperties(true);
Yaml yaml = new Yaml(new Constructor(AntoraYml.class), representer);
AntoraYml antoraYml = yaml.load(new FileInputStream(antoraYmlFile));
String actualAntoraPrerelease = antoraYml.getPrerelease();
boolean preReleaseMatches = antoraYml.getPrerelease() == null && expectedAntoraPrerelease == null ||
(actualAntoraPrerelease != null && actualAntoraPrerelease.equals(expectedAntoraPrerelease));
String actualAntoraDisplayVersion = antoraYml.getDisplay_version();
boolean displayVersionMatches = antoraYml.getDisplay_version() == null && expectedAntoraDisplayVersion == null ||
(actualAntoraDisplayVersion != null && actualAntoraDisplayVersion.equals(expectedAntoraDisplayVersion));
String actualAntoraVersion = antoraYml.getVersion();
if (!preReleaseMatches ||
!displayVersionMatches ||
!expectedAntoraVersion.equals(actualAntoraVersion)) {
throw new GradleException("The Gradle version of '" + getProject().getVersion() + "' should have version: '"
+ expectedAntoraVersion + "' prerelease: '" + expectedAntoraPrerelease + "' display_version: '"
+ expectedAntoraDisplayVersion + "' defined in " + antoraYmlFile + " but got version: '"
+ actualAntoraVersion + "' prerelease: '" + actualAntoraPrerelease + "' display_version: '" + actualAntoraDisplayVersion + "'");
}
}
@InputFile
public abstract RegularFileProperty getAntoraYmlFile();
@Input
public abstract Property<String> getAntoraVersion();
@Input
@Optional
public abstract Property<String> getAntoraPrerelease();
@Input
@Optional
public abstract Property<String> getAntoraDisplayVersion();
public static class AntoraYml {
private String version;
private String prerelease;
private String display_version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getPrerelease() {
return prerelease;
}
public void setPrerelease(String prerelease) {
this.prerelease = prerelease;
}
public String getDisplay_version() {
return display_version;
}
public void setDisplay_version(String display_version) {
this.display_version = display_version;
}
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2019-2022 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 org.springframework.gradle.antora;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.TaskAction;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
public abstract class UpdateAntoraVersionTask extends DefaultTask {
@TaskAction
public void update() throws IOException {
String projectVersion = getProject().getVersion().toString();
File antoraYmlFile = getAntoraYmlFile().getAsFile().get();
String updatedAntoraVersion = AntoraVersionUtils.getDefaultAntoraVersion(projectVersion);
String updatedAntoraPrerelease = AntoraVersionUtils.getDefaultAntoraPrerelease(projectVersion);
String updatedAntoraDisplayVersion = AntoraVersionUtils.getDefaultAntoraDisplayVersion(projectVersion);
Representer representer = new Representer();
representer.getPropertyUtils().setSkipMissingProperties(true);
Yaml yaml = new Yaml(new Constructor(AntoraYml.class), representer);
AntoraYml antoraYml = yaml.load(new FileInputStream(antoraYmlFile));
System.out.println("Updating the version parameters in " + antoraYmlFile.getName() + " to version: "
+ updatedAntoraVersion + ", prerelease: " + updatedAntoraPrerelease + ", display_version: "
+ updatedAntoraDisplayVersion);
antoraYml.setVersion(updatedAntoraVersion);
antoraYml.setPrerelease(updatedAntoraPrerelease);
antoraYml.setDisplay_version(updatedAntoraDisplayVersion);
FileWriter outputWriter = new FileWriter(antoraYmlFile);
getYaml().dump(antoraYml, outputWriter);
}
@InputFile
public abstract RegularFileProperty getAntoraYmlFile();
public static class AntoraYml {
private String name;
private String version;
private String prerelease;
private String display_version;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getPrerelease() {
return prerelease;
}
public void setPrerelease(String prerelease) {
this.prerelease = prerelease;
}
public String getDisplay_version() {
return display_version;
}
public void setDisplay_version(String display_version) {
this.display_version = display_version;
}
}
private Yaml getYaml() {
Representer representer = new Representer() {
@Override
protected NodeTuple representJavaBeanProperty(Object javaBean,
org.yaml.snakeyaml.introspector.Property property, Object propertyValue, Tag customTag) {
// Don't write out null values
if (propertyValue == null) {
return null;
}
else {
return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
}
}
};
representer.addClassTag(AntoraYml.class, Tag.MAP);
DumperOptions ymlOptions = new DumperOptions();
ymlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
ymlOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
return new Yaml(representer, ymlOptions);
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright 2019-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 org.springframework.gradle.github.milestones;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.util.List;
public class GitHubMilestoneApi {
private String baseUrl = "https://api.github.com";
private OkHttpClient client;
private Gson gson = new Gson();
public GitHubMilestoneApi() {
this.client = new OkHttpClient.Builder().build();
}
public GitHubMilestoneApi(String gitHubToken) {
this.client = new OkHttpClient.Builder()
.addInterceptor(new AuthorizationInterceptor(gitHubToken))
.build();
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public long findMilestoneNumberByTitle(RepositoryRef repositoryRef, String milestoneTitle) {
String url = this.baseUrl + "/repos/" + repositoryRef.getOwner() + "/" + repositoryRef.getName() + "/milestones?per_page=100";
Request request = new Request.Builder().get().url(url)
.build();
try {
Response response = this.client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new RuntimeException("Could not find milestone with title " + milestoneTitle + " for repository " + repositoryRef + ". Response " + response);
}
List<Milestone> milestones = this.gson.fromJson(response.body().charStream(), new TypeToken<List<Milestone>>(){}.getType());
for (Milestone milestone : milestones) {
if (milestoneTitle.equals(milestone.getTitle())) {
return milestone.getNumber();
}
}
if (milestones.size() <= 100) {
throw new RuntimeException("Could not find open milestone with title " + milestoneTitle + " for repository " + repositoryRef + " Got " + milestones);
}
throw new RuntimeException("It is possible there are too many open milestones open (only 100 are supported). Could not find open milestone with title " + milestoneTitle + " for repository " + repositoryRef + " Got " + milestones);
} catch (IOException e) {
throw new RuntimeException("Could not find open milestone with title " + milestoneTitle + " for repository " + repositoryRef, e);
}
}
public boolean isOpenIssuesForMilestoneNumber(RepositoryRef repositoryRef, long milestoneNumber) {
String url = this.baseUrl + "/repos/" + repositoryRef.getOwner() + "/" + repositoryRef.getName() + "/issues?per_page=1&milestone=" + milestoneNumber;
Request request = new Request.Builder().get().url(url)
.build();
try {
Response response = this.client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new RuntimeException("Could not find issues for milestone number " + milestoneNumber + " for repository " + repositoryRef + ". Response " + response);
}
List<Object> issues = this.gson.fromJson(response.body().charStream(), new TypeToken<List<Object>>(){}.getType());
return !issues.isEmpty();
} catch (IOException e) {
throw new RuntimeException("Could not find issues for milestone number " + milestoneNumber + " for repository " + repositoryRef, e);
}
}
// public boolean isOpenIssuesForMilestoneName(String owner, String repository, String milestoneName) {
//
// }
private static class AuthorizationInterceptor implements Interceptor {
private final String token;
public AuthorizationInterceptor(String token) {
this.token = token;
}
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + this.token).build();
return chain.proceed(request);
}
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2019-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 org.springframework.gradle.github.milestones;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
public class GitHubMilestoneHasNoOpenIssuesTask extends DefaultTask {
@Input
private RepositoryRef repository = new RepositoryRef();
@Input
private String milestoneTitle;
@Input @Optional
private String gitHubAccessToken;
private GitHubMilestoneApi milestones = new GitHubMilestoneApi();
@TaskAction
public void checkHasNoOpenIssues() {
long milestoneNumber = this.milestones.findMilestoneNumberByTitle(this.repository, this.milestoneTitle);
boolean isOpenIssues = this.milestones.isOpenIssuesForMilestoneNumber(this.repository, milestoneNumber);
if (isOpenIssues) {
throw new IllegalStateException("The repository " + this.repository + " has open issues for milestone with the title " + this.milestoneTitle + " and number " + milestoneNumber);
}
System.out.println("The repository " + this.repository + " has no open issues for milestone with the title " + this.milestoneTitle + " and number " + milestoneNumber);
}
public RepositoryRef getRepository() {
return repository;
}
public void repository(Action<RepositoryRef> repository) {
repository.execute(this.repository);
}
public void setRepository(RepositoryRef repository) {
this.repository = repository;
}
public String getMilestoneTitle() {
return milestoneTitle;
}
public void setMilestoneTitle(String milestoneTitle) {
this.milestoneTitle = milestoneTitle;
}
public String getGitHubAccessToken() {
return gitHubAccessToken;
}
public void setGitHubAccessToken(String gitHubAccessToken) {
this.gitHubAccessToken = gitHubAccessToken;
this.milestones = new GitHubMilestoneApi(gitHubAccessToken);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2019-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 org.springframework.gradle.github.milestones;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
public class GitHubMilestonePlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getTasks().register("gitHubCheckMilestoneHasNoOpenIssues", GitHubMilestoneHasNoOpenIssuesTask.class, new Action<GitHubMilestoneHasNoOpenIssuesTask>() {
@Override
public void execute(GitHubMilestoneHasNoOpenIssuesTask githubCheckMilestoneHasNoOpenIssues) {
githubCheckMilestoneHasNoOpenIssues.setGroup("Release");
githubCheckMilestoneHasNoOpenIssues.setDescription("Checks if there are any open issues for the specified repository and milestone");
githubCheckMilestoneHasNoOpenIssues.setMilestoneTitle((String) project.findProperty("nextVersion"));
if (project.hasProperty("githubAccessToken")) {
githubCheckMilestoneHasNoOpenIssues.setGitHubAccessToken((String) project.findProperty("gitHubAccessToken"));
}
}
});
}
}

View File

@@ -0,0 +1,31 @@
package org.springframework.gradle.github.milestones;
public class Milestone {
private String title;
private long number;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public long getNumber() {
return number;
}
public void setNumber(long number) {
this.number = number;
}
@Override
public String toString() {
return "Milestone{" +
"title='" + title + '\'' +
", number=" + number +
'}';
}
}

View File

@@ -0,0 +1,65 @@
package org.springframework.gradle.github.milestones;
public class RepositoryRef {
private String owner;
private String name;
RepositoryRef() {
}
public RepositoryRef(String owner, String name) {
this.owner = owner;
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "RepositoryRef{" +
"owner='" + owner + '\'' +
", name='" + name + '\'' +
'}';
}
public static RepositoryRefBuilder owner(String owner) {
return new RepositoryRefBuilder().owner(owner);
}
public static final class RepositoryRefBuilder {
private String owner;
private String repository;
private RepositoryRefBuilder() {
}
private RepositoryRefBuilder owner(String owner) {
this.owner = owner;
return this;
}
public RepositoryRefBuilder repository(String repository) {
this.repository = repository;
return this;
}
public RepositoryRef build() {
return new RepositoryRef(owner, repository);
}
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2016-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 org.springframework.gradle.maven;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.publish.PublishingExtension;
import org.gradle.api.publish.maven.MavenPom;
import org.gradle.api.publish.maven.MavenPomDeveloperSpec;
import org.gradle.api.publish.maven.MavenPomIssueManagement;
import org.gradle.api.publish.maven.MavenPomLicenseSpec;
import org.gradle.api.publish.maven.MavenPomOrganization;
import org.gradle.api.publish.maven.MavenPomScm;
import org.gradle.api.publish.maven.MavenPublication;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
public class MavenPublishingConventionsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPlugins().withType(MavenPublishPlugin.class).all(new Action<MavenPublishPlugin>() {
@Override
public void execute(MavenPublishPlugin mavenPublish) {
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
publishing.getPublications().withType(MavenPublication.class)
.all((mavenPublication) -> MavenPublishingConventionsPlugin.this.customizePom(mavenPublication.getPom(), project));
MavenPublishingConventionsPlugin.this.customizeJavaPlugin(project);
}
});
}
private void customizePom(MavenPom pom, Project project) {
pom.getUrl().set("https://spring.io/projects/spring-session");
pom.getName().set(project.provider(project::getName));
pom.getDescription().set(project.provider(project::getDescription));
pom.organization(this::customizeOrganization);
pom.licenses(this::customizeLicences);
pom.developers(this::customizeDevelopers);
pom.scm(this::customizeScm);
pom.issueManagement(this::customizeIssueManagement);
}
private void customizeOrganization(MavenPomOrganization organization) {
organization.getName().set("Pivotal Software, Inc.");
organization.getUrl().set("https://spring.io");
}
private void customizeLicences(MavenPomLicenseSpec licences) {
licences.license((licence) -> {
licence.getName().set("Apache License, Version 2.0");
licence.getUrl().set("https://www.apache.org/licenses/LICENSE-2.0");
});
}
private void customizeDevelopers(MavenPomDeveloperSpec developers) {
developers.developer((developer) -> {
developer.getName().set("Pivotal");
developer.getEmail().set("info@pivotal.io");
developer.getOrganization().set("Pivotal Software, Inc.");
developer.getOrganizationUrl().set("https://www.spring.io");
});
}
private void customizeScm(MavenPomScm scm) {
scm.getConnection().set("scm:git:git://github.com/spring-projects/spring-session.git");
scm.getDeveloperConnection().set("scm:git:ssh://git@github.com/spring-projects/spring-session.git");
scm.getUrl().set("https://github.com/spring-projects/spring-session");
}
private void customizeIssueManagement(MavenPomIssueManagement issueManagement) {
issueManagement.getSystem().set("GitHub");
issueManagement.getUrl().set("https://github.com/spring-projects/spring-session/issues");
}
private void customizeJavaPlugin(Project project) {
project.getPlugins().withType(JavaPlugin.class).all((javaPlugin) -> {
JavaPluginExtension extension = project.getExtensions().getByType(JavaPluginExtension.class);
extension.withJavadocJar();
extension.withSourcesJar();
});
}
}

View File

@@ -0,0 +1,33 @@
package org.springframework.gradle.maven;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaPlatformPlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.publish.PublishingExtension;
import org.gradle.api.publish.VariantVersionMappingStrategy;
import org.gradle.api.publish.VersionMappingStrategy;
import org.gradle.api.publish.maven.MavenPublication;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
public class PublishAllJavaComponentsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPlugins().withType(MavenPublishPlugin.class).all((mavenPublish) -> {
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
publishing.getPublications().create("mavenJava", MavenPublication.class, new Action<MavenPublication>() {
@Override
public void execute(MavenPublication maven) {
project.getPlugins().withType(JavaPlugin.class, (plugin) -> {
maven.from(project.getComponents().getByName("java"));
});
project.getPlugins().withType(JavaPlatformPlugin.class, (plugin) -> {
maven.from(project.getComponents().getByName("javaPlatform"));
});
}
});
});
}
}

View File

@@ -0,0 +1,26 @@
package org.springframework.gradle.maven;
import io.spring.gradle.convention.Utils;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
public class PublishArtifactsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getTasks().register("publishArtifacts", new Action<Task>() {
@Override
public void execute(Task publishArtifacts) {
publishArtifacts.setGroup("Publishing");
publishArtifacts.setDescription("Publish the artifacts to either Artifactory or Maven Central based on the version");
if (Utils.isRelease(project)) {
publishArtifacts.dependsOn("publishToOssrh");
}
else {
publishArtifacts.dependsOn("artifactoryPublish");
}
}
});
}
}

View File

@@ -0,0 +1,29 @@
package org.springframework.gradle.maven;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.api.publish.PublishingExtension;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
import java.io.File;
public class PublishLocalPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPlugins().withType(MavenPublishPlugin.class).all(new Action<MavenPublishPlugin>() {
@Override
public void execute(MavenPublishPlugin mavenPublish) {
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
publishing.getRepositories().maven(new Action<MavenArtifactRepository>() {
@Override
public void execute(MavenArtifactRepository maven) {
maven.setName("local");
maven.setUrl(new File(project.getRootProject().getBuildDir(), "publications/repos"));
}
});
}
});
}
}

View File

@@ -0,0 +1,21 @@
package org.springframework.gradle.maven;
import io.spring.gradle.convention.ArtifactoryPlugin;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.PluginManager;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
public class SpringMavenPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
PluginManager pluginManager = project.getPluginManager();
pluginManager.apply(MavenPublishPlugin.class);
pluginManager.apply(SpringSigningPlugin.class);
pluginManager.apply(MavenPublishingConventionsPlugin.class);
pluginManager.apply(PublishAllJavaComponentsPlugin.class);
pluginManager.apply(PublishLocalPlugin.class);
pluginManager.apply(PublishArtifactsPlugin.class);
pluginManager.apply(ArtifactoryPlugin.class);
}
}

View File

@@ -0,0 +1,28 @@
package org.springframework.gradle.maven;
import io.github.gradlenexus.publishplugin.NexusPublishExtension;
import io.github.gradlenexus.publishplugin.NexusPublishPlugin;
import io.github.gradlenexus.publishplugin.NexusRepository;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import java.net.URI;
import java.time.Duration;
public class SpringNexusPublishPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPlugins().apply(NexusPublishPlugin.class);
NexusPublishExtension nexusPublishing = project.getExtensions().findByType(NexusPublishExtension.class);
nexusPublishing.getRepositories().create("ossrh", new Action<NexusRepository>() {
@Override
public void execute(NexusRepository nexusRepository) {
nexusRepository.getNexusUrl().set(URI.create("https://s01.oss.sonatype.org/service/local/"));
nexusRepository.getSnapshotRepositoryUrl().set(URI.create("https://s01.oss.sonatype.org/content/repositories/snapshots/"));
}
});
nexusPublishing.getConnectTimeout().set(Duration.ofMinutes(3));
nexusPublishing.getClientTimeout().set(Duration.ofMinutes(3));
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2016-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 org.springframework.gradle.maven;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.publish.Publication;
import org.gradle.api.publish.PublishingExtension;
import org.gradle.api.publish.plugins.PublishingPlugin;
import org.gradle.plugins.signing.SigningExtension;
import org.gradle.plugins.signing.SigningPlugin;
import java.util.concurrent.Callable;
public class SpringSigningPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPluginManager().apply(SigningPlugin.class);
project.getPlugins().withType(SigningPlugin.class).all(new Action<SigningPlugin>() {
@Override
public void execute(SigningPlugin signingPlugin) {
boolean hasSigningKey = project.hasProperty("signing.keyId") || project.hasProperty("signingKey");
if (hasSigningKey) {
sign(project);
}
}
});
}
private void sign(Project project) {
SigningExtension signing = project.getExtensions().findByType(SigningExtension.class);
signing.setRequired(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return project.getGradle().getTaskGraph().hasTask("publishArtifacts");
}
});
String signingKeyId = (String) project.findProperty("signingKeyId");
String signingKey = (String) project.findProperty("signingKey");
String signingPassword = (String) project.findProperty("signingPassword");
if (signingKeyId != null) {
signing.useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword);
} else {
signing.useInMemoryPgpKeys(signingKey, signingPassword);
}
project.getPlugins().withType(PublishAllJavaComponentsPlugin.class).all(new Action<PublishAllJavaComponentsPlugin>() {
@Override
public void execute(PublishAllJavaComponentsPlugin publishingPlugin) {
PublishingExtension publishing = project.getExtensions().findByType(PublishingExtension.class);
Publication maven = publishing.getPublications().getByName("mavenJava");
signing.sign(maven);
}
});
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2002-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 org.springframework.gradle.propdeps
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.plugins.ide.eclipse.EclipsePlugin
/**
* Plugin to allow optional and provided dependency configurations to work with the
* standard gradle 'eclipse' plugin
*
* @author Phillip Webb
*/
class PropDepsEclipsePlugin implements Plugin<Project> {
public void apply(Project project) {
project.plugins.apply(PropDepsPlugin)
project.plugins.apply(EclipsePlugin)
project.eclipse {
classpath {
plusConfigurations += [project.configurations.provided, project.configurations.optional]
}
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2002-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 org.springframework.gradle.propdeps
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.plugins.ide.idea.IdeaPlugin
/**
* Plugin to allow optional and provided dependency configurations to work with the
* standard gradle 'idea' plugin
*
* @author Phillip Webb
* @author Brian Clozel
* @link https://youtrack.jetbrains.com/issue/IDEA-107046
* @link https://youtrack.jetbrains.com/issue/IDEA-117668
*/
class PropDepsIdeaPlugin implements Plugin<Project> {
public void apply(Project project) {
project.plugins.apply(PropDepsPlugin)
project.plugins.apply(IdeaPlugin)
project.idea.module {
// IDEA internally deals with 4 scopes : COMPILE, TEST, PROVIDED, RUNTIME
// but only PROVIDED seems to be picked up
scopes.PROVIDED.plus += [project.configurations.provided]
scopes.PROVIDED.plus += [project.configurations.optional]
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2002-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 org.springframework.gradle.propdeps
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.plugins.JavaLibraryPlugin
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.javadoc.Javadoc
/**
* Plugin to allow 'optional' and 'provided' dependency configurations
*
* As stated in the maven documentation, provided scope "is only available on the compilation and test classpath,
* and is not transitive".
*
* This plugin creates two new configurations, and each one:
* <ul>
* <li>is a parent of the compile configuration</li>
* <li>is not visible, not transitive</li>
* <li>all dependencies are excluded from the default configuration</li>
* </ul>
*
* @author Phillip Webb
* @author Brian Clozel
* @author Rob Winch
*
* @see <a href="https://www.gradle.org/docs/current/userguide/java_plugin.html#N121CF">Maven documentation</a>
* @see <a href="https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope">Gradle configurations</a>
* @see PropDepsEclipsePlugin
* @see PropDepsIdeaPlugin
*/
class PropDepsPlugin implements Plugin<Project> {
public void apply(Project project) {
project.plugins.apply(JavaPlugin)
Configuration provided = addConfiguration(project, "provided")
Configuration optional = addConfiguration(project, "optional")
Javadoc javadoc = project.tasks.getByName(JavaPlugin.JAVADOC_TASK_NAME)
javadoc.classpath = javadoc.classpath.plus(provided).plus(optional)
}
private Configuration addConfiguration(Project project, String name) {
Configuration configuration = project.configurations.create(name)
configuration.extendsFrom(project.configurations.implementation)
project.plugins.withType(JavaLibraryPlugin, {
configuration.extendsFrom(project.configurations.api)
})
project.sourceSets.all {
compileClasspath += configuration
runtimeClasspath += configuration
}
return configuration
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright 2019-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 org.springframework.gradle.sagan;
import java.util.regex.Pattern;
/**
* Domain object for creating a new release version.
*/
public class Release {
private String version;
private ReleaseStatus status;
private boolean current;
private String referenceDocUrl;
private String apiDocUrl;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public ReleaseStatus getStatus() {
return status;
}
public void setStatus(ReleaseStatus status) {
this.status = status;
}
public boolean isCurrent() {
return current;
}
public void setCurrent(boolean current) {
this.current = current;
}
public String getReferenceDocUrl() {
return referenceDocUrl;
}
public void setReferenceDocUrl(String referenceDocUrl) {
this.referenceDocUrl = referenceDocUrl;
}
public String getApiDocUrl() {
return apiDocUrl;
}
public void setApiDocUrl(String apiDocUrl) {
this.apiDocUrl = apiDocUrl;
}
@Override
public String toString() {
return "Release{" +
"version='" + version + '\'' +
", status=" + status +
", current=" + current +
", referenceDocUrl='" + referenceDocUrl + '\'' +
", apiDocUrl='" + apiDocUrl + '\'' +
'}';
}
public enum ReleaseStatus {
/**
* Unstable version with limited support
*/
SNAPSHOT,
/**
* Pre-Release version meant to be tested by the community
*/
PRERELEASE,
/**
* Release Generally Available on public artifact repositories and enjoying full support from maintainers
*/
GENERAL_AVAILABILITY;
private static final Pattern PRERELEASE_PATTERN = Pattern.compile("[A-Za-z0-9\\.\\-]+?(M|RC)\\d+");
private static final String SNAPSHOT_SUFFIX = "SNAPSHOT";
/**
* Parse the ReleaseStatus from a String
* @param version a project version
* @return the release status for this version
*/
public static ReleaseStatus parse(String version) {
if (version == null) {
throw new IllegalArgumentException("version cannot be null");
}
if (version.endsWith(SNAPSHOT_SUFFIX)) {
return SNAPSHOT;
}
if (PRERELEASE_PATTERN.matcher(version).matches()) {
return PRERELEASE;
}
return GENERAL_AVAILABILITY;
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2019-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 org.springframework.gradle.sagan;
import com.google.gson.Gson;
import okhttp3.*;
import java.io.IOException;
import java.util.Base64;
/**
* Implements necessary calls to the Sagan API See https://spring.io/restdocs/index.html
*/
public class SaganApi {
private String baseUrl = "https://spring.io/api";
private OkHttpClient client;
private Gson gson = new Gson();
public SaganApi(String gitHubToken) {
this.client = new OkHttpClient.Builder()
.addInterceptor(new BasicInterceptor("not-used", gitHubToken))
.build();
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public void createReleaseForProject(Release release, String projectName) {
String url = this.baseUrl + "/projects/" + projectName + "/releases";
String releaseJsonString = gson.toJson(release);
RequestBody body = RequestBody.create(MediaType.parse("application/json"), releaseJsonString);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try {
Response response = this.client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new RuntimeException("Could not create release " + release + ". Got response " + response);
}
} catch (IOException fail) {
throw new RuntimeException("Could not create release " + release, fail);
}
}
public void deleteReleaseForProject(String release, String projectName) {
String url = this.baseUrl + "/projects/" + projectName + "/releases/" + release;
Request request = new Request.Builder()
.url(url)
.delete()
.build();
try {
Response response = this.client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new RuntimeException("Could not delete release " + release + ". Got response " + response);
}
} catch (IOException fail) {
throw new RuntimeException("Could not delete release " + release, fail);
}
}
private static class BasicInterceptor implements Interceptor {
private final String token;
public BasicInterceptor(String username, String token) {
this.token = Base64.getEncoder().encodeToString((username + ":" + token).getBytes());
}
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Authorization", "Basic " + this.token).build();
return chain.proceed(request);
}
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2019-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 org.springframework.gradle.sagan;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
public class SaganCreateReleaseTask extends DefaultTask {
@Input
private String gitHubAccessToken;
@Input
private String version;
@Input
private String apiDocUrl;
@Input
private String referenceDocUrl;
@Input
private String projectName;
@TaskAction
public void saganCreateRelease() {
SaganApi sagan = new SaganApi(this.gitHubAccessToken);
Release release = new Release();
release.setVersion(this.version);
release.setApiDocUrl(this.apiDocUrl);
release.setReferenceDocUrl(this.referenceDocUrl);
sagan.createReleaseForProject(release, this.projectName);
}
public String getGitHubAccessToken() {
return gitHubAccessToken;
}
public void setGitHubAccessToken(String gitHubAccessToken) {
this.gitHubAccessToken = gitHubAccessToken;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getApiDocUrl() {
return apiDocUrl;
}
public void setApiDocUrl(String apiDocUrl) {
this.apiDocUrl = apiDocUrl;
}
public String getReferenceDocUrl() {
return referenceDocUrl;
}
public void setReferenceDocUrl(String referenceDocUrl) {
this.referenceDocUrl = referenceDocUrl;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2019-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 org.springframework.gradle.sagan;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
public class SaganDeleteReleaseTask extends DefaultTask {
@Input
private String gitHubAccessToken;
@Input
private String version;
@Input
private String projectName;
@TaskAction
public void saganCreateRelease() {
SaganApi sagan = new SaganApi(this.gitHubAccessToken);
sagan.deleteReleaseForProject(this.version, this.projectName);
}
public String getGitHubAccessToken() {
return gitHubAccessToken;
}
public void setGitHubAccessToken(String gitHubAccessToken) {
this.gitHubAccessToken = gitHubAccessToken;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2019-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 org.springframework.gradle.sagan;
import io.spring.gradle.convention.Utils;
import org.gradle.api.*;
public class SaganPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getTasks().register("saganCreateRelease", SaganCreateReleaseTask.class, new Action<SaganCreateReleaseTask>() {
@Override
public void execute(SaganCreateReleaseTask saganCreateVersion) {
saganCreateVersion.setGroup("Release");
saganCreateVersion.setDescription("Creates a new version for the specified project on spring.io");
saganCreateVersion.setVersion((String) project.findProperty("nextVersion"));
saganCreateVersion.setProjectName(Utils.getProjectName(project));
saganCreateVersion.setGitHubAccessToken((String) project.findProperty("gitHubAccessToken"));
}
});
project.getTasks().register("saganDeleteRelease", SaganDeleteReleaseTask.class, new Action<SaganDeleteReleaseTask>() {
@Override
public void execute(SaganDeleteReleaseTask saganDeleteVersion) {
saganDeleteVersion.setGroup("Release");
saganDeleteVersion.setDescription("Delete a version for the specified project on spring.io");
saganDeleteVersion.setVersion((String) project.findProperty("previousVersion"));
saganDeleteVersion.setProjectName(Utils.getProjectName(project));
saganDeleteVersion.setGitHubAccessToken((String) project.findProperty("gitHubAccessToken"));
}
});
}
}

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.ArtifactoryPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.MavenBomPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.CheckstylePlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.DocsPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.IncludeCheckRemotePlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.IntegrationTestPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.JacocoPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.JavadocApiPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.JavadocOptionsPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.RepositoryConventionPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.RootProjectPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.SpringModulePlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.SpringSampleBootPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.SpringSampleWarPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.SpringSamplePlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.SpringTestPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.SpringDependencyManagementConventionPlugin

View File

@@ -0,0 +1 @@
implementation-class=io.spring.gradle.convention.TestsConfigurationPlugin

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2002-2017 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.gradle;
import org.apache.commons.io.FileUtils;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.Enumeration;
public class TestKit {
final File buildDir;
public TestKit(File buildDir) {
this.buildDir = buildDir;
}
public File getRootDir() {
return buildDir;
}
public GradleRunner withProjectDir(File projectDir) throws IOException {
FileUtils.copyDirectory(projectDir, buildDir);
return GradleRunner.create()
.withProjectDir(buildDir)
.withPluginClasspath();
}
public GradleRunner withProjectResource(String projectResourceName) throws IOException, URISyntaxException {
ClassLoader classLoader = getClass().getClassLoader();
Enumeration<URL> resources = classLoader.getResources(projectResourceName);
if(!resources.hasMoreElements()) {
throw new IOException("Cannot find resource " + projectResourceName + " with " + classLoader);
}
URL resourceUrl = resources.nextElement();
File projectDir = Paths.get(resourceUrl.toURI()).toFile();
return withProjectDir(projectDir);
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2002-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.gradle.convention;
import io.spring.gradle.IncludeRepoTask;
import org.apache.commons.io.FileUtils;
import org.gradle.api.Project;
import org.gradle.api.tasks.GradleBuild;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
class IncludeCheckRemotePluginTest {
Project rootProject;
@AfterEach
public void cleanup() throws Exception {
if (rootProject != null) {
FileUtils.deleteDirectory(rootProject.getProjectDir());
}
}
@Test
void applyWhenExtensionPropertiesNoTasksThenCreateCheckRemoteTaskWithDefaultTask() {
this.rootProject = ProjectBuilder.builder().build();
this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
(includeCheckRemoteExtension) -> {
includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
includeCheckRemoteExtension.setProperty("ref", "main");
});
GradleBuild checkRemote = (GradleBuild) this.rootProject.getTasks().named("checkRemote").get();
assertThat(checkRemote.getTasks()).containsExactly("check");
}
@Test
void applyWhenExtensionPropertiesTasksThenCreateCheckRemoteWithProvidedTasks() {
this.rootProject = ProjectBuilder.builder().build();
this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
(includeCheckRemoteExtension) -> {
includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
includeCheckRemoteExtension.setProperty("ref", "main");
includeCheckRemoteExtension.setProperty("tasks", Arrays.asList("clean", "build", "test"));
});
GradleBuild checkRemote = (GradleBuild) this.rootProject.getTasks().named("checkRemote").get();
assertThat(checkRemote.getTasks()).containsExactly("clean", "build", "test");
}
@Test
void applyWhenExtensionPropertiesThenRegisterIncludeRepoTaskWithExtensionProperties() {
this.rootProject = ProjectBuilder.builder().build();
this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
(includeCheckRemoteExtension) -> {
includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
includeCheckRemoteExtension.setProperty("ref", "main");
});
IncludeRepoTask includeRepo = (IncludeRepoTask) this.rootProject.getTasks().named("includeRepo").get();
assertThat(includeRepo).isNotNull();
assertThat(includeRepo.getRepository().get()).isEqualTo("my-project/my-repository");
assertThat(includeRepo.getRef().get()).isEqualTo("main");
}
@Test
void applyWhenRegisterTasksThenCheckRemoteDirSameAsIncludeRepoOutputDir() {
this.rootProject = ProjectBuilder.builder().build();
this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
(includeCheckRemoteExtension) -> {
includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
includeCheckRemoteExtension.setProperty("ref", "main");
});
IncludeRepoTask includeRepo = (IncludeRepoTask) this.rootProject.getTasks().named("includeRepo").get();
GradleBuild checkRemote = (GradleBuild) this.rootProject.getTasks().named("checkRemote").get();
assertThat(checkRemote.getDir()).isEqualTo(includeRepo.getOutputDirectory());
}
@Test
void applyWhenNoExtensionPropertiesThenRegisterTasks() {
this.rootProject = ProjectBuilder.builder().build();
this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
IncludeRepoTask includeRepo = (IncludeRepoTask) this.rootProject.getTasks().named("includeRepo").get();
GradleBuild checkRemote = (GradleBuild) this.rootProject.getTasks().named("checkRemote").get();
assertThat(includeRepo).isNotNull();
assertThat(checkRemote).isNotNull();
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2002-2016 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.gradle.convention;
import org.apache.commons.io.FileUtils;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import java.io.File;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Rob Winch
*/
public class IntegrationPluginTest {
Project rootProject;
@AfterEach
public void cleanup() throws Exception {
if (rootProject != null) {
FileUtils.deleteDirectory(rootProject.getProjectDir());
}
}
@Test
public void applyWhenNoSourceThenIntegrationTestTaskNull() {
rootProject = ProjectBuilder.builder().build();
rootProject.getPlugins().apply(JavaPlugin.class);
rootProject.getPlugins().apply(IntegrationTestPlugin.class);
assertThat(rootProject.getTasks().findByPath("integrationTest")).isNull();
}
}

View File

@@ -0,0 +1,52 @@
package io.spring.gradle.convention;
import io.spring.gradle.TestKit;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
public class IntegrationTestPluginITest {
private io.spring.gradle.TestKit testKit;
@BeforeEach
void setup(@TempDir Path tempDir) {
this.testKit = new TestKit(tempDir.toFile());
}
@Test
public void checkWithJavaPlugin() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/integrationtest/withjava/")
.withArguments("check")
.build();
assertThat(result.task(":check").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(new File(testKit.getRootDir(), "build/test-results/integrationTest/")).exists();
assertThat(new File(testKit.getRootDir(), "build/reports/tests/integrationTest/")).exists();
}
@Test
public void checkWithPropdeps() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/integrationtest/withpropdeps/")
.withArguments("check")
.build();
assertThat(result.task(":check").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(new File(testKit.getRootDir(), "build/test-results/integrationTest/")).exists();
assertThat(new File(testKit.getRootDir(), "build/reports/tests/integrationTest/")).exists();
}
@Test
public void checkWithGroovy() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/integrationtest/withgroovy/")
.withArguments("check")
.build();
assertThat(result.task(":check").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(new File(testKit.getRootDir(), "build/test-results/integrationTest/")).exists();
assertThat(new File(testKit.getRootDir(), "build/reports/tests/integrationTest/")).exists();
}
}

View File

@@ -0,0 +1,31 @@
package io.spring.gradle.convention;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
public class JacocoPluginITest{
private io.spring.gradle.TestKit testKit;
@BeforeEach
void setup(@TempDir Path tempDir) {
this.testKit = new io.spring.gradle.TestKit(tempDir.toFile());
}
@Test
public void checkWithJavaPlugin() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/jacoco/java/")
.withArguments("check")
.build();
assertThat(result.task(":check").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(new File(testKit.getRootDir(), "build/jacoco")).exists();
assertThat(new File(testKit.getRootDir(), "build/reports/jacoco/test/html/")).exists();
}
}

View File

@@ -0,0 +1,38 @@
package io.spring.gradle.convention;
import io.spring.gradle.TestKit;
import org.apache.commons.io.FileUtils;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
public class JavadocApiPluginITest {
private TestKit testKit;
@BeforeEach
void setup(@TempDir Path tempDir) {
this.testKit = new TestKit(tempDir.toFile());
}
@Test
public void multiModuleApi() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/javadocapi/multimodule/")
.withArguments("api")
.build();
assertThat(result.task(":api").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File allClasses = new File(testKit.getRootDir(), "build/api/allclasses-noframe.html");
File index = new File(testKit.getRootDir(), "build/api/allclasses-index.html");
File listing = allClasses.exists() ? allClasses : index;
String listingText = FileUtils.readFileToString(listing);
assertThat(listingText).contains("sample/Api.html");
assertThat(listingText).contains("sample/Impl.html");
assertThat(listingText).doesNotContain("sample/Sample.html");
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2002-2016 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.gradle.convention;
import java.io.File;
import org.apache.commons.io.FileUtils;
import static org.assertj.core.api.Assertions.assertThat;
import org.gradle.api.Project;
import org.gradle.api.tasks.javadoc.Javadoc;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
/**
* @author Rob Winch
*/
public class JavadocApiPluginTest {
Project rootProject;
@AfterEach
public void cleanup() throws Exception {
if (rootProject != null) {
FileUtils.deleteDirectory(rootProject.getProjectDir());
}
}
@Test
public void applyWhenNotOverrideThenPropertiesDefaulted() {
rootProject = ProjectBuilder.builder().build();
rootProject.getPlugins().apply(JavadocApiPlugin.class);
Javadoc apiTask = (Javadoc) rootProject.getTasks().getByPath("api");
assertThat(apiTask).isNotNull();
assertThat(apiTask.getGroup()).isEqualTo("Documentation");
assertThat(apiTask.getDescription()).isEqualTo("Generates aggregated Javadoc API documentation.");
assertThat(apiTask.getMaxMemory()).isEqualTo("1024m");
assertThat(apiTask.getDestinationDir()).isEqualTo(new File(rootProject.getBuildDir(), "api"));
}
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright 2016-2018 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.gradle.convention;
import org.gradle.api.Project;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.api.artifacts.repositories.ArtifactRepository;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.api.plugins.ExtraPropertiesExtension;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RepositoryConventionPlugin}.
*/
public class RepositoryConventionPluginTests {
private Project project = ProjectBuilder.builder().build();
@BeforeEach
public void setUp() {
this.project.getProperties().clear();
}
@Test
public void applyWhenIsReleaseThenShouldIncludeReleaseRepo() {
this.project.setVersion("1.0.0.RELEASE");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertReleaseRepository(repositories);
}
@Test
public void applyWhenIsMilestoneThenShouldIncludeMilestoneRepo() {
this.project.setVersion("1.0.0.M1");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertMilestoneRepository(repositories); // milestone
}
@Test
public void applyWhenIsSnapshotThenShouldIncludeSnapshotRepo() {
this.project.setVersion("1.0.0.BUILD-SNAPSHOT");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertSnapshotRepository(repositories);
}
@Test
public void applyWhenIsSnapshotWithForceReleaseThenShouldOnlyIncludeReleaseRepo() {
this.project.getExtensions().getByType(ExtraPropertiesExtension.class)
.set("forceMavenRepositories", "release");
this.project.setVersion("1.0.0.RELEASE");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertReleaseRepository(repositories);
}
@Test
public void applyWhenIsReleaseWithForceMilestoneThenShouldIncludeMilestoneRepo() {
this.project.getExtensions().getByType(ExtraPropertiesExtension.class)
.set("forceMavenRepositories", "milestone");
this.project.setVersion("1.0.0.RELEASE");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertMilestoneRepository(repositories);
}
@Test
public void applyWhenIsReleaseWithForceSnapshotThenShouldIncludeSnapshotRepo() {
this.project.getExtensions().getByType(ExtraPropertiesExtension.class)
.set("forceMavenRepositories", "snapshot");
this.project.setVersion("1.0.0.RELEASE");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertSnapshotRepository(repositories);
}
@Test
public void applyWhenIsReleaseWithForceLocalThenShouldIncludeReleaseAndLocalRepos() {
this.project.getExtensions().getByType(ExtraPropertiesExtension.class)
.set("forceMavenRepositories", "local");
this.project.setVersion("1.0.0.RELEASE");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertThat(repositories).hasSize(5);
assertThat((repositories.get(0)).getName()).isEqualTo("MavenLocal");
}
@Test
public void applyWhenIsReleaseWithForceMilestoneAndLocalThenShouldIncludeMilestoneAndLocalRepos() {
this.project.getExtensions().getByType(ExtraPropertiesExtension.class)
.set("forceMavenRepositories", "milestone,local");
this.project.setVersion("1.0.0.RELEASE");
this.project.getPluginManager().apply(RepositoryConventionPlugin.class);
RepositoryHandler repositories = this.project.getRepositories();
assertThat(repositories).hasSize(6);
assertThat((repositories.get(0)).getName()).isEqualTo("MavenLocal");
}
private void assertSnapshotRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(6);
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://jcenter.bintray.com/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
.isEqualTo("https://repo.spring.io/snapshot/");
assertThat(((MavenArtifactRepository) repositories.get(3)).getUrl().toString())
.isEqualTo("https://repo.spring.io/milestone/");
}
private void assertMilestoneRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(5);
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://jcenter.bintray.com/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
.isEqualTo("https://repo.spring.io/milestone/");
}
private void assertReleaseRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(4);
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://jcenter.bintray.com/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
.isEqualTo("https://repo.spring.io/release/");
}
}

View File

@@ -0,0 +1,70 @@
package io.spring.gradle.convention;
import io.spring.gradle.TestKit;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
public class ShowcaseITest {
private TestKit testKit;
@BeforeEach
void setup(@TempDir Path tempDir) {
this.testKit = new TestKit(tempDir.toFile());
}
@Test
public void build() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/showcase/")
.withArguments("build", "--stacktrace")
.forwardOutput()
.build();
assertThat(result.getOutput()).contains("BUILD SUCCESSFUL");
}
@Test
@Disabled
public void install() throws Exception {
BuildResult result = this.testKit
.withProjectResource("samples/showcase/")
.withArguments("install", "--stacktrace")
.build();
assertThat(result.getOutput()).contains("SUCCESS");
File pom = new File(testKit.getRootDir(), "sgbcs-core/build/poms/pom-default.xml");
assertThat(pom).exists();
String pomText = new String(Files.readAllBytes(pom.toPath()));
String pomTextNoSpace = pomText.replaceAll("\\s", "");
assertThat(pomText).doesNotContain("<dependencyManagement>");
assertThat(pomTextNoSpace).contains("<dependency>\n <groupId>org.springframework</groupId>\n <artifactId>spring-test</artifactId>\n <scope>test</scope>\n <version>4.3.6.RELEASE</version>\n </dependency>".replaceAll("\\s", ""));
assertThat(pomTextNoSpace).contains("<developers>\n <developer>\n <id>rwinch</id>\n <name>Rob Winch</name>\n <email>rwinch@pivotal.io</email>\n </developer>\n <developer>\n <id>jgrandja</id>\n <name>Joe Grandja</name>\n <email>jgrandja@pivotal.io</email>\n </developer>\n </developers>".replaceAll("\\s", ""));
assertThat(pomTextNoSpace).contains("<scm>\n <connection>scm:git:git://github.com/spring-projects/spring-security</connection>\n <developerConnection>scm:git:git://github.com/spring-projects/spring-security</developerConnection>\n <url>https://github.com/spring-projects/spring-security</url>\n </scm>".replaceAll("\\s", ""));
assertThat(pomTextNoSpace).contains("<description>sgbcs-core</description>");
assertThat(pomTextNoSpace).contains("<url>https://spring.io/spring-security</url>");
assertThat(pomTextNoSpace).contains("<organization>\n <name>spring.io</name>\n <url>https://spring.io/</url>\n </organization>".replaceAll("\\s", ""));
assertThat(pomTextNoSpace).contains(" <licenses>\n <license>\n <name>The Apache Software License, Version 2.0</name>\n <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>\n <distribution>repo</distribution>\n </license>\n </licenses>".replaceAll("\\s", ""));
assertThat(pomTextNoSpace).contains("<scm>\n <connection>scm:git:git://github.com/spring-projects/spring-security</connection>\n <developerConnection>scm:git:git://github.com/spring-projects/spring-security</developerConnection>\n <url>https://github.com/spring-projects/spring-security</url>\n </scm>".replaceAll("\\s", ""));
File bom = new File(testKit.getRootDir(), "bom/build/poms/pom-default.xml");
assertThat(bom).exists();
assertThat(bom).hasContent("<artifactId>sgbcs-core</artifactId>");
BuildResult secondBuild = this.testKit.withProjectResource("samples/showcase/").withArguments("mavenBom", "--stacktrace").build();
// mavenBom is not up to date since install is never up to date
assertThat(result.task(":bom:mavenBom").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
}

View File

@@ -0,0 +1,61 @@
package io.spring.gradle.convention;
import io.spring.gradle.TestKit;
import org.apache.commons.io.IOUtils;
import org.gradle.testkit.runner.BuildResult;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import static org.assertj.core.api.Assertions.assertThat;
public class SpringMavenPluginITest {
private TestKit testKit;
@BeforeEach
void setup(@TempDir Path tempDir) {
this.testKit = new TestKit(tempDir.toFile());
}
@Disabled
@Test
public void install() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/maven/install")
.withArguments("install")
.build();
assertThat(result.getOutput()).contains("SUCCESS");
File pom = new File(testKit.getRootDir(), "build/poms/pom-default.xml");
assertThat(pom).exists();
String pomText = new String(Files.readAllBytes(pom.toPath()));
assertThat(pomText.replaceAll("\\s", "")).contains("<dependency>\n <groupId>aopalliance</groupId>\n <artifactId>aopalliance</artifactId>\n <version>1.0</version>\n <scope>compile</scope>\n <optional>true</optional>\n </dependency>".replaceAll("\\s", ""));
}
@Disabled
@Test
public void signArchivesWhenInMemory() throws Exception {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(2);
map.put("ORG_GRADLE_PROJECT_signingKey", getSigningKey());
map.put("ORG_GRADLE_PROJECT_signingPassword", "password");
BuildResult result = this.testKit.withProjectResource("samples/maven/signing")
.withArguments("signArchives")
.withEnvironment(map)
.forwardOutput()
.build();
assertThat(result.getOutput()).contains("SUCCESS");
final File jar = new File(testKit.getRootDir(), "build/libs/signing-1.0.0.RELEASE.jar");
assertThat(jar).exists();
File signature = new File(jar.getAbsolutePath() + ".asc");
assertThat(signature).exists();
}
public String getSigningKey() throws Exception {
return IOUtils.toString(getClass().getResource("/test-private.pgp"));
}
}

View File

@@ -0,0 +1,31 @@
package io.spring.gradle.convention;
import io.spring.gradle.TestKit;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
public class TestsConfigurationPluginITest {
private TestKit testKit;
@BeforeEach
void setup(@TempDir Path tempDir) {
this.testKit = new TestKit(tempDir.toFile());
}
@Test
public void canFindDepencency() throws Exception {
BuildResult result = this.testKit.withProjectResource("samples/testsconfiguration")
.withArguments("check")
.build();
assertThat(result.task(":web:check").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
}

View File

@@ -0,0 +1,147 @@
package io.spring.gradle.convention;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import org.gradle.api.Project;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class UtilsTest {
@Mock
Project project;
@Mock
Project rootProject;
@Test
public void getProjectName() {
when(project.getRootProject()).thenReturn(rootProject);
when(rootProject.getName()).thenReturn("spring-security");
assertThat(Utils.getProjectName(project)).isEqualTo("spring-security");
}
@Test
public void getProjectNameWhenEndsWithBuildThenStrippedOut() {
when(project.getRootProject()).thenReturn(rootProject);
when(rootProject.getName()).thenReturn("spring-security-build");
assertThat(Utils.getProjectName(project)).isEqualTo("spring-security");
}
@Test
public void isSnapshotValidWithDot() {
when(project.getVersion()).thenReturn("1.0.0.BUILD-SNAPSHOT");
assertThat(Utils.isSnapshot(project)).isTrue();
}
@Test
public void isSnapshotValidWithNoBuild() {
when(project.getVersion()).thenReturn("1.0.0-SNAPSHOT");
assertThat(Utils.isSnapshot(project)).isTrue();
}
@Test
public void isSnapshotValidWithDash() {
when(project.getVersion()).thenReturn("Theme-BUILD-SNAPSHOT");
assertThat(Utils.isSnapshot(project)).isTrue();
}
@Test
public void isSnapshotInvalid() {
when(project.getVersion()).thenReturn("1.0.0.SNAPSHOT");
assertThat(Utils.isSnapshot(project)).isFalse();
}
@Test
public void isMilestoneValidWithDot() {
when(project.getVersion()).thenReturn("1.0.0.M1");
assertThat(Utils.isMilestone(project)).isTrue();
}
@Test
public void isMilestoneValidWithDash() {
when(project.getVersion()).thenReturn("Theme-M1");
assertThat(Utils.isMilestone(project)).isTrue();
}
@Test
public void isMilestoneValidWithNumberDash() {
when(project.getVersion()).thenReturn("1.0.0-M1");
assertThat(Utils.isMilestone(project)).isTrue();
}
@Test
public void isMilestoneInvalid() {
when(project.getVersion()).thenReturn("1.0.0.M");
assertThat(Utils.isMilestone(project)).isFalse();
}
@Test
public void isReleaseCandidateValidWithDot() {
when(project.getVersion()).thenReturn("1.0.0.RC1");
assertThat(Utils.isMilestone(project)).isTrue();
}
@Test
public void isReleaseCandidateValidWithNumberDash() {
when(project.getVersion()).thenReturn("1.0.0-RC1");
assertThat(Utils.isMilestone(project)).isTrue();
}
@Test
public void isReleaseCandidateValidWithDash() {
when(project.getVersion()).thenReturn("Theme-RC1");
assertThat(Utils.isMilestone(project)).isTrue();
}
@Test
public void isReleaseCandidateInvalid() {
when(project.getVersion()).thenReturn("1.0.0.RC");
assertThat(Utils.isMilestone(project)).isFalse();
}
@Test
public void isReleaseValidWithDot() {
when(project.getVersion()).thenReturn("1.0.0.RELEASE");
assertThat(Utils.isRelease(project)).isTrue();
}
@Test
public void isReleaseValidWithNoRelease() {
when(project.getVersion()).thenReturn("1.0.0");
assertThat(Utils.isRelease(project)).isTrue();
}
@Test
public void isReleaseValidWithDash() {
when(project.getVersion()).thenReturn("Theme-RELEASE");
assertThat(Utils.isRelease(project)).isTrue();
}
@Test
public void isServiceReleaseValid() {
when(project.getVersion()).thenReturn("Theme-SR1");
assertThat(Utils.isRelease(project)).isTrue();
}
}

Some files were not shown because too many files have changed in this diff Show More