Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Google Play upload task #49

Merged
merged 2 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ moshi = "1.15.0"
retrofit = "2.9.0"
junit = "4.13.2"
ksp = "1.9.23-1.0.19"
play-publish = "v3-rev20231115-2.0.0"
google-auth = "1.20.0"

[libraries]
agp = { module = "com.android.tools.build:gradle", version.ref = "agp" }
Expand All @@ -29,6 +31,8 @@ kotlin-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.
ktlint-plugin = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint" }
detekt-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" }
ksp-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
play-publish = { module = "com.google.apis:google-api-services-androidpublisher", version.ref = "play-publish" }
google-auth = { module = "com.google.auth:google-auth-library-oauth2-http", version.ref = "google-auth" }

[plugins]
agp = { id = "com.android.application", version.ref = "agp" }
Expand Down
2 changes: 2 additions & 0 deletions plugin-build/plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ dependencies {
implementation(libs.retrofitMoshi)
implementation(libs.grgitCore)
implementation(libs.grgitGradle)
implementation(libs.play.publish)
implementation(libs.google.auth)

testImplementation(libs.junit)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package ru.kode.android.build.publish.plugin

import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.api.variant.impl.VariantOutputImpl
import com.android.build.gradle.AppExtension
Expand Down Expand Up @@ -33,11 +34,13 @@ import ru.kode.android.build.publish.plugin.extension.config.ChangelogConfig
import ru.kode.android.build.publish.plugin.extension.config.FirebaseAppDistributionConfig
import ru.kode.android.build.publish.plugin.extension.config.JiraConfig
import ru.kode.android.build.publish.plugin.extension.config.OutputConfig
import ru.kode.android.build.publish.plugin.extension.config.PlayConfig
import ru.kode.android.build.publish.plugin.extension.config.SlackConfig
import ru.kode.android.build.publish.plugin.extension.config.TelegramConfig
import ru.kode.android.build.publish.plugin.task.appcenter.AppCenterDistributionTask
import ru.kode.android.build.publish.plugin.task.changelog.GenerateChangelogTask
import ru.kode.android.build.publish.plugin.task.jira.JiraAutomationTask
import ru.kode.android.build.publish.plugin.task.play.PlayDistributionTask
import ru.kode.android.build.publish.plugin.task.slack.changelog.SendSlackChangelogTask
import ru.kode.android.build.publish.plugin.task.slack.distribution.SlackDistributionTask
import ru.kode.android.build.publish.plugin.task.tag.GetLastTagTask
Expand All @@ -59,6 +62,7 @@ internal const val DEFAULT_VERSION_CODE = 1
internal const val DEFAULT_BASE_FILE_NAME = "dev-build"
internal const val CHANGELOG_FILENAME = "changelog.txt"
internal const val APP_CENTER_DISTRIBUTION_UPLOAD_TASK_PREFIX = "appCenterDistributionUpload"
internal const val PLAY_DISTRIBUTION_UPLOAD_TASK_PREFIX = "playUpload"
internal const val SLACK_DISTRIBUTION_UPLOAD_TASK_PREFIX = "slackDistributionUpload"
internal const val JIRA_AUTOMATION_TASK = "jiraAutomation"
internal const val DEFAULT_CONTAINER_NAME = "default"
Expand Down Expand Up @@ -93,17 +97,20 @@ abstract class BuildPublishPlugin : Plugin<Project> {
as? VariantOutputImpl
if (output != null) {
val buildVariant = BuildVariant(variant.name, variant.flavorName, variant.buildType)
val outputFileName = output.outputFileName.get()
val apkOutputFileName = output.outputFileName.get()

val bundleFile = variant.artifacts.get(SingleArtifact.BUNDLE)
val outputProviders =
project.registerVariantTasks(
buildPublishExtension,
buildVariant,
changelogFile,
outputFileName,
apkOutputFileName,
bundleFile,
grgitService,
)
output.versionCode.set(outputProviders.versionCode)
output.outputFileName.set(outputProviders.outputFileName)
output.outputFileName.set(outputProviders.apkOutputFileName)
output.versionName.set(outputProviders.versionName)
}
},
Expand All @@ -128,7 +135,8 @@ abstract class BuildPublishPlugin : Plugin<Project> {
buildPublishExtension: BuildPublishExtension,
buildVariant: BuildVariant,
changelogFile: Provider<RegularFile>,
outputFileName: String,
apkOutputFileName: String,
bundleFile: Provider<RegularFile>,
grgitService: Provider<GrgitService>,
): OutputProviders {
val outputConfig =
Expand All @@ -150,15 +158,15 @@ abstract class BuildPublishPlugin : Plugin<Project> {
project.provider { DEFAULT_VERSION_CODE }
}
}
val outputFileNameProvider =
val apkOutputFileNameProvider =
useVersionsFromTagProvider.flatMap { useVersionsFromTag ->
if (useVersionsFromTag) {
outputConfig.baseFileName.zip(tagBuildProvider) { baseFileName, tagBuildFile ->
mapToOutputFileName(tagBuildFile, outputFileName, baseFileName)
mapToOutputApkFileName(tagBuildFile, apkOutputFileName, baseFileName)
}
} else {
outputConfig.baseFileName.map { baseFileName ->
createDefaultOutputFileName(baseFileName, outputFileName)
createDefaultOutputFileName(baseFileName, apkOutputFileName)
}
}
}
Expand All @@ -172,9 +180,9 @@ abstract class BuildPublishPlugin : Plugin<Project> {
project.provider { DEFAULT_VERSION_NAME }
}
}
val outputFileProvider =
outputFileNameProvider.flatMap { fileName ->
mapToOutputFile(buildVariant, fileName)
val apkOutputFileProvider =
apkOutputFileNameProvider.flatMap { fileName ->
mapToOutputApkFile(buildVariant, fileName)
}
tasks.registerPrintLastIncreasedTagTask(
buildVariant,
Expand Down Expand Up @@ -220,7 +228,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
buildVariant,
generateChangelogFileProvider,
tagBuildProvider,
outputFileProvider,
apkOutputFileProvider,
)
}
val appCenterDistributionConfig =
Expand All @@ -233,12 +241,27 @@ abstract class BuildPublishPlugin : Plugin<Project> {
config = appCenterDistributionConfig,
buildVariant = buildVariant,
changelogFileProvider = generateChangelogFileProvider,
buildVariantOutputFileProvider = outputFileProvider,
apkOutputFileProvider = apkOutputFileProvider,
tagBuildProvider = tagBuildProvider,
outputConfig = outputConfig,
)
tasks.registerAppCenterDistributionTask(params)
}
val playConfig =
with(buildPublishExtension.play) {
findByName(buildVariant.name) ?: findByName(DEFAULT_CONTAINER_NAME)
}
if (playConfig != null) {
val params =
PlayTaskParams(
config = playConfig,
buildVariant = buildVariant,
bundleOutputFileProvider = bundleFile,
tagBuildProvider = tagBuildProvider,
outputConfig = outputConfig,
)
tasks.registerPlayTask(params)
}
val jiraConfig =
with(buildPublishExtension.jira) {
findByName(buildVariant.name) ?: findByName(DEFAULT_CONTAINER_NAME)
Expand All @@ -256,7 +279,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
return OutputProviders(
versionName = versionNameProvider,
versionCode = versionCodeProvider,
outputFileName = outputFileNameProvider,
apkOutputFileName = apkOutputFileNameProvider,
)
}

