Skip to content

Commit

Permalink
Reinstate Maven support
Browse files Browse the repository at this point in the history
Closes gh-81
  • Loading branch information
wilkinsona committed Jul 2, 2024
1 parent d6c72eb commit c8c04b4
Show file tree
Hide file tree
Showing 42 changed files with 2,323 additions and 351 deletions.
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Gradle Enterprise Conventions

Conventions for Gradle projects that use the Gradle Enterprise instance hosted at [ge.spring.io](https://ge.spring.io).
Conventions for Maven and Gradle projects that use the Gradle Enterprise instance hosted at [ge.spring.io](https://ge.spring.io).

## Build cache conventions

Expand All @@ -26,7 +26,9 @@ When applied alongside the [Develocity Plugin](https://plugins.gradle.org/plugin
The build scans will be customized to:

- Add tags:
- `JDK-<version>`, where `<version>` is the value of the `toolchainVersion` project property or, when not set, the specification version of the JDK running the build.
- `JDK-<version>`.
When using Maven, `<version>` is the specification version of the JDK running the build.
When using Gradle, `<version>` is the value of the `toolchainVersion` project property or, when not set, it's the specification version of the JDK running the build.
- `CI` or `Local` depending on where the build is executing.
- `dirty` if the git working copy is dirty.
- Name of the git branch being built.
Expand Down Expand Up @@ -96,6 +98,8 @@ Jenkins is detected by looking for an environment variable named `JENKINS_URL`.
Releases of the conventions are published to Maven Central.
Snapshots are published to https://repo.spring.io/snapshot.

### Gradle

The first step in using the conventions is to make the necessary repository available for plugin resolution.
This is done by configuring a plugin management repository in `settings.gradle`, as shown in the following example:

Expand All @@ -120,3 +124,22 @@ plugins {
// …
}
```

### Maven

To use the conventions, create a `.mvn/extensions.xml` file in the root of the project:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<extensions>
<extension>
<groupId>io.spring.ge.conventions</groupId>
<artifactId>gradle-enterprise-conventions-maven-extension</artifactId>
<version><<version>></version>
</extension>
</extensions>
```

Any existing `.mvn/gradle-enterprise.xml` file should be deleted in favor of the configuration that's provided by the conventions.
Lastly, add `.mvn/.develocity/` to the project's `.gitignore` file.
The conventions are ready to use.
91 changes: 91 additions & 0 deletions gradle-enterprise-conventions-core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
plugins {
id "checkstyle"
id "io.spring.javaformat" version "$javaFormatVersion"
id "java"
id "maven-publish"
}

description = "Gradle Enterprise Conventions Core"
group = 'io.spring.ge.conventions'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
mavenCentral()
}

dependencies {
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}")

testImplementation("org.assertj:assertj-core:3.24.2")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
testImplementation("org.mockito:mockito-core:4.11.0")
}

test {
useJUnitPlatform()
}

java {
withJavadocJar()
withSourcesJar()
}

checkstyle {
def archive = configurations.checkstyle.filter { it.name.startsWith("spring-javaformat-checkstyle")}
config = resources.text.fromArchiveEntry(archive, "io/spring/javaformat/checkstyle/checkstyle.xml")
toolVersion = 9.3
}

tasks.withType(GenerateModuleMetadata).all {
enabled = false
}

if (project.hasProperty("distributionRepository")) {
publishing {
repositories {
maven {
url = "${distributionRepository}"
name = "deployment"
}
}
}
}

publishing {
publications {
maven(MavenPublication) {
from components.java
}
withType(MavenPublication) { mavenPublication ->
pom {
name = project.description
description = project.description
url = 'https://github.com/spring-io/gradle-enterprise-conventions'
organization {
name = 'Pivotal Software, Inc.'
url = 'https://spring.io'
}
licenses {
license {
name = 'The Apache Software License, Version 2.0'
url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
scm {
url = 'https://github.com/spring-io/gradle-enterprise-conventions'
connection = 'scm:git:https://github.com/spring-io/gradle-enterprise-conventions'
}
developers {
developer {
id = 'wilkinsona'
name = 'Andy Wilkinson'
email = 'awilkinson@pivotal.io'
roles = ["Project lead"]
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@
* limitations under the License.
*/

package io.spring.ge.conventions.gradle;
package io.spring.ge.conventions.core;

import java.util.Map;

import com.gradle.develocity.agent.gradle.buildcache.DevelocityBuildCache;
import org.gradle.caching.configuration.BuildCacheConfiguration;

/**
* Conventions that are applied to the build cache.
*
Expand All @@ -30,25 +27,22 @@ public class BuildCacheConventions {

private final Map<String, String> env;

private final Class<? extends DevelocityBuildCache> buildCacheType;

public BuildCacheConventions(Class<? extends DevelocityBuildCache> buildCache) {
this(buildCache, System.getenv());
public BuildCacheConventions() {
this(System.getenv());
}

BuildCacheConventions(Class<? extends DevelocityBuildCache> buildCacheType, Map<String, String> env) {
BuildCacheConventions(Map<String, String> env) {
this.env = env;
this.buildCacheType = buildCacheType;
}

/**
* Applies the conventions to the given {@code buildCache}.
* @param buildCache build cache to be configured
*/
public void execute(BuildCacheConfiguration buildCache) {
buildCache.local((local) -> local.setEnabled(true));
buildCache.remote(this.buildCacheType, (remote) -> {
remote.setEnabled(true);
public void execute(ConfigurableBuildCache buildCache) {
buildCache.local((local) -> local.enable());
buildCache.remote((remote) -> {
remote.enable();
String cacheServer = this.env.get("DEVELOCITY_CACHE_SERVER");
if (cacheServer == null) {
cacheServer = serverOfCacheUrl(this.env.get("GRADLE_ENTERPRISE_CACHE_URL"));
Expand All @@ -62,7 +56,7 @@ public void execute(BuildCacheConfiguration buildCache) {
accessKey = this.env.get("GRADLE_ENTERPRISE_ACCESS_KEY");
}
if (hasText(accessKey) && ContinuousIntegration.detect(this.env) != null) {
remote.setPush(true);
remote.enablePush();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package io.spring.ge.conventions.gradle;
package io.spring.ge.conventions.core;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
Expand All @@ -23,93 +23,89 @@
import java.util.function.Consumer;
import java.util.stream.Collectors;

import com.gradle.develocity.agent.gradle.DevelocityConfiguration;
import com.gradle.develocity.agent.gradle.scan.BuildScanConfiguration;
import io.spring.ge.conventions.gradle.ProcessRunner.RunFailedException;
import org.gradle.api.Action;
import io.spring.ge.conventions.core.ProcessRunner.RunFailedException;

/**
* {@link Action} that configures the {@link BuildScanConfiguration build scan} with
* Spring conventions.
* Conventions that are applied to build scans for Maven and Gradle builds. Spring
* conventions.
*
* @author Andy Wilkinson
*/
class BuildScanConventions implements Action<BuildScanConfiguration> {

private final DevelocityConfiguration develocity;
public class BuildScanConventions {

private final ProcessRunner processRunner;

private final Map<String, String> env;

BuildScanConventions(DevelocityConfiguration develocity, ProcessRunner processRunner) {
this(develocity, processRunner, System.getenv());
public BuildScanConventions(ProcessRunner processRunner) {
this(processRunner, System.getenv());
}

BuildScanConventions(DevelocityConfiguration develocity, ProcessRunner processRunner, Map<String, String> env) {
this.develocity = develocity;
protected BuildScanConventions(ProcessRunner processRunner, Map<String, String> env) {
this.processRunner = processRunner;
this.env = env;
}

/**
* Applies the conventions to the given {@code buildScan}.
* Applies the conventions to the given {@code develocity} and {@code buildScan}.
* @param develocity develocity to be configured
* @param buildScan build scan to be configured
*/
@Override
public void execute(BuildScanConfiguration buildScan) {
public void execute(ConfigurableDevelocity develocity, ConfigurableBuildScan buildScan) {
buildScan.obfuscation((obfuscation) -> obfuscation
.ipAddresses((addresses) -> addresses.stream().map((address) -> "0.0.0.0").collect(Collectors.toList())));
configurePublishing(buildScan);
configurePublishing(develocity, buildScan);
ContinuousIntegration ci = ContinuousIntegration.detect(this.env);
tagBuildScan(buildScan, ci);
buildScan.background(this::addGitMetadata);
buildScan.background((backgrounded) -> addGitMetadata(develocity, backgrounded));
buildScan.background(this::addDockerMetadata);
buildScan.background(this::addDockerComposeMetadata);
addCiMetadata(buildScan, ci);
buildScan.getUploadInBackground().set(ci == null);
buildScan.capture((settings) -> settings.getFileFingerprints().set(true));
buildScan.uploadInBackground(ci == null);
buildScan.captureInputFiles(true);
}

/**
* Configures publishing of the build scan. The default implementation always
* publishes scans when authenticated and publishes them to
* {@code https://ge.spring.io}.
* @param develocity develocity to configure
* @param buildScan build scan to configure
*
*/
protected void configurePublishing(BuildScanConfiguration buildScan) {
buildScan.publishing((publishing) -> publishing.onlyIf((context) -> context.isAuthenticated()));
this.develocity.getServer().set("https://ge.spring.io");
protected void configurePublishing(ConfigurableDevelocity develocity, ConfigurableBuildScan buildScan) {
buildScan.publishIfAuthenticated();
develocity.setServer("https://ge.spring.io");
}

private void tagBuildScan(BuildScanConfiguration buildScan, ContinuousIntegration ci) {
private void tagBuildScan(ConfigurableBuildScan buildScan, ContinuousIntegration ci) {
tagCiOrLocal(buildScan, ci);
tagJdk(buildScan);
tagOperatingSystem(buildScan);
}

private void tagCiOrLocal(BuildScanConfiguration buildScan, ContinuousIntegration ci) {
private void tagCiOrLocal(ConfigurableBuildScan buildScan, ContinuousIntegration ci) {
buildScan.tag((ci != null) ? "CI" : "Local");
}

private void tagJdk(BuildScanConfiguration buildScan) {
private void tagJdk(ConfigurableBuildScan buildScan) {
buildScan.tag("JDK-" + getJdkVersion());
}

protected String getJdkVersion() {
return System.getProperty("java.specification.version");
}

private void tagOperatingSystem(BuildScanConfiguration buildScan) {
private void tagOperatingSystem(ConfigurableBuildScan buildScan) {
buildScan.tag(System.getProperty("os.name"));
}

private void addGitMetadata(BuildScanConfiguration buildScan) {
private void addGitMetadata(ConfigurableDevelocity develocity, ConfigurableBuildScan buildScan) {
run("git", "rev-parse", "--short=8", "--verify", "HEAD").standardOut((gitCommitId) -> {
String commitIdLabel = "Git commit";
buildScan.value(commitIdLabel, gitCommitId);

String server = this.develocity.getServer().getOrNull();
String server = develocity.getServer();
if (server != null) {
buildScan.link("Git commit build scans", server + createSearchUrl(commitIdLabel, gitCommitId));
}
Expand All @@ -124,16 +120,16 @@ private void addGitMetadata(BuildScanConfiguration buildScan) {
});
}

private void addDockerMetadata(BuildScanConfiguration buildScan) {
private void addDockerMetadata(ConfigurableBuildScan buildScan) {
run("docker", "--version").standardOut((dockerVersion) -> buildScan.value("Docker", dockerVersion));
}

private void addDockerComposeMetadata(BuildScanConfiguration buildScan) {
private void addDockerComposeMetadata(ConfigurableBuildScan buildScan) {
run("docker", "compose", "version")
.standardOut((dockerComposeVersion) -> buildScan.value("Docker Compose", dockerComposeVersion));
}

private void addCiMetadata(BuildScanConfiguration buildScan, ContinuousIntegration ci) {
private void addCiMetadata(ConfigurableBuildScan buildScan, ContinuousIntegration ci) {
if (ci == null) {
return;
}
Expand Down
Loading

0 comments on commit c8c04b4

Please sign in to comment.