diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index cde86f17a..d44234ef4 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -54,9 +54,6 @@ jobs: - name: Spotless Check run: ./gradlew spotlessCheck - - name: Lint Check - run: ./gradlew lintDefaultRelease - default: runs-on: nekomoee steps: diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e6d90db18..17ddf0cea 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -47,9 +47,9 @@ 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") @@ -65,7 +65,7 @@ android { 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) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AboutScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AboutScreen.kt index 55d0ad5ec..3c8762137 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AboutScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AboutScreen.kt @@ -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, diff --git a/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt b/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt index 8c4082860..a7ade1c53 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt @@ -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().defaultBranch - val workflowRunsUrl = "$API_URL/actions/workflows/ci.yml/runs?branch=$branch&event=push&status=success&per_page=1" - val workflowRun = ghStatement(workflowRunsUrl).executeAndParseAs().workflowRuns[0] - val shortSha = workflowRun.headSha.take(7) + val branch = statement(API_URL).executeAndParseAs().defaultBranch + val run = statement("$API_URL/actions/runs?event=push&status=success&ref=refs/heads/$branch").executeAndParseAs().workflowRuns[0] + val shortSha = run.headSha.take(7) if (shortSha != curSha) { - val artifacts = ghStatement(workflowRun.artifactsUrl).executeAndParseAs() - val archiveUrl = artifacts.getDownloadLink() + val artifacts = statement("$API_URL/actions/runs/${run.id}/artifacts").executeAndParseAs() + val archiveUrl = artifacts.downloadLink val changelog = runSuspendCatching { val commitComparisonUrl = "$API_URL/compare/$curSha...$shortSha" - val result = ghStatement(commitComparisonUrl).executeAndParseAs() + val result = statement(commitComparisonUrl).executeAndParseAs() // 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() + val release = statement(LATEST_RELEASE_URL).executeAndParseAs() 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, diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt index 6419b6597..47f5b47bb 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt @@ -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) diff --git a/app/src/main/kotlin/tachiyomi/data/release/Commit.kt b/app/src/main/kotlin/tachiyomi/data/release/Commit.kt new file mode 100644 index 000000000..f1104152d --- /dev/null +++ b/app/src/main/kotlin/tachiyomi/data/release/Commit.kt @@ -0,0 +1,15 @@ +package tachiyomi.data.release + +import kotlinx.serialization.Serializable + +@Serializable +data class CommitComparison(val commits: List) + +@Serializable +data class Commit(val commit: CommitDetail) + +@Serializable +data class CommitDetail(val author: CommitAuthor, val message: String) + +@Serializable +data class CommitAuthor(val name: String) diff --git a/app/src/main/kotlin/tachiyomi/data/release/GithubCommit.kt b/app/src/main/kotlin/tachiyomi/data/release/GithubCommit.kt deleted file mode 100644 index 0f8ddb543..000000000 --- a/app/src/main/kotlin/tachiyomi/data/release/GithubCommit.kt +++ /dev/null @@ -1,15 +0,0 @@ -package tachiyomi.data.release - -import kotlinx.serialization.Serializable - -@Serializable -data class GithubCommitComparison(val commits: List) - -@Serializable -data class GithubCommit(val commit: GithubCommitDetail) - -@Serializable -data class GithubCommitDetail(val author: GithubCommitAuthor, val message: String) - -@Serializable -data class GithubCommitAuthor(val name: String) diff --git a/app/src/main/kotlin/tachiyomi/data/release/GithubWorkflow.kt b/app/src/main/kotlin/tachiyomi/data/release/GithubWorkflow.kt deleted file mode 100644 index 855f92ee4..000000000 --- a/app/src/main/kotlin/tachiyomi/data/release/GithubWorkflow.kt +++ /dev/null @@ -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, -) - -@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, -) { - 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, -) diff --git a/app/src/main/kotlin/tachiyomi/data/release/GithubRelease.kt b/app/src/main/kotlin/tachiyomi/data/release/Release.kt similarity index 64% rename from app/src/main/kotlin/tachiyomi/data/release/GithubRelease.kt rename to app/src/main/kotlin/tachiyomi/data/release/Release.kt index fb28f0caf..4b8ea5dbd 100644 --- a/app/src/main/kotlin/tachiyomi/data/release/GithubRelease.kt +++ b/app/src/main/kotlin/tachiyomi/data/release/Release.kt @@ -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, + @SerialName("assets") val assets: List, ) { 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, +) diff --git a/app/src/main/kotlin/tachiyomi/data/release/Workflow.kt b/app/src/main/kotlin/tachiyomi/data/release/Workflow.kt new file mode 100644 index 000000000..a3fe0cf6d --- /dev/null +++ b/app/src/main/kotlin/tachiyomi/data/release/Workflow.kt @@ -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) + +@Serializable +data class WorkflowRun( + @SerialName("commit_sha") val headSha: String, + @SerialName("title") val title: String, + @SerialName("id") val id: Int, +) + +typealias Artifacts = List + +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, +)