Skip to content

Commit

Permalink
Add convention sample for single build Gradle plugin and Maven extension
Browse files Browse the repository at this point in the history
  • Loading branch information
erichaagdev committed Jul 30, 2024
1 parent 0ad93f7 commit d991382
Show file tree
Hide file tree
Showing 71 changed files with 3,014 additions and 8 deletions.
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ updates:
schedule:
interval: "daily"
time: "02:00"
- package-ecosystem: "gradle"
directory: "convention-develocity-shared"
registries:
- gradle-plugin-portal
schedule:
interval: "daily"
time: "02:00"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,12 @@ jobs:
sed -i '/distributionSha256Sum.*/d' gradle/wrapper/gradle-wrapper.properties
./gradlew wrapper --gradle-version=${{ matrix.versions.version }} --no-scan
./gradlew wrapper --gradle-version=${{ matrix.versions.version }} --no-scan
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }}
- name: Verify example build
id: build
working-directory: convention-develocity-gradle-plugin/examples/gradle_${{ matrix.versions.sample }}
run: ./gradlew build -Ddevelocity.url=https://ge.solutions-team.gradle.com
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }}
DEVELOCITY_ACCESS_KEY: ${{ secrets.DV_SOLUTIONS_ACCESS_KEY }}
- name: Verify Build Scan published
if: ${{ !steps.build.outputs.build-scan-url }}
run: echo "::error ::No Build Scan published"; exit 1
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,9 @@ jobs:
- name: Set Maven version
if: ${{ matrix.versions.version != '(Current)' }}
working-directory: convention-develocity-maven-extension/examples/maven_${{ matrix.versions.sample }}
run: ./mvnw wrapper:wrapper -Dmaven=${{ matrix.versions.version }} -Dgradle.enterprise.url=https://ge.solutions-team.gradle.com
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }}
run: ./mvnw wrapper:wrapper -Dmaven=${{ matrix.versions.version }} -Ddevelocity.scan.disabled
- name: Verify example build
working-directory: convention-develocity-maven-extension/examples/maven_${{ matrix.versions.sample }}
run: ./mvnw clean verify -Ddevelocity.url=https://ge.solutions-team.gradle.com
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }}
DEVELOCITY_ACCESS_KEY: ${{ secrets.DV_SOLUTIONS_ACCESS_KEY }}
123 changes: 123 additions & 0 deletions .github/workflows/convention-develocity-shared-verification.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Verify Convention Develocity Shared

on:
push:
branches: [ main ]
paths: [ 'convention-develocity-shared/**' ]
pull_request:
branches: [ main ]
paths: [ 'convention-develocity-shared/**' ]
workflow_dispatch:

jobs:
build:
name: Build Convention Develocity Shared
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 8
uses: actions/setup-java@v4
with:
java-version: '8'
distribution: 'temurin'
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Build with Gradle
working-directory: convention-develocity-shared
run: ./gradlew build publishToMavenLocal
- name: Upload convention
uses: actions/upload-artifact@v4
with:
name: convention-develocity-shared
path: ~/.m2/repository/com/myorg

verification_gradle:
name: Verify Example Build for Gradle ${{ matrix.versions.version }}
needs: [build]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
versions:
- sample: '5'
version: '5.0'
- sample: '6'
version: '6.0.1'
- sample: '6.9_and_later'
version: '6.9.4'
- sample: '6.9_and_later'
version: '7.0.2'
- sample: '6.9_and_later'
version: '8.0.2'
- sample: '6.9_and_later'
version: '(Current)'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 8
uses: actions/setup-java@v4
with:
java-version: '8'
distribution: 'temurin'
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Download plugin
uses: actions/download-artifact@v4
with:
name: convention-develocity-shared
path: ~/.m2/repository/com/myorg
- name: Set Gradle version
if: ${{ matrix.versions.version != '(Current)' }}
working-directory: convention-develocity-shared/examples/gradle_${{ matrix.versions.sample }}
run: |
sed -i '/distributionSha256Sum.*/d' gradle/wrapper/gradle-wrapper.properties
./gradlew wrapper --gradle-version=${{ matrix.versions.version }} --no-scan
./gradlew wrapper --gradle-version=${{ matrix.versions.version }} --no-scan
- name: Verify example build
id: build
working-directory: convention-develocity-shared/examples/gradle_${{ matrix.versions.sample }}
run: ./gradlew build -Ddevelocity.url=https://ge.solutions-team.gradle.com
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.DV_SOLUTIONS_ACCESS_KEY }}
- name: Verify Build Scan published
if: ${{ !steps.build.outputs.build-scan-url }}
run: echo "::error ::No Build Scan published"; exit 1