Expand Down Expand Up @@ -298,7 +321,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
buildVariant: BuildVariant,
generateChangelogFileProvider: Provider<RegularFile>,
tagBuildProvider: Provider<RegularFile>,
outputFileProvider: Provider<RegularFile>,
apkOutputFileProvider: Provider<RegularFile>,
) {
registerSendSlackChangelogTask(
outputConfig,
Expand All @@ -316,7 +339,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
slackConfig.uploadApiTokenFile,
slackConfig.uploadChannels,
buildVariant,
outputFileProvider,
apkOutputFileProvider,
)
}
}
Expand All @@ -325,13 +348,13 @@ abstract class BuildPublishPlugin : Plugin<Project> {
apiTokenFile: RegularFileProperty,
channels: SetProperty<String>,
buildVariant: BuildVariant,
outputFileProvider: Provider<RegularFile>,
apkOutputFileProvider: Provider<RegularFile>,
) {
register(
"$SLACK_DISTRIBUTION_UPLOAD_TASK_PREFIX${buildVariant.capitalizedName()}",
SlackDistributionTask::class.java,
) {
it.buildVariantOutputFile.set(outputFileProvider)
it.buildVariantOutputFile.set(apkOutputFileProvider)
it.apiTokenFile.set(apiTokenFile)
it.channels.set(channels)
}
Expand Down Expand Up @@ -449,7 +472,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
AppCenterDistributionTask::class.java,
) {
it.tagBuildFile.set(params.tagBuildProvider)
it.buildVariantOutputFile.set(params.buildVariantOutputFileProvider)
it.buildVariantOutputFile.set(params.apkOutputFileProvider)
it.changelogFile.set(params.changelogFileProvider)
it.apiTokenFile.set(config.apiTokenFile)
it.ownerName.set(config.ownerName)
Expand All @@ -461,6 +484,23 @@ abstract class BuildPublishPlugin : Plugin<Project> {
it.uploadStatusRequestDelayCoefficient.set(config.uploadStatusRequestDelayCoefficient)
}
}

