Skip to content

Commit 1fdb522

Browse files
Migrate build logic to conventions plugins (#2484)
* Overhauls our builds to use convention plugins --------- Co-authored-by: Hunter Mellema <[email protected]>
1 parent b855e2b commit 1fdb522

File tree

47 files changed

+959
-947
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+959
-947
lines changed

.github/workflows/ci.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ jobs:
2525
java-version: ${{ matrix.java }}
2626
distribution: 'corretto'
2727

28-
- name: Clean, build and javadoc
28+
- name: Clean, build, test, and javadoc
2929
run: ./gradlew clean build javadoc -Plog-tests --stacktrace
3030

3131
- name: Allow long file names in git for windows
3232
if: matrix.os == 'windows-latest'
3333
run: git config --system core.longpaths true
3434

35-
- name: CLI integration tests
35+
- name: Integration tests
3636
if: matrix.java == 17
37-
run: ./gradlew :smithy-cli:integ -Plog-tests --stacktrace
37+
run: ./gradlew integ -Plog-tests --stacktrace
3838

3939
- uses: actions/upload-artifact@v4
4040
if: failure()

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ target/
2828
**/dependency-reduced-pom.xml
2929

3030
# Gradle
31-
/.gradle
31+
**/.gradle
3232
build/
3333
!smithy-build/src/main/java/software/amazon/smithy/build
3434
!smithy-build/src/main/resources/software/amazon/smithy/build

build.gradle.kts

+36-258
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import org.jreleaser.gradle.plugin.JReleaserExtension
2+
import org.jreleaser.model.Active
3+
14
/*
25
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
36
*
@@ -13,263 +16,35 @@
1316
* permissions and limitations under the License.
1417
*/
1518

16-
import com.github.spotbugs.snom.Effort
17-
import org.jreleaser.model.Active
18-
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
19-
2019
plugins {
21-
`java-library`
22-
`maven-publish`
23-
signing
24-
checkstyle
25-
jacoco
26-
id("com.github.spotbugs") version "6.0.8"
27-
id("io.codearte.nexus-staging") version "0.30.0"
28-
id("me.champeau.jmh") version "0.7.2"
29-
id("com.github.johnrengelman.shadow") version "7.1.2"
30-
id("org.jreleaser") version "1.12.0" apply false
20+
java
21+
alias(libs.plugins.jreleaser) apply false
3122
}
3223

3324
// Load the Smithy version from VERSION.
3425
val libraryVersion = project.file("VERSION").readText().trim()
35-
3626
println("Smithy version: '$libraryVersion'")
3727

3828
allprojects {
3929
group = "software.amazon.smithy"
4030
version = libraryVersion
4131
}
4232

43-
// JReleaser publishes artifacts from a local staging repository, rather than maven local.
44-
// https://jreleaser.org/guide/latest/examples/maven/staging-artifacts.html#_gradle
45-
val stagingDirectory = rootProject.layout.buildDirectory.dir("staging")
46-
47-
subprojects {
48-
apply(plugin = "java-library")
49-
50-
java {
51-
sourceCompatibility = JavaVersion.VERSION_1_8
52-
targetCompatibility = JavaVersion.VERSION_1_8
53-
}
54-
55-
repositories {
56-
mavenLocal()
57-
mavenCentral()
58-
}
59-
60-
dependencies {
61-
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
62-
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0")
63-
testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0")
64-
testImplementation("org.hamcrest:hamcrest:2.1")
65-
testCompileOnly("org.apiguardian:apiguardian-api:1.1.2")
66-
}
67-
68-
// Reusable license copySpec for building JARs
69-
val licenseSpec = copySpec {
70-
from("${project.rootDir}/LICENSE")
71-
from("${project.rootDir}/NOTICE")
72-
}
73-
74-
// Set up tasks that build source and javadoc jars.
75-
tasks.register<Jar>("sourcesJar") {
76-
metaInf.with(licenseSpec)
77-
from(sourceSets.main.get().allSource)
78-
archiveClassifier.set("sources")
79-
}
80-
81-
// Build a javadoc JAR too.
82-
tasks.register<Jar>("javadocJar") {
83-
metaInf.with(licenseSpec)
84-
from(tasks.javadoc)
85-
archiveClassifier.set("javadoc")
86-
}
87-
88-
// Include an Automatic-Module-Name in all JARs.
89-
afterEvaluate {
90-
tasks.jar {
91-
metaInf.with(licenseSpec)
92-
inputs.property("moduleName", project.extra.get("moduleName"))
93-
manifest {
94-
attributes("Automatic-Module-Name" to project.extra.get("moduleName"))
95-
}
96-
}
97-
}
98-
99-
// Always run javadoc after build.
100-
tasks["build"].dependsOn(tasks["javadoc"])
101-
102-
// ==== Tests ====
103-
// https://docs.gradle.org/current/samples/sample_java_multi_project_with_junit5_tests.html
104-
tasks.test {
105-
useJUnitPlatform()
106-
}
107-
108-
// Log on passed, skipped, and failed test events if the `-Plog-tests` property is set.
109-
// https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/logging/TestLoggingContainer.html
110-
if (project.hasProperty("log-tests")) {
111-
tasks.test {
112-
testLogging {
113-
events("passed", "skipped", "failed")
114-
exceptionFormat = TestExceptionFormat.FULL
115-
}
116-
}
117-
}
118-
119-
// ==== Maven ====
120-
apply(plugin = "maven-publish")
121-
apply(plugin = "signing")
122-
apply(plugin = "com.github.johnrengelman.shadow")
123-
124-
// This is a little hacky, but currently needed to build a shadowed CLI JAR and smithy-syntax JAR with the same
125-
// customizations as other JARs.
126-
if (project.name != "smithy-cli" && project.name != "smithy-syntax") {
127-
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
128-
isEnabled = false
129-
}
130-
}
131-
132-
publishing {
133-
repositories {
134-
// JReleaser's `publish` task publishes to all repositories, so only configure one.
135-
maven {
136-
name = "localStaging"
137-
url = uri(stagingDirectory)
138-
}
139-
}
140-
141-
publications {
142-
create<MavenPublication>("mavenJava") {
143-
if (tasks.findByName("shadowJar")?.enabled == true) {
144-
project.shadow.component(this)
145-
} else {
146-
from(components["java"])
147-
}
148-
149-
// Ship the source and javadoc jars.
150-
artifact(tasks["sourcesJar"])
151-
artifact(tasks["javadocJar"])
152-
153-
// Include extra information in the POMs.
154-
afterEvaluate {
155-
pom {
156-
name.set(project.ext["displayName"].toString())
157-
description.set(project.description)
158-
url.set("https://github.com/smithy-lang/smithy")
159-
licenses {
160-
license {
161-
name.set("Apache License 2.0")
162-
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
163-
distribution.set("repo")
164-
}
165-
}
166-
developers {
167-
developer {
168-
id.set("smithy")
169-
name.set("Smithy")
170-
organization.set("Amazon Web Services")
171-
organizationUrl.set("https://aws.amazon.com")
172-
roles.add("developer")
173-
}
174-
}
175-
scm {
176-
url.set("https://github.com/smithy-lang/smithy.git")
177-
}
178-
}
179-
}
180-
}
181-
}
182-
183-
// Don't sign the artifacts if we didn't get a key and password to use.
184-
if (project.hasProperty("signingKey") && project.hasProperty("signingPassword")) {
185-
signing {
186-
useInMemoryPgpKeys(
187-
project.property("signingKey").toString(),
188-
project.property("signingPassword").toString()
189-
)
190-
sign(publishing.publications["mavenJava"])
191-
}
192-
}
193-
}
194-
195-
tasks.register<Copy>("copyMavenMetadataForDevelopment") {
196-
from("build/tmp/publishMavenJavaPublicationToMavenLocal") {
197-
rename("module-maven-metadata.xml", "maven-metadata.xml")
198-
}
199-
val wdir = "${System.getProperty("user.home")}/.m2/repository/software/amazon/smithy/${project.name}"
200-
into(wdir)
201-
}
202-
203-
tasks.publishToMavenLocal {
204-
finalizedBy("copyMavenMetadataForDevelopment")
205-
}
206-
207-
// ==== CheckStyle ====
208-
// https://docs.gradle.org/current/userguide/checkstyle_plugin.html
209-
apply(plugin = "checkstyle")
210-
tasks.named("checkstyleTest") {
211-
enabled = false
212-
}
213-
214-
// ==== Code coverage ====
215-
// https://docs.gradle.org/current/userguide/jacoco_plugin.html
216-
apply(plugin = "jacoco")
217-
218-
// report is always generated after tests run
219-
tasks.test {
220-
finalizedBy(tasks.jacocoTestReport)
221-
}
222-
223-
// tests are required to run before generating the report
224-
tasks.jacocoTestReport {
225-
dependsOn(tasks.test)
226-
reports {
227-
xml.required.set(false)
228-
csv.required.set(false)
229-
html.outputLocation.set(file("$buildDir/reports/jacoco"))
230-
}
231-
}
232-
233-
// ==== Spotbugs ====
234-
// https://plugins.gradle.org/plugin/com.github.spotbugs
235-
apply(plugin = "com.github.spotbugs")
236-
// We don't need to lint tests.
237-
tasks.named("spotbugsTest") {
238-
enabled = false
239-
}
240-
// Configure the bug filter for spotbugs.
241-
spotbugs {
242-
effort.set(Effort.MAX)
243-
excludeFilter.set(file("${project.rootDir}/config/spotbugs/filter.xml"))
244-
}
245-
}
246-
247-
// The root project doesn't produce a JAR.
248-
tasks.named("jar") {
249-
enabled = false
250-
}
251-
252-
// ==== Javadoc ====
33+
// Consolidated Javadoc creation
25334
afterEvaluate {
254-
tasks.javadoc {
255-
title = "Smithy API ${version}"
256-
setDestinationDir(file("${project.buildDir}/docs/javadoc/latest"))
257-
// Build a consolidated javadoc of all subprojects.
258-
source(subprojects.map { project(it.path).sourceSets.main.get().allJava })
259-
classpath = files(subprojects.map { project(it.path).sourceSets.main.get().compileClasspath })
260-
}
261-
}
262-
263-
// Disable HTML doclint to work around heading tag sequence validation
264-
// inconsistencies between JDK15 and earlier Java versions.
265-
allprojects {
266-
tasks.withType<Javadoc> {
267-
(options as StandardJavadocDocletOptions).apply {
268-
addStringOption("Xdoclint:-html", "-quiet")
269-
// Fixed in JDK 12: https://bugs.openjdk.java.net/browse/JDK-8215291
270-
// --no-module-directories does not exist in JDK 8 and is removed in 13
271-
if (JavaVersion.current().run { isJava9 || isJava10 || isJava11 }) {
272-
addBooleanOption("-no-module-directories", true)
35+
tasks {
36+
javadoc {
37+
title = "Smithy API ${version}"
38+
setDestinationDir(layout.buildDirectory.dir("docs/javadoc/latest").get().asFile)
39+
source(subprojects.map { project(it.path).sourceSets.main.get().allJava })
40+
classpath = files(subprojects.map { project(it.path).sourceSets.main.get().compileClasspath })
41+
(options as StandardJavadocDocletOptions).apply {
42+
addStringOption("Xdoclint:-html", "-quiet")
43+
// Fixed in JDK 12: https://bugs.openjdk.java.net/browse/JDK-8215291
44+
// --no-module-directories does not exist in JDK 8 and is removed in 13
45+
if (JavaVersion.current().run { isJava9 || isJava10 || isJava11 }) {
46+
addBooleanOption("-no-module-directories", true)
47+
}
27348
}
27449
}
27550
}
@@ -280,29 +55,32 @@ allprojects {
28055
if (project.hasProperty("release.main")) {
28156
apply(plugin = "org.jreleaser")
28257

283-
extensions.configure<org.jreleaser.gradle.plugin.JReleaserExtension> {
284-
dryrun.set(false)
58+
// Workaround for https://github.com/jreleaser/jreleaser/issues/1492
59+
tasks.register("clean")
60+
61+
configure<JReleaserExtension> {
62+
dryrun = false
28563

28664
// Used for creating and pushing the version tag, but this configuration ensures that
28765
// an actual GitHub release isn't created (since the CLI release does that)
28866
release {
28967
github {
290-
skipRelease.set(true)
291-
tagName.set("{{projectVersion}}")
68+
skipRelease = true
69+
tagName = "{{projectVersion}}"
29270
}
29371
}
29472

29573
// Used to announce a release to configured announcers.
29674
// https://jreleaser.org/guide/latest/reference/announce/index.html
29775
announce {
298-
active.set(Active.NEVER)
76+
active = Active.NEVER
29977
}
30078

30179
// Signing configuration.
30280
// https://jreleaser.org/guide/latest/reference/signing.html
30381
signing {
304-
active.set(Active.ALWAYS)
305-
armored.set(true)
82+
active = Active.ALWAYS
83+
armored = true
30684
}
30785

30886
// Configuration for deploying to Maven Central.
@@ -311,15 +89,15 @@ if (project.hasProperty("release.main")) {
31189
maven {
31290
nexus2 {
31391
create("maven-central") {
314-
active.set(Active.ALWAYS)
315-
url.set("https://aws.oss.sonatype.org/service/local")
316-
snapshotUrl.set("https://aws.oss.sonatype.org/content/repositories/snapshots")
317-
closeRepository.set(true)
318-
releaseRepository.set(true)
319-
stagingRepository(stagingDirectory.get().toString())
92+
active = Active.ALWAYS
93+
url = "https://aws.oss.sonatype.org/service/local"
94+
snapshotUrl = "https://aws.oss.sonatype.org/content/repositories/snapshots"
95+
closeRepository = true
96+
releaseRepository = true
97+
stagingRepository(stagingDir().get().asFile.path)
32098
}
32199
}
322100
}
323101
}
324102
}
325-
}
103+
}

buildSrc/build.gradle.kts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
gradlePluginPortal()
8+
}
9+
10+
dependencies {
11+
// Plugins used by buildSrc scripts
12+
implementation(libs.spotbugs)
13+
implementation(libs.spotless)
14+
implementation(libs.jmh)
15+
16+
// https://github.com/gradle/gradle/issues/15383
17+
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
18+
}

0 commit comments

Comments
 (0)