verification:
name: Verify Example Build for Maven ${{ matrix.versions.version }}
needs: [build]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
versions:
- sample: '3'
version: '3.6.3'
- sample: '3'
version: '3.8.8'
- sample: '3'
version: '(Current)'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 8
uses: actions/setup-java@v4
with:
java-version: '8'
distribution: 'temurin'
cache: maven
- name: Download extension
uses: actions/download-artifact@v4
with:
name: convention-develocity-shared
path: ~/.m2/repository/com/myorg
- name: Set Maven version
if: ${{ matrix.versions.version != '(Current)' }}
working-directory: convention-develocity-shared/examples/maven_${{ matrix.versions.sample }}
run: ./mvnw wrapper:wrapper -Dmaven=${{ matrix.versions.version }} -Ddevelocity.scan.disabled
- name: Verify example build
working-directory: convention-develocity-shared/examples/maven_${{ matrix.versions.sample }}
run: ./mvnw clean verify -Ddevelocity.url=https://ge.solutions-team.gradle.com
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.DV_SOLUTIONS_ACCESS_KEY }}
2 changes: 1 addition & 1 deletion convention-develocity-gradle-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ cd plugins/gradle-5-or-newer
./gradlew publishToMavenLocal
```

Once you have published the plugins, you can run the four example builds under `examples`:
Once you have published the plugins, you can run the five example builds under `examples`:

```bash
cd examples/gradle_6_and_later
Expand Down
143 changes: 143 additions & 0 deletions convention-develocity-shared/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
## Develocity Conventions

This project demonstrates how a convention Gradle plugin and Maven extension can share the same Develocity build configuration across multiple projects.
It is intended to serve as a starting point for creating your own Gradle plugin and Maven extension that applies your specific Develocity configuration.
Note the inline comments in the build and source code for things to adjust specifically to your needs.

### Applying the extension to your build

#### Gradle

##### Using a dynamic version

For builds using Gradle 6.9 and later, it's recommended to apply the convention plugin using a [dynamic version](https://docs.gradle.org/current/userguide/dynamic_versions.html).
This approach ensures that the latest version of the plugin is automatically used, but only for the specified major version.
For example, the following will automatically use the latest `1.x` version of the plugin up to, but excluding, version `2.0`:

```groovy
plugins {
id 'com.myorg.convention-develocity-gradle-plugin' version '1.+'
}
```

This allows you to quickly roll out non-breaking changes to all consumers of the convention plugin.
Breaking changes in the plugin should be released under a new major version, e.g., `2.0`.
All consumers of the plugin will then need to update the specified major version, e.g., `2.+`.

> [!IMPORTANT]
> Using dynamic versions should only be done when releases and development versions are published to separate repositories.
> Not having this separation introduces the risk that consumers will use a development version of the plugin not yet ready to be used.
> In these scenarios, using a static version is preferred.
##### Using a static version

For projects using earlier versions of Gradle, the convention plugin must be applied using a static version.
For example:

```groovy
plugins {
id 'com.myorg.convention-develocity-gradle-plugin' version '1.0'
}
```

For each new release of the convention plugin, consuming builds will need to be explicitly updated.

#### Maven

##### Using a version range

It's recommended to apply the convention extension using a [version range](https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html).
This approach ensures that the latest version of the extension is automatically used, up to the specified maximum version.
For example, the following will automatically use the latest version of the extension up to, but excluding, version `2.0`:

```xml
<extensions>
<extension>
<groupId>com.myorg</groupId>
<artifactId>convention-develocity-maven-extension</artifactId>
<version>(,2.0)</version>
</extension>
</extensions>
```

