diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ab976be384..a29ed3a572 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,7 +16,9 @@ * along with Proton Mail. If not, see . */ +import java.io.ByteArrayOutputStream import java.util.Properties +import ch.protonmail.android.mail.plugin.GenerateGitHashTask import com.android.build.api.dsl.VariantDimension import configuration.extensions.protonEnvironment import org.gradle.kotlin.dsl.get @@ -49,6 +51,33 @@ val accountSentryDSN: String = privateProperties.getProperty("accountSentryDSN") val sentryDSN: String = privateProperties.getProperty("sentryDSN") ?: "" val proxyToken: String? = privateProperties.getProperty("PROXY_TOKEN") +val gitHashFile = File(project.layout.buildDirectory.asFile.get(), "git/git-hash.txt") + +val getGitHashTask = tasks.register("getGitHash") { + headRefFile.set(File(project.rootDir, ".git/HEAD")) + refsDirectory.set(File(project.rootDir, ".git/refs")) + outputFile.set(gitHashFile) +} + +fun gitHashProvider(): Provider { + return provider { + // This will only be evaluated during execution phase, not configuration + if (gitHashFile.exists()) gitHashFile.readText().trim() else "unknown" + } +} + +afterEvaluate { + // Only needed for dev/alpha flavors, we don't use the hash in prod. + listOf("dev", "alpha").forEach { flavorName -> + val capitalizedName = flavorName.capitalize() + tasks.matching { + it.name.startsWith("process${capitalizedName}") + }.configureEach { + dependsOn(getGitHashTask) + } + } +} + android { namespace = "ch.protonmail.android" compileSdk = AppConfiguration.compileSdk.get() @@ -150,10 +179,9 @@ android { flavorDimensions.add("default") productFlavors { - val gitHash = "git rev-parse --short HEAD".runCommand(workingDir = rootDir) create("dev") { applicationIdSuffix = ".dev" - versionNameSuffix = "-dev+$gitHash" + versionNameSuffix = "-dev+${gitHashProvider().get()}" buildConfigField("Boolean", "USE_DEFAULT_PINS", "false") val protonHost = "proton.black" @@ -165,7 +193,7 @@ android { } create("alpha") { applicationIdSuffix = ".alpha" - versionNameSuffix = "-alpha+$gitHash" + versionNameSuffix = "-alpha+${gitHashProvider().get()}" buildConfigField("Boolean", "USE_DEFAULT_PINS", "true") } create("prod") { diff --git a/build-plugin/src/main/kotlin/ch/protonmail/android/mail/plugin/GenerateGitHashTask.kt b/build-plugin/src/main/kotlin/ch/protonmail/android/mail/plugin/GenerateGitHashTask.kt new file mode 100644 index 0000000000..0cb1fcff3c --- /dev/null +++ b/build-plugin/src/main/kotlin/ch/protonmail/android/mail/plugin/GenerateGitHashTask.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton Technologies AG and Proton Mail. + * + * Proton Mail is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Proton Mail is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Proton Mail. If not, see . + */ + +package ch.protonmail.android.mail.plugin + +import java.io.ByteArrayOutputStream +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import javax.inject.Inject + +abstract class GenerateGitHashTask : DefaultTask() { + + @get:InputFile + abstract val headRefFile: RegularFileProperty + + @get:InputDirectory + abstract val refsDirectory: DirectoryProperty + + @get:OutputFile + abstract val outputFile: RegularFileProperty + + @get:Inject + abstract val execOperations: ExecOperations + + @TaskAction + fun execute() { + outputFile.get().asFile.parentFile?.mkdirs() + + val stdout = ByteArrayOutputStream() + + execOperations.exec { + commandLine("git", "rev-parse", "--short", "HEAD") + standardOutput = stdout + } + + val gitHash = stdout.toString().trim() + outputFile.get().asFile.writeText(gitHash) + logger.info("Current git hash: $gitHash") + } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts deleted file mode 100644 index 1ea6fd03e8..0000000000 --- a/buildSrc/build.gradle.kts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2022 Proton Technologies AG - * This file is part of Proton Technologies AG and Proton Mail. - * - * Proton Mail is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Proton Mail is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Proton Mail. If not, see . - */ - -plugins { - `kotlin-dsl` -} - -repositories { - maven("https://plugins.gradle.org/m2/") -} diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts deleted file mode 100644 index 2095b818fb..0000000000 --- a/buildSrc/settings.gradle.kts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2022 Proton Technologies AG - * This file is part of Proton Technologies AG and Proton Mail. - * - * Proton Mail is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Proton Mail is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Proton Mail. If not, see . - */ - -buildCache { - if (System.getenv("CI") != "true") { - local { - removeUnusedEntriesAfterDays = 5 - } - } - - val remoteCacheUrl = providers.environmentVariable("GRADLE_REMOTE_CACHE_URL").orNull - ?: providers.gradleProperty("remoteCacheUrl").orNull - ?: "" - - if (remoteCacheUrl.isNotEmpty()) { - remote { - url = uri(remoteCacheUrl) - isPush = providers.environmentVariable("CI_PIPELINE_SOURCE").orNull == "push" - credentials { - username = providers.environmentVariable("GRADLE_REMOTE_CACHE_USERNAME").orNull - ?: providers.gradleProperty("remoteCacheUsername").orNull - ?: "" - password = providers.environmentVariable("GRADLE_REMOTE_CACHE_PASSWORD").orNull - ?: providers.gradleProperty("remoteCachePassword").orNull - ?: "" - } - } - } -} diff --git a/buildSrc/src/main/kotlin/Helpers.kt b/buildSrc/src/main/kotlin/Helpers.kt deleted file mode 100644 index a93a718504..0000000000 --- a/buildSrc/src/main/kotlin/Helpers.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2022 Proton Technologies AG - * This file is part of Proton Technologies AG and Proton Mail. - * - * Proton Mail is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Proton Mail is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Proton Mail. If not, see . - */ - -import java.io.File -import java.io.IOException -import java.util.concurrent.TimeUnit -import org.gradle.api.Project -import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.dependencies -import kotlin.apply -import kotlin.io.inputStream - -fun String.runCommand( - workingDir: File = File("."), - timeoutAmount: Long = 60, - timeoutUnit: TimeUnit = TimeUnit.SECONDS -): String = ProcessBuilder(split("\\s(?=(?:[^'\"`]*(['\"`])[^'\"`]*\\1)*[^'\"`]*$)".toRegex())) - .directory(workingDir) - .redirectOutput(ProcessBuilder.Redirect.PIPE) - .redirectError(ProcessBuilder.Redirect.PIPE) - .start() - .apply { waitFor(timeoutAmount, timeoutUnit) } - .run { - val error = errorStream.bufferedReader().readText().trim() - if (error.isNotEmpty()) { - throw IOException(error) - } - inputStream.bufferedReader().readText().trim() - }