Implement semi-automated releases
This still requires manually running the gradle task but the next step will be getting a GitHub workflow to perform the release whenever a new tag is pushed
This commit is contained in:
parent
f51d669da3
commit
f69bf81630
10 changed files with 168 additions and 12 deletions
|
@ -8,6 +8,8 @@ plugins {
|
||||||
id("kotlin-android")
|
id("kotlin-android")
|
||||||
id("kotlin-kapt")
|
id("kotlin-kapt")
|
||||||
id("com.osacky.fladle")
|
id("com.osacky.fladle")
|
||||||
|
id("com.github.triplet.play") version "3.8.4"
|
||||||
|
id("com.wbrawner.releasehelper")
|
||||||
}
|
}
|
||||||
|
|
||||||
val keystoreProperties = Properties()
|
val keystoreProperties = Properties()
|
||||||
|
@ -46,8 +48,8 @@ android {
|
||||||
applicationId = "com.wbrawner.simplemarkdown"
|
applicationId = "com.wbrawner.simplemarkdown"
|
||||||
minSdk = 23
|
minSdk = 23
|
||||||
targetSdk = 33
|
targetSdk = 33
|
||||||
versionCode = 39
|
versionCode = 41
|
||||||
versionName = "0.8.15"
|
versionName = "0.8.16"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
testInstrumentationRunnerArguments["clearPackageData"] = "true"
|
testInstrumentationRunnerArguments["clearPackageData"] = "true"
|
||||||
buildConfigField("boolean", "ENABLE_CUSTOM_CSS", "true")
|
buildConfigField("boolean", "ENABLE_CUSTOM_CSS", "true")
|
||||||
|
@ -87,6 +89,19 @@ android {
|
||||||
execution = "ANDROIDX_TEST_ORCHESTRATOR"
|
execution = "ANDROIDX_TEST_ORCHESTRATOR"
|
||||||
}
|
}
|
||||||
namespace = "com.wbrawner.simplemarkdown"
|
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 {
|
dependencies {
|
||||||
|
@ -124,8 +139,7 @@ dependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
android.productFlavors.forEach { flavor ->
|
android.productFlavors.forEach { flavor ->
|
||||||
if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
|
if (gradle.startParameter.taskRequests.toString().lowercase(Locale.getDefault()).contains(flavor.name)
|
||||||
.contains(flavor.name)
|
|
||||||
&& flavor.name == "play"
|
&& flavor.name == "play"
|
||||||
) {
|
) {
|
||||||
apply(plugin = "com.google.gms.google-services")
|
apply(plugin = "com.google.gms.google-services")
|
||||||
|
|
10
app/proguard-rules.pro
vendored
10
app/proguard-rules.pro
vendored
|
@ -29,3 +29,13 @@
|
||||||
-keepattributes SourceFile,LineNumberTable
|
-keepattributes SourceFile,LineNumberTable
|
||||||
-keep public class * extends java.lang.Exception
|
-keep public class * extends java.lang.Exception
|
||||||
### Crashlytics ###
|
### 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
|
|
@ -46,8 +46,8 @@ class SettingsFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||||
if (!isAdded) return
|
if (!isAdded || sharedPreferences == null || key == null) return
|
||||||
val preference = findPreference(key) as? ListPreference ?: return
|
val preference = findPreference(key) as? ListPreference ?: return
|
||||||
setListPreferenceSummary(sharedPreferences, preference)
|
setListPreferenceSummary(sharedPreferences, preference)
|
||||||
if (preference.key != getString(R.string.pref_key_dark_mode)) {
|
if (preference.key != getString(R.string.pref_key_dark_mode)) {
|
||||||
|
@ -59,7 +59,7 @@ class SettingsFragment
|
||||||
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||||
}
|
}
|
||||||
val darkModeValue = sharedPreferences.getString(preference.key, null)
|
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)) {
|
if (darkModeValue.equals(getString(R.string.pref_value_light), ignoreCase = true)) {
|
||||||
darkMode = AppCompatDelegate.MODE_NIGHT_NO
|
darkMode = AppCompatDelegate.MODE_NIGHT_NO
|
||||||
} else if (darkModeValue.equals(getString(R.string.pref_value_dark), ignoreCase = true)) {
|
} else if (darkModeValue.equals(getString(R.string.pref_value_dark), ignoreCase = true)) {
|
||||||
|
|
2
app/src/play/play/release-notes/en-US/production.txt
Normal file
2
app/src/play/play/release-notes/en-US/production.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
- Add support for themed icon
|
||||||
|
- Fix crashes
|
|
@ -1,5 +1,3 @@
|
||||||
import java.net.URI
|
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
|
@ -7,7 +5,7 @@ buildscript {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
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.gms:google-services:4.3.15")
|
||||||
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.4")
|
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.4")
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20")
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20")
|
||||||
|
|
1
buildSrc/.gitignore
vendored
Normal file
1
buildSrc/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
build/
|
18
buildSrc/build.gradle.kts
Normal file
18
buildSrc/build.gradle.kts
Normal file
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<Project> {
|
||||||
|
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\"")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,10 @@
|
||||||
|
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
android.defaults.buildfeatures.buildconfig=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
android.nonFinalResIds=false
|
||||||
|
android.nonTransitiveRClass=false
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
|
||||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
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
|
||||||
|
|
Loading…
Reference in a new issue