This allows you to quickly roll out non-breaking changes to all consumers of the convention extension.
Breaking changes in the extension should be released under a new major version, e.g., `2.0`.
All consumers of the extension will then need to update the upper boundary of the version range to the next major version, e.g., `(,3.0)`.

> [!IMPORTANT]
> Using version ranges should only be done when releases and development versions are published to separate repositories.
> Not having this separation introduces the risk that consumers will use a development version of the extension not yet ready to be used.
> In these scenarios, using a static version is preferred.
##### Using a static version

In scenarios where a version range can't be used, e.g., when releases and development versions are published to the same repository, a static version should be used.
For example:

```xml
<extensions>
<extension>
<groupId>com.myorg</groupId>
<artifactId>convention-develocity-maven-extension</artifactId>
<version>1.0</version>
</extension>
</extensions>
```

For each new release of the convention extension, consuming builds will need to be explicitly updated.

### Content

This project is structured as follows:

* `convention-develocity-gradle-plugin` - Contains the convention Gradle plugin
* `convention-develocity-maven-extension` - Contains the convention Maven extension
* `convention-develocity-shared` - Contains the convention logic shared between build tools
* `examples` - Contains example builds that apply the convention Gradle plugin or Maven extension for different Gradle and Maven versions
* `gradle_5` - Applies the convention Gradle plugin on a Gradle 5 build
* `gradle_6` - Applies the convention Gradle plugin on a Gradle 6 build
* `gradle_6.9_and_later` - Applies the convention Gradle plugin on a Gradle 6.9 and later build
* `maven_3` - Applies the convention Maven extension on a Maven 3 build

### Running the example builds

Before running the example builds, publish all components to your local Maven repository.

```bash
./gradlew publishToMavenLocal
```

> [!NOTE]
> You would publish these components to your internal artifact provider, e.g., Artifactory or Nexus, for production usage.
> The shared convention plugin at `buildSrc/src/main/kotlin/com.myorg.publishing-conventions.gradle.kts` can be used to configure the publishing of all components.
#### Gradle

Once you have published the plugin, you can run the three example builds under `examples`:

```bash
cd examples/gradle_5
./gradlew build

cd examples/gradle_6
./gradlew build

cd examples/gradle_6_and_later
./gradlew build
```

#### Maven

Once you have installed the extension, you can run the example build under `examples`:

```bash
cd examples/maven_3
./mvnw clean verify
```

> [!IMPORTANT]
> The artifact provider must be configured as a [Mirror](https://maven.apache.org/guides/mini/guide-mirror-settings.html) to Maven Central in order to correctly resolve the extension.
#### Requirements

To run the example builds, use Java 8 or higher.
7 changes: 7 additions & 0 deletions convention-develocity-shared/buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
`kotlin-dsl`
}

repositories {
gradlePluginPortal()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import org.gradle.jvm.toolchain.JavaLanguageVersion

plugins {
id("java")
}

java {
withJavadocJar()
withSourcesJar()
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
plugins {
id("maven-publish")
}

publishing {
repositories {
maven {
// CHANGE ME: change to point to your organization's artifact repository
url = uri("https://repo.myorg.com/maven")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
plugins {
id("com.myorg.java-conventions")
id("com.myorg.publishing-conventions")
id("java-gradle-plugin")
}

repositories {
gradlePluginPortal()
}

dependencies {
implementation("com.gradle:develocity-gradle-plugin:3.17.6")
implementation("com.gradle:common-custom-user-data-gradle-plugin:2.0.2")
implementation(project(":convention-develocity-shared"))
}

gradlePlugin {
plugins {
create("develocityConventions") {
// CHANGE ME: change for your organization
id = "com.myorg.convention-develocity-gradle-plugin"
displayName = "Convention Develocity Gradle Plugin"
description = "A Gradle plugin to apply and configure the Develocity Gradle plugin for com.myorg"
implementationClass = "com.myorg.ConventionDevelocityGradlePlugin"
}
}
}

tasks.withType<ValidatePlugins>().configureEach {
failOnWarning = true
enableStricterValidation = true
}
Loading

0 comments on commit d991382

Please sign in to comment.