From dad009a63c88ac64beebbeb782d235f53e11c8b1 Mon Sep 17 00:00:00 2001 From: why Date: Tue, 26 Mar 2024 20:01:04 +0800 Subject: [PATCH] =?UTF-8?q?[Feat]:=20=E5=A2=9E=E5=8A=A0=20Action=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=80=9A=E9=81=93=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 7 +- .../com/xiaoyv/bangumi/ui/HomeActivity.kt | 6 +- .../ui/feature/setting/SettingActivity.kt | 7 +- .../setting/network/NetworkConfigActivity.kt | 8 +++ .../res/layout/activity_setting_github.xml | 17 ++++- gradle.properties | 15 +---- lib-common/build.gradle.kts | 17 +++++ .../com/xiaoyv/common/api/api/BgmJsonApi.kt | 7 ++ .../com/xiaoyv/common/api/api/BgmWebApi.kt | 8 +++ .../common/api/response/GithubActionEntity.kt | 44 +++++++++++++ .../com/xiaoyv/common/helper/ConfigHelper.kt | 10 +++ .../com/xiaoyv/common/helper/UpdateHelper.kt | 66 ++++++++++++++++++- lib-h5/public/test.http | 25 ++++--- 13 files changed, 205 insertions(+), 32 deletions(-) create mode 100644 lib-common/src/main/java/com/xiaoyv/common/api/response/GithubActionEntity.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1ef1a14a..8cfebb0b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import java.io.ByteArrayOutputStream + plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.jetbrainsKotlinAndroid) @@ -39,7 +41,7 @@ android { } buildTypes { - getByName("release") { + debug { isMinifyEnabled = false isShrinkResources = false signingConfig = signingConfigs.getByName("release") @@ -49,7 +51,7 @@ android { ) } - getByName("debug") { + debug { isMinifyEnabled = false isShrinkResources = false signingConfig = signingConfigs.getByName("release") @@ -71,6 +73,7 @@ android { buildFeatures { viewBinding = true + buildConfig = true } packaging { diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/HomeActivity.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/HomeActivity.kt index ba24e6bf..b153c93f 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/HomeActivity.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/HomeActivity.kt @@ -149,7 +149,11 @@ class HomeActivity : BaseViewModelActivity() } // 更新检测 - UpdateHelper.checkUpdate(this, false) + if (ConfigHelper.updateChannel == UpdateHelper.CHANNEL_RELEASE) { + UpdateHelper.checkUpdateRelease(this, false) + } else { + UpdateHelper.checkUpdateAction(this, false) + } showTip() } diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/setting/SettingActivity.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/setting/SettingActivity.kt index c3c48f68..d7a02897 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/setting/SettingActivity.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/setting/SettingActivity.kt @@ -12,6 +12,7 @@ import com.xiaoyv.bangumi.helper.RouteHelper import com.xiaoyv.blueprint.base.mvvm.normal.BaseViewModelActivity import com.xiaoyv.blueprint.kts.launchUI import com.xiaoyv.common.config.GlobalConfig +import com.xiaoyv.common.helper.ConfigHelper import com.xiaoyv.common.helper.UpdateHelper import com.xiaoyv.common.helper.UserHelper import com.xiaoyv.common.kts.initNavBack @@ -150,7 +151,11 @@ class SettingActivity : BaseViewModelActivity + @@ -131,7 +132,7 @@ android:background="?attr/selectableItemBackground" android:clickable="true" android:focusable="true" - android:text="禁用 Tags" /> + android:text="图片搜索禁用 Tags" /> + android:text="图片 AP 搜索源" /> + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 9d6c32ae..3edbcbdd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,4 @@ -## For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx1024m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -# -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. For more details, visit -# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects -# org.gradle.parallel=true -#Sun Dec 10 16:25:48 CST 2023 +org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" -Dfile.encoding\=UTF-8 android.nonTransitiveRClass=true android.useAndroidX=true kotlin.code.style=official -org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" -Dfile.encoding\=UTF-8 diff --git a/lib-common/build.gradle.kts b/lib-common/build.gradle.kts index 363ae415..a8688ca4 100644 --- a/lib-common/build.gradle.kts +++ b/lib-common/build.gradle.kts @@ -1,3 +1,5 @@ +import java.io.ByteArrayOutputStream + plugins { alias(libs.plugins.androidLibrary) alias(libs.plugins.jetbrainsKotlinAndroid) @@ -16,6 +18,16 @@ android { consumerProguardFiles("consumer-rules.pro") } + // Head Hash + fun headSha() = ByteArrayOutputStream().let { + exec { + commandLine("bash", "-c", "git rev-parse HEAD") + isIgnoreExitValue = true + standardOutput = it + } + it.toString().trim().lowercase() + } + buildTypes { release { isMinifyEnabled = false @@ -24,6 +36,10 @@ android { "proguard-rules.pro" ) } + + debug { + buildConfigField("java.lang.String", "BUILD_HEAD_SHA", "\"${headSha()}\"") + } } ksp { @@ -41,6 +57,7 @@ android { buildFeatures { viewBinding = true + buildConfig = true } } diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmJsonApi.kt b/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmJsonApi.kt index ab4eb98b..6df35469 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmJsonApi.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmJsonApi.kt @@ -9,6 +9,7 @@ import com.xiaoyv.common.api.request.SyncNameParam import com.xiaoyv.common.api.response.AuthStatusEntity import com.xiaoyv.common.api.response.AuthTokenEntity import com.xiaoyv.common.api.response.BaiduTranslateEntity +import com.xiaoyv.common.api.response.GithubActionEntity import com.xiaoyv.common.api.response.GithubContent import com.xiaoyv.common.api.response.GithubLatestEntity import com.xiaoyv.common.api.response.GithubPutEntity @@ -80,6 +81,12 @@ interface BgmJsonApi { @GET("https://api.github.com/repos/xiaoyvyv/bangumi/releases/latest") suspend fun queryGithubLatest(): GithubLatestEntity + @GET("https://api.github.com/repos/xiaoyvyv/bangumi/actions/artifacts") + suspend fun queryGithubAction( + @Query("name") name: String, + @Query("per_page") pageSize: Int + ): GithubActionEntity + @GET("https://api.github.com/repos/{user}/{repo}/contents/{path}") suspend fun queryGithubFileContent( @Path("user", encoded = true) user: String, diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt b/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt index 8a14eba0..968826de 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt @@ -7,6 +7,7 @@ import com.xiaoyv.common.api.parser.entity.DollarsEntity import com.xiaoyv.common.api.parser.entity.LikeEntity import com.xiaoyv.common.api.request.CreateTokenParam import com.xiaoyv.common.api.response.BgmStatusEntity +import com.xiaoyv.common.api.response.GithubActionEntity import com.xiaoyv.common.api.response.NotifyEntity import com.xiaoyv.common.api.response.ReplyResultEntity import com.xiaoyv.common.api.response.UploadResultEntity @@ -52,6 +53,13 @@ interface BgmWebApi { @GET("{url}") suspend fun qeuryUrl(@Path("url", encoded = true) url: String): Response + @GET("{url}") + suspend fun queryGithubActionDownloadUrl( + @Header("Authorization") token: String = "Bearer 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", + @Header("X-GitHub-Api-Version") version: String = "2022-11-28", + @Path("url", encoded = true) url: String + ): Response + @GET("/login") suspend fun queryLoginPage(): Document diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/response/GithubActionEntity.kt b/lib-common/src/main/java/com/xiaoyv/common/api/response/GithubActionEntity.kt new file mode 100644 index 00000000..d6717363 --- /dev/null +++ b/lib-common/src/main/java/com/xiaoyv/common/api/response/GithubActionEntity.kt @@ -0,0 +1,44 @@ +package com.xiaoyv.common.api.response + +import android.os.Parcelable + +import kotlinx.parcelize.Parcelize + +import androidx.annotation.Keep + +import com.google.gson.annotations.SerializedName + + +@Keep +@Parcelize +data class GithubActionEntity( + @SerializedName("artifacts") var artifacts: List? = null, + @SerializedName("total_count") var totalCount: Int = 0 +) : Parcelable { + + @Keep + @Parcelize + data class Artifact( + @SerializedName("archive_download_url") var archiveDownloadUrl: String? = null, + @SerializedName("created_at") var createdAt: String? = null, + @SerializedName("expired") var expired: Boolean = false, + @SerializedName("expires_at") var expiresAt: String? = null, + @SerializedName("id") var id: Long = 0, + @SerializedName("name") var name: String? = null, + @SerializedName("node_id") var nodeId: String? = null, + @SerializedName("size_in_bytes") var sizeInBytes: Long = 0, + @SerializedName("updated_at") var updatedAt: String? = null, + @SerializedName("url") var url: String? = null, + @SerializedName("workflow_run") var workflowRun: WorkflowRun? = null + ) : Parcelable + + @Keep + @Parcelize + data class WorkflowRun( + @SerializedName("head_branch") var headBranch: String? = null, + @SerializedName("head_repository_id") var headRepositoryId: Long = 0, + @SerializedName("head_sha") var headSha: String? = null, + @SerializedName("id") var id: Long = 0, + @SerializedName("repository_id") var repositoryId: Long = 0 + ) : Parcelable +} \ No newline at end of file diff --git a/lib-common/src/main/java/com/xiaoyv/common/helper/ConfigHelper.kt b/lib-common/src/main/java/com/xiaoyv/common/helper/ConfigHelper.kt index 4452cdd0..bf287700 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/helper/ConfigHelper.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/helper/ConfigHelper.kt @@ -1,3 +1,5 @@ +@file:Suppress("SpellCheckingInspection") + package com.xiaoyv.common.helper import android.os.Build @@ -45,6 +47,7 @@ object ConfigHelper { private const val KEY_NETWORK_HOSTS = "network-hosts" private const val KEY_VP_SLOP = "vp-slop" private const val KEY_BGM_URL = "bgm-url" + private const val KEY_UPDATE_CHANNEL = "update-channel" private const val KEY_RAKUEN_TAB_REMEMBER = "rakuen-tab-remember" private const val KEY_TIMELINE_TAB_REMEMBER = "timeline-tab-remember" private const val KEY_FORCE_BROWSER = "force-browser" @@ -327,6 +330,13 @@ object ConfigHelper { get() = SPStaticUtils.getString(KEY_BGM_URL, BgmApiManager.baseUrlArray.first()) set(value) = SPStaticUtils.put(KEY_BGM_URL, value.trim()) + /** + * 默认的域名 + */ + var updateChannel: String + get() = SPStaticUtils.getString(KEY_UPDATE_CHANNEL, UpdateHelper.CHANNEL_RELEASE) + set(value) = SPStaticUtils.put(KEY_UPDATE_CHANNEL, value.trim()) + /** * VP 滚动斜率阈值倍数,SDK 默认值为 2,越大越不容易左右滑动误触发 */ diff --git a/lib-common/src/main/java/com/xiaoyv/common/helper/UpdateHelper.kt b/lib-common/src/main/java/com/xiaoyv/common/helper/UpdateHelper.kt index cff7435c..37676197 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/helper/UpdateHelper.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/helper/UpdateHelper.kt @@ -1,9 +1,12 @@ package com.xiaoyv.common.helper import com.blankj.utilcode.util.AppUtils +import com.blankj.utilcode.util.SPStaticUtils import com.xiaoyv.blueprint.base.mvvm.normal.BaseViewModelActivity import com.xiaoyv.blueprint.kts.launchUI +import com.xiaoyv.common.BuildConfig import com.xiaoyv.common.api.BgmApiManager +import com.xiaoyv.common.api.response.GithubActionEntity import com.xiaoyv.common.kts.openInBrowser import com.xiaoyv.common.kts.showConfirmDialog import com.xiaoyv.widget.kts.errorMsg @@ -18,11 +21,72 @@ import kotlinx.coroutines.withContext * @since 12/12/23 */ object UpdateHelper { + const val CHANNEL_RELEASE = "Release" + const val CHANNEL_ACTION = "Action" /** + * Action 通道 + * * 更新通过对比 Tag 实现,github 发布 Release 必须严格按照 `vX.X.X` 格式创建 Tag */ - fun checkUpdate(activity: BaseViewModelActivity<*, *>, showLoading: Boolean = false) { + fun checkUpdateAction(activity: BaseViewModelActivity<*, *>, showLoading: Boolean = false) { + activity.launchUI( + state = if (showLoading) activity.viewModel.loadingDialogState(cancelable = false) else null, + error = { + it.printStackTrace() + + if (showLoading) { + showToastCompat(it.errorMsg) + } + }, + block = { + val entity = withContext(Dispatchers.IO) { + BgmApiManager.bgmJsonApi.queryGithubAction( + name = "app-universal-release.apk", + pageSize = 1 + ) + } + + val artifact = entity.artifacts?.firstOrNull() + val headSha = artifact?.workflowRun?.headSha.orEmpty() + + require(artifact != null && headSha.isNotBlank()) { "暂无更新包发布" } + + require(BuildConfig.BUILD_HEAD_SHA != headSha) { "当前已经是最新版" } + + val downloadUrl = queryActionDownloadUrl(artifact) + + activity.showConfirmDialog( + title = "检测到 Action 更新", + message = "检测到有新的 Action 版本(${artifact.id}),是否下载更新?", + confirmText = "下载", + neutralText = "查看详情", + cancelable = false, + onNeutralClick = { + openInBrowser("https://github.com/xiaoyvyv/bangumi/actions/runs/${artifact.workflowRun?.id}") + }, + onConfirmClick = { + openInBrowser(downloadUrl) + } + ) + } + ) + } + + private suspend fun queryActionDownloadUrl(artifact: GithubActionEntity.Artifact): String { + return withContext(Dispatchers.IO) { + BgmApiManager.bgmWebNoRedirectApi.queryGithubActionDownloadUrl(url = artifact.archiveDownloadUrl.orEmpty()) + .headers()["Location"] + .orEmpty() + } + } + + /** + * Release 通道 + * + * 更新通过对比 Tag 实现,github 发布 Release 必须严格按照 `vX.X.X` 格式创建 Tag + */ + fun checkUpdateRelease(activity: BaseViewModelActivity<*, *>, showLoading: Boolean = false) { activity.launchUI( state = if (showLoading) activity.viewModel.loadingDialogState(cancelable = false) else null, error = { diff --git a/lib-h5/public/test.http b/lib-h5/public/test.http index 7d1098cf..16ba7bbe 100644 --- a/lib-h5/public/test.http +++ b/lib-h5/public/test.http @@ -268,13 +268,18 @@ Content-Type: application/json ### -POST / HTTP/1.1 -Host: res.res.res.res:11400 -Content-Length: 288 -Content-Type: application/octet-stream -Connection: close -User-Agent: Mozilla/4.0 -Accept: */* - -�X&'�����2�b�� ,I�1l�[�ᣪ�ȶ�+�����$��;=E�gQ:�u���cŏҦ}[<�Û�v�qV�)3۲GǃSH�q��8����~�E����E���/Ay� 0�"��*���y�Q�ɣi$�ga٤��?��qK�C��~�&�F��(G�]-0�~CӨ5t��et�,8tJ� -���-�)$t��2��E�v��Cc5jhS���.=�b`f �'=���)�U��ɫp����Y��eq���8J��*P �rL/w�o \ No newline at end of file +# @no-redirect +https://api.github.com/repos/xiaoyvyv/bangumi/actions/artifacts/1358851382/zip + +### + +# @no-redirect +GET https://api.github.com/repos/xiaoyvyv/bangumi/actions/artifacts/1358851382/zip +Accept: application/vnd.github+json +Authorization: Bearer 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 +X-GitHub-Api-Version: 2022-11-28 + +### + + +