Compare commits

...
4 Commits
Author SHA1 Message Date
yenru0 f66a463393 Release 1.15.0 2026-10-08 17:48:29 +09:00
yenru0 33fd89041c Merge remote-tracking branch 'origin/main' 2026-10-08 17:45:37 +09:00
Dude so hot 40271d744b Fixup deser type 2026-10-08 16:36:38 +08:00
Dude so hot d901326640 Support automatically download ci 2026-10-08 16:19:03 +08:00
10 changed files with 86 additions and 112 deletions

No files matched your search

-3
View File
@@ -54,9 +54,6 @@ jobs:
- name: Spotless Check
run: ./gradlew spotlessCheck
- name: Lint Check
run: ./gradlew lintDefaultRelease
default:
runs-on: nekomoee
steps:
+5 -5
View File
@@ -47,25 +47,25 @@ android {
commandLine = "git log -1 --format=%ct".split(' ')
}.standardOutput.asText.get().trim()
val repoUrl = providers.exec {
val repoName = providers.exec {
commandLine = "git remote get-url origin".split(' ')
}.standardOutput.asText.get().trim().removeSuffix(".git")
}.standardOutput.asText.get().trim().removeSuffix(".git").removePrefix("https://codeberg.org/")
val snapshot = !hasProperty("release")
defaultConfig {
applicationId = "yenru0.yrkaierx.ehviewer"
versionCode = 180063
versionCode = 180064
versionName = if (snapshot) {
"1.15.0-SNAPSHOT"
} else {
"1.14.6"
"1.15.0"
}
buildConfigField("boolean", "SNAPSHOT", "$snapshot")
buildConfigField("String", "RAW_VERSION_NAME", "\"$versionName\"")
buildConfigField("String", "COMMIT_SHA", "\"$commitSha\"")
buildConfigField("long", "COMMIT_TIME", commitTime)
buildConfigField("String", "REPO_URL", "\"$repoUrl\"")
buildConfigField("String", "REPO_NAME", "\"$repoName\"")
ndk {
if (isRelease) {
abiFilters.addAll(supportedAbis)
@@ -36,7 +36,7 @@ import com.hippo.ehviewer.ui.main.NavigationIcon
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.updater.AppUpdater
import com.hippo.ehviewer.updater.Release
import com.hippo.ehviewer.updater.EhRelease
import com.hippo.ehviewer.util.AppConfig
import com.hippo.ehviewer.util.ReadableTime
import com.hippo.ehviewer.util.displayString
@@ -49,7 +49,7 @@ import moe.tarsin.navigate
import moe.tarsin.snackbar
import moe.tarsin.string
const val REPO_URL = BuildConfig.REPO_URL
const val REPO_URL = "https://codeberg.org/${BuildConfig.REPO_NAME}"
const val RELEASE_URL = "$REPO_URL/releases"
@Composable
@@ -124,7 +124,7 @@ fun AnimatedVisibilityScope.AboutScreen(navigator: DestinationsNavigator) = Scre
}
context(_: Context, _: DialogState)
suspend fun showNewVersion(release: Release) {
suspend fun showNewVersion(release: EhRelease) {
awaitConfirmationOrCancel(
confirmText = R.string.download,
title = R.string.new_version_available,
@@ -6,12 +6,9 @@ import com.hippo.ehviewer.EhApplication.Companion.ktorClient
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.executeAndParseAs
import com.hippo.ehviewer.spider.timeoutBySpeed
import com.hippo.ehviewer.ui.settings.RELEASE_URL
import com.hippo.ehviewer.ui.settings.REPO_URL
import com.hippo.ehviewer.util.copyTo
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.accept
import io.ktor.client.request.bearerAuth
import io.ktor.client.request.prepareGet
import io.ktor.client.statement.bodyAsChannel
import io.ktor.http.ContentType
@@ -23,17 +20,18 @@ import kotlin.time.Instant
import kotlinx.io.asSource
import moe.tarsin.coroutines.runSuspendCatching
import okio.Path
import tachiyomi.data.release.GithubArtifacts
import tachiyomi.data.release.GithubCommitComparison
import tachiyomi.data.release.GithubRelease
import tachiyomi.data.release.GithubRepo
import tachiyomi.data.release.GithubWorkflowRuns
import tachiyomi.data.release.Artifacts
import tachiyomi.data.release.CommitComparison
import tachiyomi.data.release.Release
import tachiyomi.data.release.Repository
import tachiyomi.data.release.WorkflowRuns
import tachiyomi.data.release.downloadLink
private const val API_URL = "$REPO_URL/actions/runs"
const val LATEST_RELEASE_URL = "$RELEASE_URL/latest"
const val API_URL = "https://codeberg.org/api/v1/repos/${BuildConfig.REPO_NAME}"
const val LATEST_RELEASE_URL = "$API_URL/releases/latest"
object AppUpdater {
suspend fun checkForUpdate(forceCheck: Boolean = false): Release? {
suspend fun checkForUpdate(forceCheck: Boolean = false): EhRelease? {
val now = Clock.System.now()
val last = Instant.fromEpochSeconds(Settings.lastUpdateTime)
val interval = Settings.updateIntervalDays.value
@@ -41,31 +39,30 @@ object AppUpdater {
Settings.lastUpdateTime = now.epochSeconds
if (Settings.useCIUpdateChannel.value) {
val curSha = BuildConfig.COMMIT_SHA
val branch = ghStatement(API_URL).executeAndParseAs<GithubRepo>().defaultBranch
val workflowRunsUrl = "$API_URL/actions/workflows/ci.yml/runs?branch=$branch&event=push&status=success&per_page=1"
val workflowRun = ghStatement(workflowRunsUrl).executeAndParseAs<GithubWorkflowRuns>().workflowRuns[0]
val shortSha = workflowRun.headSha.take(7)
val branch = statement(API_URL).executeAndParseAs<Repository>().defaultBranch
val run = statement("$API_URL/actions/runs?event=push&status=success&ref=refs/heads/$branch").executeAndParseAs<WorkflowRuns>().workflowRuns[0]
val shortSha = run.headSha.take(7)
if (shortSha != curSha) {
val artifacts = ghStatement(workflowRun.artifactsUrl).executeAndParseAs<GithubArtifacts>()
val archiveUrl = artifacts.getDownloadLink()
val artifacts = statement("$API_URL/actions/runs/${run.id}/artifacts").executeAndParseAs<Artifacts>()
val archiveUrl = artifacts.downloadLink
val changelog = runSuspendCatching {
val commitComparisonUrl = "$API_URL/compare/$curSha...$shortSha"
val result = ghStatement(commitComparisonUrl).executeAndParseAs<GithubCommitComparison>()
val result = statement(commitComparisonUrl).executeAndParseAs<CommitComparison>()
// TODO: Prettier format, Markdown?
result.commits.joinToString("\n") { commit ->
"${commit.commit.message.takeWhile { it != '\n' }} (@${commit.commit.author.name})"
}
}.getOrDefault(workflowRun.title)
return Release(shortSha, changelog, archiveUrl)
}.getOrDefault(run.title)
return EhRelease(shortSha, changelog, archiveUrl)
}
} else {
val curVersion = BuildConfig.RAW_VERSION_NAME
val release = ghStatement(LATEST_RELEASE_URL).executeAndParseAs<GithubRelease>()
val release = statement(LATEST_RELEASE_URL).executeAndParseAs<Release>()
val latestVersion = release.version
val description = release.info
val downloadUrl = release.getDownloadLink()
if (latestVersion != curVersion) {
return Release(latestVersion, description, downloadUrl)
return EhRelease(latestVersion, description, downloadUrl)
}
}
}
@@ -77,7 +74,7 @@ object AppUpdater {
timeoutBySpeed(
url,
{
ghStatement(url) {
statement(url) {
// https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#get-a-release-asset
if (!isZip) accept(ContentType.Application.OctetStream)
it()
@@ -100,22 +97,14 @@ object AppUpdater {
}
}
private suspend inline fun ghStatement(
suspend inline fun statement(
url: String,
builder: HttpRequestBuilder.() -> Unit = {},
) = ktorClient.prepareGet(url) {
bearerAuth(GithubTokenParts.joinToString("_"))
apply(builder)
}
private val GithubTokenParts = arrayOf(
"github",
"pat",
"11A4H2ACI0iGDuL1O6wPYW",
"OTFg8xaCNUwR1NHaJE1AT3LoYPfz6bouI7E7ReLf8GjIRFHCL5UsHL9EnWP",
)
data class Release(
data class EhRelease(
val version: String,
val changelog: String,
val downloadLink: String,
@@ -39,13 +39,11 @@ object AppConfig {
private const val CRASH = "crash"
private const val TAG_TRANSLATIONS = "tag-translations"
private val abi = Build.SUPPORTED_ABIS[0].takeIf {
it in setOf("arm64-v8a", "x86_64", "armeabi-v7a")
} ?: "universal"
private val abi = Build.SUPPORTED_ABIS[0].takeIf { it in ["arm64-v8a", "x86_64", "armeabi-v7a"] } ?: "universal"
val isBenchmark = "nonMinified" in BuildConfig.BUILD_TYPE || "benchmark" in BuildConfig.BUILD_TYPE
fun matchVariant(name: String) = name.contains(BuildConfig.FLAVOR) && name.contains(abi)
fun matchVariant(name: String) = abi in name
val commitTime = ParserUtils.formatDate(BuildConfig.COMMIT_TIME * 1000)
@@ -0,0 +1,15 @@
package tachiyomi.data.release
import kotlinx.serialization.Serializable
@Serializable
data class CommitComparison(val commits: List<Commit>)
@Serializable
data class Commit(val commit: CommitDetail)
@Serializable
data class CommitDetail(val author: CommitAuthor, val message: String)
@Serializable
data class CommitAuthor(val name: String)
@@ -1,15 +0,0 @@
package tachiyomi.data.release
import kotlinx.serialization.Serializable
@Serializable
data class GithubCommitComparison(val commits: List<GithubCommit>)
@Serializable
data class GithubCommit(val commit: GithubCommitDetail)
@Serializable
data class GithubCommitDetail(val author: GithubCommitAuthor, val message: String)
@Serializable
data class GithubCommitAuthor(val name: String)
@@ -1,40 +0,0 @@
package tachiyomi.data.release
import com.hippo.ehviewer.util.AppConfig
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class GithubRepo(
@SerialName("default_branch") val defaultBranch: String,
)
@Serializable
data class GithubWorkflowRuns(
@SerialName("workflow_runs") val workflowRuns: List<GithubWorkflowRun>,
)
@Serializable
data class GithubWorkflowRun(
@SerialName("head_sha") val headSha: String,
@SerialName("display_title") val title: String,
@SerialName("artifacts_url") val artifactsUrl: String,
)
@Serializable
data class GithubArtifacts(
@SerialName("artifacts") val artifacts: List<GithubArtifact>,
) {
fun getDownloadLink(): String {
// The default order is upload order, so we need to sort it
return artifacts.sortedBy { it.name }.run {
find { AppConfig.matchVariant(it.name) } ?: this[0]
}.downloadLink
}
}
@Serializable
data class GithubArtifact(
val name: String,
@SerialName("archive_download_url") val downloadLink: String,
)
@@ -4,15 +4,12 @@ import com.hippo.ehviewer.util.AppConfig
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Contains information about the latest release from GitHub.
*/
@Serializable
data class GithubRelease(
data class Release(
@SerialName("tag_name") val version: String,
@SerialName("body") val info: String,
@SerialName("html_url") val releaseLink: String,
@SerialName("assets") val assets: List<GitHubAssets>,
@SerialName("assets") val assets: List<Assets>,
) {
fun getDownloadLink(): String {
val asset = assets.find { AppConfig.matchVariant(it.name) } ?: assets[0]
@@ -20,8 +17,10 @@ data class GithubRelease(
}
}
/**
* Assets class containing download url.
*/
@Serializable
data class GitHubAssets(val url: String, val name: String)
data class Assets(
@SerialName("browser_download_url")
val url: String,
val name: String,
)
@@ -0,0 +1,31 @@
package tachiyomi.data.release
import com.ehviewer.core.util.unreachable
import com.hippo.ehviewer.util.AppConfig
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Repository(@SerialName("default_branch") val defaultBranch: String)
@Serializable
data class WorkflowRuns(@SerialName("workflow_runs") val workflowRuns: List<WorkflowRun>)
@Serializable
data class WorkflowRun(
@SerialName("commit_sha") val headSha: String,
@SerialName("title") val title: String,
@SerialName("id") val id: Int,
)
typealias Artifacts = List<Artifact>
val Artifacts.downloadLink
get() = (find { AppConfig.matchVariant(it.name) } ?: unreachable()).downloadLink
@Serializable
data class Artifact(
val name: String,
@SerialName("archive_download_url")
val downloadLink: String,
)