Skip to content

Commit 010c032

Browse files
committed
chore: adding missing files from kmp-project-template
1 parent e49f208 commit 010c032

56 files changed

Lines changed: 6299 additions & 5 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Cleanup Cache
2+
3+
on:
4+
pull_request:
5+
types: [ closed ]
6+
workflow_dispatch:
7+
8+
jobs:
9+
cleanup:
10+
uses: openMF/mifos-x-actionhub/.github/workflows/cache-cleanup.yaml@v1.0.2
11+
with:
12+
cleanup_pr: ${{ github.event_name == 'pull_request' && github.event.repository.private == true }}
13+
cleanup_all: ${{ github.event_name == 'workflow_dispatch' }}
14+
secrets:
15+
token: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
import org.gradle.api.Plugin
3+
import org.gradle.api.Project
4+
import org.convention.configureDetekt
5+
import org.convention.detektGradle
6+
7+
/**
8+
* Plugin that applies the Detekt plugin and configures it.
9+
*/
10+
class DetektConventionPlugin : Plugin<Project> {
11+
override fun apply(target: Project) {
12+
with(target) {
13+
applyPlugins()
14+
15+
detektGradle {
16+
configureDetekt(this)
17+
}
18+
}
19+
}
20+
21+
private fun Project.applyPlugins() {
22+
pluginManager.apply {
23+
apply("io.gitlab.arturbosch.detekt")
24+
}
25+
}
26+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
import org.gradle.api.Plugin
3+
import org.gradle.api.Project
4+
import org.gradle.api.tasks.Copy
5+
import org.gradle.api.tasks.Exec
6+
import org.gradle.kotlin.dsl.register
7+
import java.util.Locale
8+
9+
/**
10+
* Plugin that installs the pre-commit git hooks from the scripts directory.
11+
*/
12+
class GitHooksConventionPlugin : Plugin<Project> {
13+
override fun apply(project: Project) {
14+
// Define a function to check if the OS is Linux or MacOS
15+
fun isLinuxOrMacOs(): Boolean {
16+
val osName = System.getProperty("os.name").lowercase(Locale.getDefault())
17+
return osName.contains("linux") || osName.contains("mac os") || osName.contains("macos")
18+
}
19+
20+
// Define the copyGitHooks task
21+
project.tasks.register<Copy>("copyGitHooks") {
22+
description = "Copies the git hooks from /scripts to the .git/hooks folder."
23+
from("${project.rootDir}/scripts/") {
24+
include("**/*.sh")
25+
rename { it.removeSuffix(".sh") }
26+
}
27+
into("${project.rootDir}/.git/hooks")
28+
}
29+
30+
// Define the installGitHooks task
31+
project.tasks.register<Exec>("installGitHooks") {
32+
description = "Installs the pre-commit git hooks from the scripts directory."
33+
group = "git hooks"
34+
workingDir = project.rootDir
35+
36+
if (isLinuxOrMacOs()) {
37+
commandLine("chmod", "-R", "+x", ".git/hooks/")
38+
}else {
39+
commandLine("cmd", "/c", "attrib", "-R", "+X", ".git/hooks/*.*")
40+
}
41+
dependsOn(project.tasks.named("copyGitHooks"))
42+
43+
doLast {
44+
println("Git hooks installed successfully.")
45+
}
46+
}
47+
48+
// Configure task dependencies after evaluation
49+
project.afterEvaluate {
50+
project.tasks.matching {
51+
it.name in listOf("preBuild", "build", "assembleDebug", "assembleRelease", "installDebug", "installRelease", "clean")
52+
}.configureEach {
53+
dependsOn(project.tasks.named("installGitHooks"))
54+
}
55+
}
56+
}
57+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import androidx.room.gradle.RoomExtension
2+
import com.google.devtools.ksp.gradle.KspExtension
3+
import org.convention.libs
4+
import org.gradle.api.Plugin
5+
import org.gradle.api.Project
6+
import org.gradle.kotlin.dsl.configure
7+
import org.gradle.kotlin.dsl.dependencies
8+
9+
class KMPRoomConventionPlugin : Plugin<Project> {
10+
override fun apply(target: Project) {
11+
with(target) {
12+
pluginManager.apply("androidx.room")
13+
pluginManager.apply("com.google.devtools.ksp")
14+
15+
extensions.configure<KspExtension> {
16+
arg("room.generateKotlin", "true")
17+
}
18+
19+
extensions.configure<RoomExtension> {
20+
// The schemas directory contains a schema file for each version of the Room database.
21+
// This is required to enable Room auto migrations.
22+
// See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration.
23+
schemaDirectory("$projectDir/schemas")
24+
}
25+
26+
dependencies {
27+
// Adding ksp dependencies for multiple platforms
28+
"implementation"(libs.findLibrary("androidx.room.ktx").get())
29+
listOf(
30+
"kspDesktop",
31+
"kspAndroid",
32+
"kspIosArm64",
33+
"kspIosX64",
34+
"kspIosSimulatorArm64",
35+
// Add any other platform you may support
36+
).forEach { platform ->
37+
add(platform, libs.findLibrary("androidx.room.compiler").get())
38+
// Kotlin Extensions and Coroutines support for Room
39+
// add(platform, libs.findLibrary("androidx.room.ktx").get())
40+
}
41+
}
42+
}
43+
}
44+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import org.convention.keystore.ConfigurationFileUpdatesTask
2+
import org.convention.keystore.KeystoreConfig
3+
import org.convention.keystore.KeystoreGenerationTask
4+
import org.convention.keystore.SecretsConfig
5+
import org.convention.keystore.SecretsEnvUpdateTask
6+
import org.gradle.api.Plugin
7+
import org.gradle.api.Project
8+
9+
/**
10+
* Convention plugin for keystore management following your existing patterns
11+
*/
12+
class KeystoreManagementConventionPlugin : Plugin<Project> {
13+
14+
override fun apply(target: Project) {
15+
with(target) {
16+
// Create extension for configuration
17+
val keystoreExtension = extensions.create("keystoreManagement", KeystoreManagementExtension::class.java)
18+
19+
// Set default configurations
20+
keystoreExtension.keystoreConfig.convention(KeystoreConfig())
21+
keystoreExtension.secretsConfig.convention(SecretsConfig())
22+
23+
// Register the keystore generation task
24+
val generateKeystoresTask = tasks.register("generateKeystores", KeystoreGenerationTask::class.java) {
25+
// Configure task with extension values
26+
keystoreConfig.set(keystoreExtension.keystoreConfig)
27+
secretsConfig.set(keystoreExtension.secretsConfig)
28+
29+
// Load configuration from secrets.env if it exists
30+
KeystoreGenerationTask.createWithSecretsConfig(this, keystoreExtension.secretsConfig.get())
31+
}
32+
33+
// Register configuration file updates task
34+
val updateConfigFilesTask = tasks.register("updateConfigurationFiles", ConfigurationFileUpdatesTask::class.java) {
35+
// Load configuration from secrets.env if it exists
36+
ConfigurationFileUpdatesTask.createWithSecretsConfig(this, keystoreExtension.secretsConfig.get())
37+
}
38+
39+
// Register secrets.env update task (KMPPT-57)
40+
val updateSecretsEnvTask = tasks.register("updateSecretsEnv", SecretsEnvUpdateTask::class.java) {
41+
// Configure to use keystores from generation task
42+
SecretsEnvUpdateTask.createFromKeystoreGeneration(this, generateKeystoresTask.get(), keystoreExtension.secretsConfig.get())
43+
}
44+
45+
// Register combined task that generates keystores and updates config files
46+
tasks.register("generateKeystoresAndUpdateConfigs", KeystoreGenerationTask::class.java) {
47+
keystoreConfig.set(keystoreExtension.keystoreConfig)
48+
secretsConfig.set(keystoreExtension.secretsConfig)
49+
50+
KeystoreGenerationTask.createWithSecretsConfig(this, keystoreExtension.secretsConfig.get())
51+
52+
// Configure the update tasks to run after this task
53+
finalizedBy(updateConfigFilesTask)
54+
finalizedBy(updateSecretsEnvTask)
55+
}
56+
57+
// Configure the update task to use generated keystores
58+
updateConfigFilesTask.configure {
59+
// Set dependency on keystore generation
60+
dependsOn(generateKeystoresTask)
61+
62+
// Configure to use upload keystore from generation task
63+
ConfigurationFileUpdatesTask.createForUploadKeystore(this, generateKeystoresTask.get())
64+
}
65+
66+
// Register convenience tasks for individual keystore types
67+
tasks.register("generateOriginalKeystore", KeystoreGenerationTask::class.java) {
68+
keystoreConfig.set(keystoreExtension.keystoreConfig)
69+
secretsConfig.set(keystoreExtension.secretsConfig)
70+
generateOriginal.set(true)
71+
generateUpload.set(false)
72+
73+
KeystoreGenerationTask.createWithSecretsConfig(this, keystoreExtension.secretsConfig.get())
74+
}
75+
76+
tasks.register("generateUploadKeystore", KeystoreGenerationTask::class.java) {
77+
keystoreConfig.set(keystoreExtension.keystoreConfig)
78+
secretsConfig.set(keystoreExtension.secretsConfig)
79+
generateOriginal.set(false)
80+
generateUpload.set(true)
81+
82+
KeystoreGenerationTask.createWithSecretsConfig(this, keystoreExtension.secretsConfig.get())
83+
}
84+
85+
// Add task group description
86+
tasks.register("keystoreHelp") {
87+
group = "keystore"
88+
description = "Shows available keystore management commands"
89+
doLast {
90+
logger.lifecycle("""
91+
|Keystore Management Plugin - Available Tasks:
92+
|
93+
|Generation Tasks:
94+
| - generateKeystores: Generate both ORIGINAL and UPLOAD keystores
95+
| - generateOriginalKeystore: Generate only the ORIGINAL (debug) keystore
96+
| - generateUploadKeystore: Generate only the UPLOAD (release) keystore
97+
| - generateKeystoresAndUpdateConfigs: Generate keystores and update config files
98+
|
99+
|Configuration Update Tasks:
100+
| - updateConfigurationFiles: Update fastlane and gradle config files with keystore info
101+
| - updateSecretsEnv: Update secrets.env with base64-encoded keystores (KMPPT-57)
102+
|
103+
|Help Tasks:
104+
| - keystoreHelp: Shows this help message
105+
|
106+
|Configuration:
107+
| The plugin automatically loads configuration from 'secrets.env' if it exists.
108+
| You can also configure manually in build.gradle.kts:
109+
|
110+
| keystoreManagement {
111+
| keystoreConfig {
112+
| companyName = "Your Company Name"
113+
| department = "Your Department"
114+
| organization = "Your Organization"
115+
| city = "Your City"
116+
| state = "Your State"
117+
| country = "US"
118+
| keyAlgorithm = "RSA"
119+
| keySize = 2048
120+
| validity = 25
121+
| overwriteExisting = false
122+
| }
123+
| secretsConfig {
124+
| secretsEnvFile = file("secrets.env")
125+
| preserveComments = true
126+
| createBackup = true
127+
| }
128+
| }
129+
|
130+
|Usage Examples:
131+
| ./gradlew generateKeystores # Generate both keystores
132+
| ./gradlew generateOriginalKeystore # Generate debug keystore only
133+
| ./gradlew generateUploadKeystore # Generate release keystore only
134+
| ./gradlew generateKeystoresAndUpdateConfigs # Generate keystores and update configs
135+
| ./gradlew updateConfigurationFiles # Update config files only
136+
| ./gradlew updateSecretsEnv # Update secrets.env with base64 keystores
137+
|
138+
|Note: This task replicates the functionality of keystore-manager.sh
139+
| with better cross-platform compatibility and Gradle integration.
140+
""".trimMargin())
141+
}
142+
}
143+
}
144+
}
145+
}
146+
147+
/**
148+
* Extension class for keystore management configuration
149+
*/
150+
abstract class KeystoreManagementExtension {
151+
abstract val keystoreConfig: org.gradle.api.provider.Property<KeystoreConfig>
152+
abstract val secretsConfig: org.gradle.api.provider.Property<SecretsConfig>
153+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import org.gradle.api.Plugin
2+
import org.gradle.api.Project
3+
4+
/**
5+
* Plugin that applies the Ktlint plugin and configures it.
6+
*/
7+
class KtlintConventionPlugin : Plugin<Project> {
8+
override fun apply(target: Project) {
9+
with(target) {
10+
applyPlugins()
11+
}
12+
}
13+
14+
private fun Project.applyPlugins() {
15+
pluginManager.apply {
16+
apply("org.jlleitschuh.gradle.ktlint")
17+
}
18+
}
19+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import org.convention.configureSpotless
2+
import org.convention.spotlessGradle
3+
import org.gradle.api.Plugin
4+
import org.gradle.api.Project
5+
6+
/**
7+
* Plugin that applies the Spotless plugin and configures it.
8+
*/
9+
class SpotlessConventionPlugin : Plugin<Project> {
10+
override fun apply(target: Project) {
11+
with(target) {
12+
applyPlugins()
13+
14+
spotlessGradle {
15+
configureSpotless(this)
16+
}
17+
}
18+
}
19+
20+
private fun Project.applyPlugins() {
21+
pluginManager.apply {
22+
apply("com.diffplug.spotless")
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)