Skip to content

Commit

Permalink
[Feat]: 增加 Action 更新通道配置
Browse files Browse the repository at this point in the history
  • Loading branch information
why committed Mar 26, 2024
1 parent adbcab8 commit dad009a
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 32 deletions.
7 changes: 5 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import java.io.ByteArrayOutputStream

plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
Expand Down Expand Up @@ -39,7 +41,7 @@ android {
}

buildTypes {
getByName("release") {
debug {
isMinifyEnabled = false
isShrinkResources = false
signingConfig = signingConfigs.getByName("release")
Expand All @@ -49,7 +51,7 @@ android {
)
}

getByName("debug") {
debug {
isMinifyEnabled = false
isShrinkResources = false
signingConfig = signingConfigs.getByName("release")
Expand All @@ -71,6 +73,7 @@ android {

buildFeatures {
viewBinding = true
buildConfig = true
}

packaging {
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/java/com/xiaoyv/bangumi/ui/HomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ class HomeActivity : BaseViewModelActivity<ActivityHomeBinding, MainViewModel>()
}

// 更新检测
UpdateHelper.checkUpdate(this, false)
if (ConfigHelper.updateChannel == UpdateHelper.CHANNEL_RELEASE) {
UpdateHelper.checkUpdateRelease(this, false)
} else {
UpdateHelper.checkUpdateAction(this, false)
}

showTip()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -150,7 +151,11 @@ class SettingActivity : BaseViewModelActivity<ActivitySettingBinding, SettingVie
}

binding.settingAbout.setOnFastLimitClickListener {
UpdateHelper.checkUpdate(this, true)
if (ConfigHelper.updateChannel == UpdateHelper.CHANNEL_RELEASE) {
UpdateHelper.checkUpdateRelease(this, true)
} else {
UpdateHelper.checkUpdateAction(this, true)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.xiaoyv.bangumi.databinding.ActivitySettingGithubBinding
import com.xiaoyv.blueprint.base.mvvm.normal.BaseViewModelActivity
import com.xiaoyv.common.api.BgmApiManager
import com.xiaoyv.common.helper.ConfigHelper
import com.xiaoyv.common.helper.UpdateHelper
import com.xiaoyv.common.kts.CommonDrawable
import com.xiaoyv.common.kts.initNavBack
import com.xiaoyv.common.kts.showConfirmDialog
Expand Down Expand Up @@ -115,6 +116,13 @@ class NetworkConfigActivity :

binding.settingSearchAp.bindBoolean(ConfigHelper::isImageSearchAP)

binding.settingUpdateChannel.bindSerializable(
activity = this,
property = ConfigHelper::updateChannel,
names = listOf("Release 通道", "Action 通道"),
values = listOf(UpdateHelper.CHANNEL_RELEASE, UpdateHelper.CHANNEL_ACTION)
)

refresh()
}

Expand Down
17 changes: 14 additions & 3 deletions app/src/main/res/layout/activity_setting_github.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
android:text="班固米域名"
app:subtitle="bgm.tv" />


<com.xiaoyv.common.widget.text.AnimeTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down Expand Up @@ -120,7 +121,7 @@
android:layout_marginTop="@dimen/ui_layout_margin"
android:paddingHorizontal="@dimen/ui_layout_margin"
android:paddingVertical="@dimen/ui_size_6"
android:text="图片搜索"
android:text="APP 相关"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant" />

Expand All @@ -131,7 +132,7 @@
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:text="禁用 Tags" />
android:text="图片搜索禁用 Tags" />

<com.xiaoyv.common.widget.setting.SettingItemView
android:id="@+id/setting_search_ap"
Expand All @@ -140,6 +141,16 @@
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:text="搜索源 AP" />
android:text="图片 AP 搜索源" />

<com.xiaoyv.common.widget.setting.SettingItemView
android:id="@+id/setting_update_channel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:text="更新检查通道"
app:subtitle="Release" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
15 changes: 1 addition & 14 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions lib-common/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import java.io.ByteArrayOutputStream

plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.jetbrainsKotlinAndroid)
Expand All @@ -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
Expand All @@ -24,6 +36,10 @@ android {
"proguard-rules.pro"
)
}

debug {
buildConfigField("java.lang.String", "BUILD_HEAD_SHA", "\"${headSha()}\"")
}
}

ksp {
Expand All @@ -41,6 +57,7 @@ android {

buildFeatures {
viewBinding = true
buildConfig = true
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -52,6 +53,13 @@ interface BgmWebApi {
@GET("{url}")
suspend fun qeuryUrl(@Path("url", encoded = true) url: String): Response<ResponseBody>

@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<ResponseBody>

@GET("/login")
suspend fun queryLoginPage(): Document

Expand Down
Original file line number Diff line number Diff line change
@@ -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<Artifact>? = 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
}
10 changes: 10 additions & 0 deletions lib-common/src/main/java/com/xiaoyv/common/helper/ConfigHelper.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("SpellCheckingInspection")

package com.xiaoyv.common.helper

import android.os.Build
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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,越大越不容易左右滑动误触发
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 = {
Expand Down
Loading

0 comments on commit dad009a

Please sign in to comment.