private fun TaskContainer.registerPlayTask(params: PlayTaskParams): TaskProvider<PlayDistributionTask> {
val buildVariant = params.buildVariant
val config = params.config

return register(
"$PLAY_DISTRIBUTION_UPLOAD_TASK_PREFIX${buildVariant.capitalizedName()}",
PlayDistributionTask::class.java,
) {
it.tagBuildFile.set(params.tagBuildProvider)
it.buildVariantOutputFile.set(params.bundleOutputFileProvider)
it.apiTokenFile.set(config.apiTokenFile)
it.appId.set(config.appId)
it.trackId.set(config.trackId)
it.updatePriority.set(config.updatePriority)
}
}
}

private fun Project.configurePlugins(
Expand Down Expand Up @@ -540,14 +580,22 @@ private fun AppDistributionExtension.configure(
private data class OutputProviders(
val versionName: Provider<String>,
val versionCode: Provider<Int>,
val outputFileName: Provider<String>,
val apkOutputFileName: Provider<String>,
)

private data class AppCenterDistributionTaskParams(
val config: AppCenterDistributionConfig,
val buildVariant: BuildVariant,
val changelogFileProvider: Provider<RegularFile>,
val buildVariantOutputFileProvider: Provider<RegularFile>,
val apkOutputFileProvider: Provider<RegularFile>,
val tagBuildProvider: Provider<RegularFile>,
val outputConfig: OutputConfig,
)

private data class PlayTaskParams(
val config: PlayConfig,
val buildVariant: BuildVariant,
val bundleOutputFileProvider: Provider<RegularFile>,
val tagBuildProvider: Provider<RegularFile>,
val outputConfig: OutputConfig,
)
Expand All @@ -561,7 +609,7 @@ private fun mapToVersionCode(tagBuildFile: RegularFile): Int {
}
}

private fun mapToOutputFileName(
private fun mapToOutputApkFileName(
tagBuildFile: RegularFile,
outputFileName: String,
baseFileName: String?,
Expand Down Expand Up @@ -600,7 +648,7 @@ private fun mapToVersionName(
}
}

private fun Project.mapToOutputFile(
private fun Project.mapToOutputApkFile(
buildVariant: BuildVariant,
fileName: String,
): Provider<RegularFile> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ru.kode.android.build.publish.plugin.extension.config.ChangelogConfig
import ru.kode.android.build.publish.plugin.extension.config.FirebaseAppDistributionConfig
import ru.kode.android.build.publish.plugin.extension.config.JiraConfig
import ru.kode.android.build.publish.plugin.extension.config.OutputConfig
import ru.kode.android.build.publish.plugin.extension.config.PlayConfig
import ru.kode.android.build.publish.plugin.extension.config.SlackConfig
import ru.kode.android.build.publish.plugin.extension.config.TelegramConfig
import javax.inject.Inject
Expand All @@ -31,4 +32,6 @@ abstract class BuildPublishExtension
objectFactory.domainObjectContainer(FirebaseAppDistributionConfig::class.java)
val appCenterDistribution: NamedDomainObjectContainer<AppCenterDistributionConfig> =
objectFactory.domainObjectContainer(AppCenterDistributionConfig::class.java)
val play: NamedDomainObjectContainer<PlayConfig> =
objectFactory.domainObjectContainer(PlayConfig::class.java)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ru.kode.android.build.publish.plugin.extension.config

import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile

interface PlayConfig {
val name: String

/**
* The path to file with token for Google Play project
*/
@get:InputFile
val apiTokenFile: RegularFileProperty

/**
* appId in Google Play
*/
@get:Input
val appId: Property<String>

/**
* Track name of target app. Defaults to "internal"
*/
@get:Input
val trackId: Property<String>

/**
* Test groups for app distribution
*
* For example: [android-testers]
*/
@get:Input
val updatePriority: Property<Int>
}
Loading
Loading