Skip to content

Commit 3819eb2

Browse files
committed
feat: Add build-logic with Versioning and Publishing plugins
1 parent 70b15ac commit 3819eb2

File tree

8 files changed

+252
-1
lines changed

8 files changed

+252
-1
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
.gradle
33
/local.properties
44
/.idea
5-
/build
5+
build/
66
.DS_Store
77
/.kotlin
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
repositories {
6+
google()
7+
mavenCentral()
8+
gradlePluginPortal()
9+
}
10+
11+
dependencies {
12+
compileOnly("com.android.tools.build:gradle:8.2.2")
13+
implementation("software.amazon.awssdk:codeartifact:2.20.68")
14+
implementation("pl.allegro.tech.build:axion-release-plugin:1.15.4")
15+
}
16+
17+
gradlePlugin {
18+
plugins {
19+
register("projectVersioning") {
20+
id = "convention.project.versioning"
21+
implementationClass = "plugins.VersioningConventionPlugin"
22+
}
23+
register("projectPublishing") {
24+
id = "convention.publishing"
25+
implementationClass = "plugins.PublishingConventionPlugin"
26+
}
27+
}
28+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package extensions
2+
3+
open class PublishingConfigExtension(
4+
var groupId: String = "",
5+
var artifactId: String = "",
6+
// CodeArtifact specific
7+
var domain: String = "",
8+
var domainOwner: String = "",
9+
var repository: String = "",
10+
var region: String = "us-east-1",
11+
) {
12+
fun groupId(value: String) {
13+
groupId = value
14+
}
15+
fun artifactId(value: String) {
16+
artifactId = value
17+
}
18+
fun domain(value: String) {
19+
domain = value
20+
}
21+
fun domainOwner(value: String) {
22+
domainOwner = value
23+
}
24+
fun repository(value: String) {
25+
repository = value
26+
}
27+
fun region(value: String) {
28+
region = value
29+
}
30+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package extensions
2+
3+
open class VersioningExtension(
4+
var tagPrefix: String = "",
5+
var useHighestVersion: Boolean = true,
6+
var initialVersion: String = "0.1.0",
7+
) {
8+
9+
fun tagPrefix(value: String) {
10+
tagPrefix = value
11+
}
12+
13+
fun useHighestVersion(value: Boolean) {
14+
useHighestVersion = value
15+
}
16+
17+
fun initialVersion(value: String) {
18+
initialVersion = value
19+
}
20+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package plugins
2+
3+
import extensions.PublishingConfigExtension
4+
import org.gradle.api.Plugin
5+
import org.gradle.api.Project
6+
import org.gradle.api.publish.PublishingExtension
7+
import org.gradle.api.publish.maven.MavenPublication
8+
import org.gradle.kotlin.dsl.configure
9+
import org.gradle.kotlin.dsl.create
10+
import org.gradle.kotlin.dsl.get
11+
import software.amazon.awssdk.regions.Region
12+
import software.amazon.awssdk.services.codeartifact.CodeartifactClient
13+
import software.amazon.awssdk.services.codeartifact.model.GetAuthorizationTokenRequest
14+
15+
@Suppress("unused")
16+
class PublishingConventionPlugin : Plugin<Project> {
17+
override fun apply(target: Project) {
18+
with(target) {
19+
with(pluginManager) {
20+
apply("maven-publish")
21+
}
22+
23+
val extension = extensions.create("publishingConfig", PublishingConfigExtension::class.java)
24+
25+
afterEvaluate {
26+
configurePublishing(extension)
27+
}
28+
}
29+
}
30+
31+
private fun Project.configurePublishing(extension: PublishingConfigExtension) {
32+
extensions.configure<PublishingExtension> {
33+
publications {
34+
// Creates a Maven publication called "release".
35+
create<MavenPublication>("release") {
36+
// Applies the component for the release build variant.
37+
from(components["release"])
38+
39+
// You can then customize attributes of the publication as shown below.
40+
groupId = extension.groupId
41+
artifactId = extension.artifactId
42+
}
43+
}
44+
repositories {
45+
// CodeArtifact repository
46+
maven {
47+
name = "CodeArtifact"
48+
url = project.uri(getCodeArtifactRepoUrl(extension))
49+
credentials {
50+
username = "aws"
51+
password = getCodeArtifactAuthToken(extension)
52+
}
53+
}
54+
}
55+
}
56+
}
57+
58+
@Suppress("ktlint:standard:max-line-length")
59+
private fun getCodeArtifactRepoUrl(extension: PublishingConfigExtension): String {
60+
return "https://${extension.domain}-${extension.domainOwner}.d.codeartifact.${extension.region}.amazonaws.com/maven/${extension.repository}/"
61+
}
62+
63+
private fun getCodeArtifactAuthToken(extension: PublishingConfigExtension): String {
64+
val client = CodeartifactClient.builder()
65+
.region(Region.of(extension.region))
66+
.build()
67+
68+
val request = GetAuthorizationTokenRequest.builder()
69+
.domain(extension.domain)
70+
.domainOwner(extension.domainOwner)
71+
.build()
72+
73+
return client.getAuthorizationToken(request).authorizationToken()
74+
}
75+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package plugins
2+
3+
import com.android.build.gradle.AppExtension
4+
import com.android.build.gradle.BaseExtension
5+
import com.android.build.gradle.LibraryExtension
6+
import extensions.VersioningExtension
7+
import org.gradle.api.GradleException
8+
import org.gradle.api.Plugin
9+
import org.gradle.api.Project
10+
import pl.allegro.tech.build.axion.release.ReleasePlugin
11+
import pl.allegro.tech.build.axion.release.domain.VersionConfig
12+
13+
@Suppress("unused")
14+
class VersioningConventionPlugin : Plugin<Project> {
15+
override fun apply(target: Project) {
16+
with(target) {
17+
if (this != rootProject) {
18+
throw GradleException(
19+
"Versioning plugin can be applied to the root project only",
20+
)
21+
}
22+
23+
with(pluginManager) {
24+
apply(ReleasePlugin::class.java)
25+
}
26+
27+
val extension = extensions.create("versioning", VersioningExtension::class.java)
28+
29+
afterEvaluate {
30+
configureVersioning(extension)
31+
}
32+
}
33+
}
34+
35+
private fun Project.configureVersioning(extension: VersioningExtension) {
36+
val scmConfig = extensions.getByType(VersionConfig::class.java).apply {
37+
useHighestVersion.set(extension.useHighestVersion)
38+
versionCreator("versionWithBranch")
39+
tag {
40+
prefix.set(extension.tagPrefix)
41+
versionSeparator.set("")
42+
initialVersion.set({ _, _ -> extension.initialVersion })
43+
}
44+
}
45+
allprojects {
46+
version = scmConfig.version
47+
setupAndroidVersioning(scmConfig)
48+
}
49+
}
50+
51+
private fun Project.setupAndroidVersioning(scmConfig: VersionConfig) {
52+
val configureVersion: BaseExtension.(String) -> Unit = { version ->
53+
val minor = version.split(".")[0].toInt()
54+
val major = version.split(".")[1].toInt()
55+
val patch = version.split(".")[2].toInt()
56+
defaultConfig.versionCode = minor * MINOR_MULTIPLIER + major * MAJOR_MULTIPLIER + patch
57+
defaultConfig.versionName = "$minor.$major.$patch"
58+
}
59+
pluginManager.withPlugin("com.android.library") {
60+
extensions.getByType(LibraryExtension::class.java).apply {
61+
configureVersion(scmConfig.undecoratedVersion)
62+
}
63+
}
64+
pluginManager.withPlugin("com.android.application") {
65+
extensions.getByType(AppExtension::class.java).apply {
66+
configureVersion(scmConfig.undecoratedVersion)
67+
}
68+
}
69+
}
70+
71+
companion object {
72+
private const val MINOR_MULTIPLIER = 1_000_000
73+
private const val MAJOR_MULTIPLIER = 1_000
74+
}
75+
}

build-logic/gradle.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534
2+
org.gradle.parallel=true
3+
org.gradle.caching=true
4+
org.gradle.configureondemand=true

build-logic/settings.gradle.kts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pluginManagement {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
gradlePluginPortal()
6+
}
7+
}
8+
9+
dependencyResolutionManagement {
10+
@Suppress("UnstableApiUsage")
11+
repositories {
12+
google()
13+
mavenCentral()
14+
gradlePluginPortal()
15+
}
16+
}
17+
18+
rootProject.name = "build-logic"
19+
include(":convention")

0 commit comments

Comments
 (0)