mirror of
https://github.com/mihonapp/mihon.git
synced 2026-10-16 13:48:09 -07:00
Enable Gradle configuration cache
This commit is contained in:
@@ -41,6 +41,8 @@ jobs:
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
|
||||
- name: Check code format
|
||||
run: ./gradlew spotlessCheck
|
||||
|
||||
@@ -42,11 +42,18 @@ jobs:
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
|
||||
- name: Decode signing keystore
|
||||
run: echo "$SIGNING_KEY" | base64 -d > "${{ runner.temp }}/antsy.keystore"
|
||||
env:
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew assembleRelease -Pinclude-telemetry -Penable-updater
|
||||
env:
|
||||
storeFileBase64: ${{ secrets.SIGNING_KEY }}
|
||||
storeFile: ${{ runner.temp }}/antsy.keystore
|
||||
storePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
keyAlias: ${{ secrets.ALIAS }}
|
||||
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
||||
@@ -93,10 +100,15 @@ jobs:
|
||||
with:
|
||||
cache-disabled: true
|
||||
|
||||
- name: Decode signing keystore
|
||||
run: echo "$SIGNING_KEY" | base64 -d > "${{ runner.temp }}/antsy.keystore"
|
||||
env:
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew assembleFoss -Penable-updater
|
||||
env:
|
||||
storeFileBase64: ${{ secrets.SIGNING_KEY }}
|
||||
storeFile: ${{ runner.temp }}/antsy.keystore
|
||||
storePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
keyAlias: ${{ secrets.ALIAS }}
|
||||
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
||||
|
||||
+30
-18
@@ -1,11 +1,13 @@
|
||||
import com.android.build.api.variant.ApplicationVariant
|
||||
import com.android.build.api.variant.BuildConfigField
|
||||
import mihon.gradle.Config
|
||||
import mihon.gradle.getBuildTime
|
||||
import mihon.gradle.getCurrentTime
|
||||
import mihon.gradle.getLatestCommitCount
|
||||
import mihon.gradle.getLatestCommitSha
|
||||
import mihon.gradle.getLatestCommitTime
|
||||
import mihon.gradle.tasks.ReplaceShortcutsPlaceholderTask
|
||||
import java.io.FileInputStream
|
||||
import java.util.Properties
|
||||
import kotlin.io.encoding.Base64
|
||||
|
||||
plugins {
|
||||
alias(mihonx.plugins.android.application)
|
||||
@@ -36,9 +38,6 @@ android {
|
||||
versionCode = 30
|
||||
versionName = "0.20.4"
|
||||
|
||||
buildConfigField("String", "COMMIT_COUNT", "\"${getLatestCommitCount()}\"")
|
||||
buildConfigField("String", "COMMIT_SHA", "\"${getLatestCommitSha()}\"")
|
||||
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime(useLatestCommitTime = false)}\"")
|
||||
buildConfigField("boolean", "TELEMETRY_INCLUDED", "${Config.includeTelemetry}")
|
||||
buildConfigField("boolean", "UPDATER_ENABLED", "${Config.enableUpdater}")
|
||||
|
||||
@@ -46,14 +45,9 @@ android {
|
||||
}
|
||||
|
||||
if (System.getenv("MIHON_GITHUB_RELEASE").toBoolean()) {
|
||||
val tempStoreFile = file(System.getenv("RUNNER_TEMP")).resolve("antsy.keystore")
|
||||
|
||||
val storeFileBytes = System.getenv("storeFileBase64").let(Base64::decode)
|
||||
tempStoreFile.outputStream().use { it.write(storeFileBytes) }
|
||||
|
||||
signingConfigs {
|
||||
named("debug") {
|
||||
storeFile = tempStoreFile
|
||||
storeFile = file(System.getenv("storeFile"))
|
||||
storePassword = System.getenv("storePassword")
|
||||
keyAlias = System.getenv("keyAlias")
|
||||
keyPassword = System.getenv("keyPassword")
|
||||
@@ -75,7 +69,6 @@ android {
|
||||
buildTypes {
|
||||
val debug = getByName("debug") {
|
||||
applicationIdSuffix = ".dev"
|
||||
versionNameSuffix = "-${getLatestCommitCount()}"
|
||||
isPseudoLocalesEnabled = true
|
||||
}
|
||||
val release = getByName("release") {
|
||||
@@ -87,8 +80,6 @@ android {
|
||||
isProfileable = true
|
||||
|
||||
proguardFiles("proguard-android-optimize.txt", "proguard-rules.pro")
|
||||
|
||||
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime(useLatestCommitTime = true)}\"")
|
||||
}
|
||||
|
||||
val commonMatchingFallbacks = listOf(release.name)
|
||||
@@ -105,11 +96,7 @@ android {
|
||||
|
||||
applicationIdSuffix = ".debug"
|
||||
|
||||
versionNameSuffix = debug.versionNameSuffix
|
||||
|
||||
matchingFallbacks.addAll(commonMatchingFallbacks)
|
||||
|
||||
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime(useLatestCommitTime = false)}\"")
|
||||
}
|
||||
create("benchmark") {
|
||||
initWith(release)
|
||||
@@ -337,7 +324,32 @@ dependencies {
|
||||
testImplementation(libs.kotlinx.coroutines.test)
|
||||
}
|
||||
|
||||
val latestCommitCount = getLatestCommitCount()
|
||||
val latestCommitSha = getLatestCommitSha()
|
||||
val latestCommitTime = getLatestCommitTime()
|
||||
val currentTime = getCurrentTime()
|
||||
|
||||
fun ApplicationVariant.buildConfigField(type: String, name: String, value: Provider<String>) {
|
||||
buildConfigFields?.put(name, value.map { BuildConfigField(type, it, null) })
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
onVariants { variant ->
|
||||
val isUnstableBuild = variant.buildType == "debug" || variant.buildType == "nightly"
|
||||
val buildTime = if (isUnstableBuild) currentTime else latestCommitTime
|
||||
|
||||
variant.buildConfigField("String", "COMMIT_COUNT", latestCommitCount.map { "\"$it\"" })
|
||||
variant.buildConfigField("String", "COMMIT_SHA", latestCommitSha.map { "\"$it\"" })
|
||||
variant.buildConfigField("String", "BUILD_TIME", buildTime.map { "\"$it\"" })
|
||||
|
||||
if (isUnstableBuild) {
|
||||
variant.outputs.forEach { output ->
|
||||
val versionName = output.versionName.get()
|
||||
output.versionName.set(latestCommitCount.map { "$versionName-$it" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onVariants { variant ->
|
||||
val resSource = variant.sources.res ?: return@onVariants
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ kotlin.code.style=official
|
||||
|
||||
# Configuration should be synced with [/gradle/build-logic/gradle.properties]
|
||||
org.gradle.caching=true
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Gradle properties are not passed to included builds
|
||||
# https://github.com/gradle/gradle/issues/2534
|
||||
org.gradle.caching=true
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package mihon.gradle
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.ValueSource
|
||||
import org.gradle.api.provider.ValueSourceParameters
|
||||
import org.gradle.process.ExecOperations
|
||||
import java.io.ByteArrayOutputStream
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Duration.Companion.nanoseconds
|
||||
import kotlin.time.Instant
|
||||
|
||||
private val logger = Logging.getLogger("mihon.gradle.BuildInfo")
|
||||
|
||||
fun Project.getLatestCommitCount(): Provider<String> {
|
||||
return git("rev-list", "--count", "HEAD", default = provider { "0" }).map { it.first }
|
||||
}
|
||||
|
||||
fun Project.getLatestCommitSha(): Provider<String> {
|
||||
return git("rev-parse", "--short", "HEAD", default = provider { "unknown" }).map { it.first }
|
||||
}
|
||||
|
||||
fun Project.getLatestCommitTime(): Provider<String> {
|
||||
return git("log", "-1", "--format=%ct", default = getCurrentTime()).map { (value, isDefault) ->
|
||||
if (isDefault) value else Instant.fromEpochSeconds(value.toLong()).toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.getCurrentTime(): Provider<String> {
|
||||
return providers.of(CurrentTimeValueSource::class.java) {}
|
||||
}
|
||||
|
||||
private fun Project.git(vararg command: String, default: Provider<String>): Provider<Pair<String, Boolean>> {
|
||||
val workTree = rootProject.layout.projectDirectory
|
||||
return providers.of(GitValueSource::class.java) {
|
||||
parameters.command.set(listOf("git", *command))
|
||||
parameters.workTree.set(workTree)
|
||||
parameters.default.set(default)
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class GitValueSource : ValueSource<Pair<String, Boolean>, GitValueSource.Parameters> {
|
||||
|
||||
interface Parameters : ValueSourceParameters {
|
||||
val command: ListProperty<String>
|
||||
val workTree: DirectoryProperty
|
||||
val default: Property<String>
|
||||
}
|
||||
|
||||
@get:Inject
|
||||
abstract val execOperations: ExecOperations
|
||||
|
||||
override fun obtain(): Pair<String, Boolean> {
|
||||
val command = parameters.command.get()
|
||||
val output = ByteArrayOutputStream()
|
||||
val error = ByteArrayOutputStream()
|
||||
|
||||
val reason = try {
|
||||
val result = execOperations.exec {
|
||||
commandLine = command
|
||||
workingDir = parameters.workTree.get().asFile
|
||||
standardOutput = output
|
||||
errorOutput = error
|
||||
isIgnoreExitValue = true
|
||||
}
|
||||
if (result.exitValue == 0) return output.toString().trim() to false
|
||||
error.toString().trim().ifEmpty { "exited with code ${result.exitValue}" }
|
||||
} catch (e: Exception) {
|
||||
e.message?.trim().orEmpty().ifEmpty { e.toString() }
|
||||
}
|
||||
|
||||
val default = parameters.default.get()
|
||||
logger.warn("`${command.joinToString(" ")}` failed, defaulting to \"$default\": $reason")
|
||||
return default to true
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class CurrentTimeValueSource : ValueSource<String, ValueSourceParameters.None> {
|
||||
|
||||
override fun obtain(): String {
|
||||
val now = Clock.System.now()
|
||||
return (now - now.nanosecondsOfSecond.nanoseconds).toString()
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package mihon.gradle
|
||||
|
||||
import org.gradle.api.Project
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Duration.Companion.nanoseconds
|
||||
import kotlin.time.Instant
|
||||
|
||||
// Git is needed in your system PATH for these commands to work.
|
||||
// If it's not installed, you can return a random value as a workaround
|
||||
fun Project.getLatestCommitCount(): String {
|
||||
return exec("git rev-list --count HEAD")
|
||||
// return "1"
|
||||
}
|
||||
|
||||
fun Project.getLatestCommitSha(): String {
|
||||
return exec("git rev-parse --short HEAD")
|
||||
// return "1"
|
||||
}
|
||||
|
||||
/**
|
||||
* @param useLatestCommitTime If `true`, the build time is based on the timestamp of the last Git commit;
|
||||
* otherwise, the current time is used. Both are in UTC.
|
||||
* @return An ISO 8601 formatted string representing the build time.
|
||||
*/
|
||||
fun Project.getBuildTime(useLatestCommitTime: Boolean): String {
|
||||
return if (useLatestCommitTime) {
|
||||
val epoch = exec("git log -1 --format=%ct").toLong()
|
||||
Instant.fromEpochSeconds(epoch).toString()
|
||||
} else {
|
||||
val now = Clock.System.now()
|
||||
(now - now.nanosecondsOfSecond.nanoseconds).toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.exec(command: String): String {
|
||||
return providers.exec {
|
||||
commandLine = command.split(" ")
|
||||
}
|
||||
.standardOutput
|
||||
.asText
|
||||
.get()
|
||||
.trim()
|
||||
}
|
||||
Reference in New Issue
Block a user