diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b9fcfeb..6723798 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -8,6 +8,8 @@ plugins { id("kotlin-android") id("kotlin-kapt") id("com.osacky.fladle") + id("com.github.triplet.play") version "3.8.4" + id("com.wbrawner.releasehelper") } val keystoreProperties = Properties() @@ -46,8 +48,8 @@ android { applicationId = "com.wbrawner.simplemarkdown" minSdk = 23 targetSdk = 33 - versionCode = 39 - versionName = "0.8.15" + versionCode = 41 + versionName = "0.8.16" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunnerArguments["clearPackageData"] = "true" buildConfigField("boolean", "ENABLE_CUSTOM_CSS", "true") @@ -87,6 +89,19 @@ android { execution = "ANDROIDX_TEST_ORCHESTRATOR" } namespace = "com.wbrawner.simplemarkdown" + playConfigs { + register("play") { + enabled.set(true) + commit.set(true) + } + } +} + +play { + commit.set(false) + enabled.set(false) + track.set("production") + defaultToAppBundles.set(true) } dependencies { @@ -124,8 +139,7 @@ dependencies { } android.productFlavors.forEach { flavor -> - if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase() - .contains(flavor.name) + if (gradle.startParameter.taskRequests.toString().lowercase(Locale.getDefault()).contains(flavor.name) && flavor.name == "play" ) { apply(plugin = "com.google.gms.google-services") diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index e8da40c..c96eb4b 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -28,4 +28,14 @@ -keepattributes *Annotation* -keepattributes SourceFile,LineNumberTable -keep public class * extends java.lang.Exception -### Crashlytics ### \ No newline at end of file +### Crashlytics ### + +-dontwarn org.bouncycastle.jsse.BCSSLParameters +-dontwarn org.bouncycastle.jsse.BCSSLSocket +-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider +-dontwarn org.conscrypt.Conscrypt$Version +-dontwarn org.conscrypt.Conscrypt +-dontwarn org.conscrypt.ConscryptHostnameVerifier +-dontwarn org.openjsse.javax.net.ssl.SSLParameters +-dontwarn org.openjsse.javax.net.ssl.SSLSocket +-dontwarn org.openjsse.net.ssl.OpenJSSE \ No newline at end of file diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.kt index 13b8aa8..0f7c1dc 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.kt @@ -46,8 +46,8 @@ class SettingsFragment } } - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { - if (!isAdded) return + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + if (!isAdded || sharedPreferences == null || key == null) return val preference = findPreference(key) as? ListPreference ?: return setListPreferenceSummary(sharedPreferences, preference) if (preference.key != getString(R.string.pref_key_dark_mode)) { @@ -59,7 +59,7 @@ class SettingsFragment AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM } val darkModeValue = sharedPreferences.getString(preference.key, null) - if (darkModeValue != null && darkModeValue.isNotEmpty()) { + if (!darkModeValue.isNullOrEmpty()) { if (darkModeValue.equals(getString(R.string.pref_value_light), ignoreCase = true)) { darkMode = AppCompatDelegate.MODE_NIGHT_NO } else if (darkModeValue.equals(getString(R.string.pref_value_dark), ignoreCase = true)) { diff --git a/app/src/play/play/release-notes/en-US/production.txt b/app/src/play/play/release-notes/en-US/production.txt new file mode 100644 index 0000000..a26efdf --- /dev/null +++ b/app/src/play/play/release-notes/en-US/production.txt @@ -0,0 +1,2 @@ +- Add support for themed icon +- Fix crashes \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index a6f4342..44233df 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,3 @@ -import java.net.URI - buildscript { repositories { gradlePluginPortal() @@ -7,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:7.4.2") + classpath("com.android.tools.build:gradle:8.1.1") classpath("com.google.gms:google-services:4.3.15") classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.4") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20") diff --git a/buildSrc/.gitignore b/buildSrc/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/buildSrc/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..d8b3964 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + `kotlin-dsl` +} + +repositories { + gradlePluginPortal() + google() + mavenCentral() +} + +gradlePlugin { + plugins { + register("release-helper") { + id = "com.wbrawner.releasehelper" + implementationClass = "com.wbrawner.releasehelper.ReleaseHelperPlugin" + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/wbrawner/releasehelper/ReleaseHelperPlugin.kt b/buildSrc/src/main/kotlin/com/wbrawner/releasehelper/ReleaseHelperPlugin.kt new file mode 100644 index 0000000..df2c589 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/wbrawner/releasehelper/ReleaseHelperPlugin.kt @@ -0,0 +1,110 @@ +package com.wbrawner.releasehelper + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Exec +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.provideDelegate +import java.io.ByteArrayOutputStream +import java.io.File + +class ReleaseHelperPlugin : Plugin { + override fun apply(target: Project) { + target.tasks.register("getLatestTag", Exec::class.java) { + val latestTag = ByteArrayOutputStream() + standardOutput = latestTag + commandLine("git describe --tags --abbrev=0".split(" ")) + doLast { + target.project.extra["latestTag"] = latestTag.toString().trim() + logger.info("Latest tag: ${target.project.extra["latestTag"]}") + } + } + + target.tasks.register("changelog") { + val changelogFile = File(target.projectDir, "src/main/play/release-notes/en-US/default.txt") + inputs.property("tag", target.provider { + target.project.extra["latestTag"] + }) + outputs.file(changelogFile) + dependsOn("getLatestTag") + doLast { + val latestTag: String by target.project.extra + val changelog = ByteArrayOutputStream() + target.exec { + standardOutput = changelog + commandLine = "git log --format=\"%B\" ${latestTag.trim()}..".split(" ") + } + changelogFile.writeText( + changelog.toString() + .split("\n") + .mapNotNull { it.trim('"').ifBlank { null } } + .joinToString("\n") { "- $it" } + ) + } + } + + target.tasks.register("majorRelease") { + dependsOn("changelog", "getLatestTag") + doLast { + val latestTag: String by target.project.extra + val newVersion = latestTag.incrementVersion(VersionPart.MAJOR) + target.updateVersionName(latestTag, newVersion) + target.exec { + commandLine = "git tag $newVersion".split(" ") + } + } + } + + target.tasks.register("minorRelease") { + dependsOn("changelog", "getLatestTag") + doLast { + val latestTag: String by target.project.extra + val newVersion = latestTag.incrementVersion(VersionPart.MAJOR) + target.updateVersionName(latestTag, newVersion) + target.exec { + commandLine = "git tag $newVersion".split(" ") + } + } + } + + target.tasks.register("patchRelease") { + dependsOn("changelog", "getLatestTag") + doLast { + val latestTag: String by target.project.extra + val newVersion = latestTag.incrementVersion(VersionPart.MAJOR) + target.updateVersionName(latestTag, newVersion) + target.exec { + commandLine = "git tag $newVersion".split(" ") + } + } + } + } +} + +private enum class VersionPart { + MAJOR, + MINOR, + PATCH +} + +private fun String.incrementVersion(part: VersionPart) = split(".") + .mapIndexed { index, numberString -> + val number = numberString.toInt() + return@mapIndexed if (index == part.ordinal) { + number + 1 + } else if (index > part.ordinal) { + 0 + } else { + number + } + } + .joinToString(".") + +private fun Project.updateVersionName(oldVersionName: String, newVersionName: String) { + File(projectDir, "app/build.gradle.kts").apply { + writeText( + readText().replace("versionName = \"$oldVersionName\"", "versionName = \"$newVersionName\"") + ) + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 9e6fce1..f6720ae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,10 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.defaults.buildfeatures.buildconfig=true android.enableJetifier=true +android.nonFinalResIds=false +android.nonTransitiveRClass=false android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 38db55e..628afa5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip