diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index a9d480c0272..561e0a0d924 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -14,6 +14,9 @@ jobs: distribution: temurin java-version: 17 + - name: Set up Android SDK + uses: android-actions/setup-android@v3 + - name: Grant execute permission for gradlew run: chmod +x gradlew @@ -23,11 +26,76 @@ jobs: cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} cache-read-only: false + - name: Build dokka + run: ./gradlew docs:dokkaGeneratePublicationHtml + - name: Run Gradle - run: ./gradlew assemblePrereleaseDebug lint + run: ./gradlew assemblePrereleaseRelease androidSourcesJar makeJar - name: Upload Artifact uses: actions/upload-artifact@v6 with: name: pull-request-build - path: "app/build/outputs/apk/prerelease/debug/*.apk" + path: | + app/build/outputs/apk/prerelease/debug/*.apk + app/build/outputs/apk/prerelease/release/*.apk + app/build/libs/app-sources.jar + app/build/classes.jar + library/build/libs/library-*-sources.jar + + - name: Stage Reports + Dokka for GitHub Pages + run: | + BRANCH_NAME=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}} + TARGET_DIR=gh-pages/$BRANCH_NAME + + mkdir -p "$TARGET_DIR" + + if [ -d "build/reports" ]; then + mkdir -p "$TARGET_DIR/reports" + cp -r build/reports/. "$TARGET_DIR/reports/" + fi + + for REPORT_DIR in */build/reports; do + if [ -d "$REPORT_DIR" ]; then + mkdir -p "$TARGET_DIR/reports/$REPORT_DIR" + cp -r "$REPORT_DIR/." "$TARGET_DIR/reports/$REPORT_DIR/" + fi + done + + if [ -d "docs/build/dokka/html" ]; then + mkdir -p "$TARGET_DIR/dokka" + cp -r docs/build/dokka/html/. "$TARGET_DIR/dokka/" + fi + + INDEX_FILE="$TARGET_DIR/index.html" + echo " + + + + Artifacts for $BRANCH_NAME + + +

Artifacts for branch $BRANCH_NAME

+ + + " >> "$INDEX_FILE" + shell: bash + + - name: Push to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./gh-pages + user_name: "github-actions" + user_email: "github-actions@github.com" + commit_message: "Update reports + dokka for ${{ github.head_ref }} [ci skip]" diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 41e8fc0a01a..85c0ff5c469 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,4 +1,5 @@ import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties +import com.android.build.gradle.tasks.MergeSourceSetFolders import org.jetbrains.dokka.gradle.engine.parameters.KotlinPlatform import org.jetbrains.dokka.gradle.engine.parameters.VisibilityModifier import org.jetbrains.kotlin.gradle.dsl.JvmDefaultMode @@ -8,30 +9,48 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile plugins { alias(libs.plugins.android.application) alias(libs.plugins.dokka) - alias(libs.plugins.kotlin.android) } val javaTarget = JvmTarget.fromTarget(libs.versions.jvmTarget.get()) -val tmpFilePath = System.getProperty("user.home") + "/work/_temp/keystore/" -val prereleaseStoreFile: File? = File(tmpFilePath).listFiles()?.first() - -fun getGitCommitHash(): String { - return try { - val headFile = file("${project.rootDir}/.git/HEAD") - - // Read the commit hash from .git/HEAD - if (headFile.exists()) { - val headContent = headFile.readText().trim() - if (headContent.startsWith("ref:")) { - val refPath = headContent.substring(5) // e.g., refs/heads/main - val commitFile = file("${project.rootDir}/.git/$refPath") - if (commitFile.exists()) commitFile.readText().trim() else "" - } else headContent // If it's a detached HEAD (commit hash directly) - } else { - "" // If .git/HEAD doesn't exist - }.take(7) // Return the short commit hash - } catch (_: Throwable) { - "" // Just return an empty string if any exception occurs + +tasks.register("generateGitHash") { + val gitHashDir = layout.buildDirectory.dir("generated/git") + val rootDir = project.rootDir + outputs.dir(gitHashDir) + + doLast { + val hash = try { + // Read the commit hash from .git/HEAD + val headFile = File(rootDir, ".git/HEAD") + if (headFile.exists()) { + val headContent = headFile.readText().trim() + if (headContent.startsWith("ref:")) { + val refPath = headContent.substring(5) // e.g., refs/heads/main + val commitFile = File(rootDir, ".git/$refPath") + if (commitFile.exists()) commitFile.readText().trim() else "" + } else headContent // If it's a detached HEAD (commit hash directly) + } else "" // If .git/HEAD doesn't exist + } catch (_: Throwable) { + "" // Just set to an empty string if any exception occurs + }.take(7) // Get the short commit hash + + val outFile = gitHashDir.get().file("git-hash.txt").asFile + outFile.parentFile.mkdirs() + outFile.writeText(hash) + } +} + +tasks.withType { + if (name.contains("Assets", ignoreCase = true)) { + dependsOn("generateGitHash") + val gitHashDir = layout.buildDirectory.dir("generated/git") + + doLast { + val assetsDir = outputs.files.singleFile + val gitHashFile = gitHashDir.get().file("git-hash.txt").asFile + val outFile = File(assetsDir, "git-hash.txt") + gitHashFile.copyTo(outFile, overwrite = true) + } } } @@ -46,9 +65,14 @@ android { } signingConfigs { - if (prereleaseStoreFile != null) { + // We just use SIGNING_KEY_ALIAS here since it won't change + // so won't kill the configuration cache. + if (System.getenv("SIGNING_KEY_ALIAS") != null) { create("prerelease") { - storeFile = file(prereleaseStoreFile) + val tmpFilePath = System.getProperty("user.home") + "/work/_temp/keystore/" + val prereleaseStoreFile: File? = File(tmpFilePath).listFiles()?.first() + + storeFile = prereleaseStoreFile?.let { file(it) } storePassword = System.getenv("SIGNING_STORE_PASSWORD") keyAlias = System.getenv("SIGNING_KEY_ALIAS") keyPassword = System.getenv("SIGNING_KEY_PASSWORD") @@ -65,8 +89,6 @@ android { versionCode = 67 versionName = "4.6.2" - resValue("string", "commit_hash", getGitCommitHash()) - manifestPlaceholders["target_sdk_version"] = libs.versions.targetSdk.get() // Reads local.properties @@ -135,21 +157,19 @@ android { } java { - // Use Java 17 toolchain even if a higher JDK runs the build. + // Use Java 17 toolchain even if a higher JDK runs the build. // We still use Java 8 for now which higher JDKs have deprecated. - toolchain { - languageVersion.set(JavaLanguageVersion.of(libs.versions.jdkToolchain.get())) - } + toolchain { + languageVersion.set(JavaLanguageVersion.of(libs.versions.jdkToolchain.get())) + } } lint { - abortOnError = false checkReleaseBuilds = false } buildFeatures { buildConfig = true - resValues = true } namespace = "com.lagradost.cloudstream3" @@ -272,8 +292,10 @@ tasks.withType { dokka { moduleName = "App" dokkaSourceSets { - main { + configureEach { + suppress = name != "prereleaseDebug" analysisPlatform = KotlinPlatform.JVM + displayName = "JVM" documentedVisibilities( VisibilityModifier.Public, VisibilityModifier.Protected diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt index 097eb2c600b..e41109b5982 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt @@ -27,6 +27,7 @@ import com.lagradost.cloudstream3.ui.settings.Globals.TV import com.lagradost.cloudstream3.ui.settings.Globals.isLandscape import com.lagradost.cloudstream3.ui.settings.Globals.isLayout import com.lagradost.cloudstream3.utils.DataStoreHelper +import com.lagradost.cloudstream3.utils.GitInfo.currentCommitHash import com.lagradost.cloudstream3.utils.ImageLoader.loadImage import com.lagradost.cloudstream3.utils.UIHelper.clipboardHelper import com.lagradost.cloudstream3.utils.UIHelper.fixSystemBarsPadding @@ -247,7 +248,7 @@ class SettingsFragment : BaseFragment( } val appVersion = BuildConfig.VERSION_NAME - val commitInfo = getString(R.string.commit_hash) + val commitHash = activity?.currentCommitHash() ?: "" val buildTimestamp = SimpleDateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.getDefault() ).apply { timeZone = TimeZone.getTimeZone("UTC") @@ -255,8 +256,9 @@ class SettingsFragment : BaseFragment( binding.appVersion.text = appVersion binding.buildDate.text = buildTimestamp + binding.commitHash.text = commitHash binding.appVersionInfo.setOnLongClickListener { - clipboardHelper(txt(R.string.extension_version), "$appVersion $commitInfo $buildTimestamp") + clipboardHelper(txt(R.string.extension_version), "$appVersion $commitHash $buildTimestamp") true } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/GitInfo.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/GitInfo.kt new file mode 100644 index 00000000000..58ff44bb257 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/GitInfo.kt @@ -0,0 +1,20 @@ +package com.lagradost.cloudstream3.utils + +import android.content.Context + +/** + * Simple helper to get the short commit hash from assets. + * The hash is generated at build and stored as an asset + * that can be accessed at runtime for Gradle + * configuration cache support. + */ +object GitInfo { + fun Context.currentCommitHash(): String = try { + assets.open("git-hash.txt") + .bufferedReader() + .readText() + .trim() + } catch (_: Exception) { + "" + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt index 057923eb05a..9380285ca44 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt @@ -24,6 +24,7 @@ import com.lagradost.cloudstream3.services.PackageInstallerService import com.lagradost.cloudstream3.utils.AppContextUtils.setDefaultFocus import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.Coroutines.ioSafe +import com.lagradost.cloudstream3.utils.GitInfo.currentCommitHash import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import okio.BufferedSink @@ -170,7 +171,7 @@ object InAppUpdater { Log.d(LOG_TAG, "Fetched GitHub tag: $updateCommitHash") return Update( - getString(R.string.commit_hash) != updateCommitHash, + currentCommitHash() != updateCommitHash, foundAsset.browserDownloadUrl, updateCommitHash, found.body, diff --git a/app/src/main/res/layout/main_settings.xml b/app/src/main/res/layout/main_settings.xml index ba377455440..5c05599e828 100644 --- a/app/src/main/res/layout/main_settings.xml +++ b/app/src/main/res/layout/main_settings.xml @@ -134,8 +134,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" - android:text="@string/commit_hash" - android:textColor="?attr/textColor" /> + android:textColor="?attr/textColor" + tools:text="1234567" /> - \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index cca263dd422..e35c1f61148 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,6 @@ plugins { alias(libs.plugins.android.multiplatform.library) apply false alias(libs.plugins.buildkonfig) apply false // Universal build config alias(libs.plugins.dokka) apply false - alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.jvm) apply false alias(libs.plugins.kotlin.multiplatform) apply false } diff --git a/gradle.properties b/gradle.properties index 0168ae437bd..85ed7146560 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,3 +26,5 @@ org.gradle.configuration-cache=true # Compiling with Java 8 is deprecated but we still use it for now android.javaCompile.suppressSourceTargetDeprecationWarning=true + +org.jetbrains.dokka.analysis.enableExperimentalKDocResolution=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index afceb26dde0..5a1f309e315 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ # https://docs.gradle.org/current/userguide/dependency_versions.html#sec:strict-version [versions] activityKtx = "1.11.0" -androidGradlePlugin = "8.13.2" +androidGradlePlugin = "9.0.0" appcompat = "1.7.1" biometric = "1.4.0-alpha04" buildkonfigGradlePlugin = "0.17.1" @@ -12,7 +12,7 @@ conscryptAndroid = { strictly = "2.5.2" } # 2.5.3 crashes everything constraintlayout = "2.2.1" coreKtx = "1.17.0" desugar_jdk_libs_nio = "2.1.5" -dokkaGradlePlugin = "2.1.0" +dokkaGradlePlugin = "2.2.0-Beta" espressoCore = "3.7.0" fragmentKtx = "1.8.9" fuzzywuzzy = "1.4.0" @@ -23,7 +23,7 @@ junit = "4.13.2" junitKtx = "1.3.0" junitVersion = "1.3.0" juniversalchardet = "2.5.0" -kotlinGradlePlugin = "2.3.0" +kotlinGradlePlugin = "2.3.20-Beta1" kotlinxCoroutinesCore = "1.10.2" lifecycleKtx = "2.9.4" material = "1.14.0-alpha08" @@ -117,7 +117,6 @@ android-lint = { id = "com.android.lint", version.ref = "androidGradlePlugin" } android-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "androidGradlePlugin" } buildkonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfigGradlePlugin" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokkaGradlePlugin" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlinGradlePlugin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm" , version.ref = "kotlinGradlePlugin" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlinGradlePlugin" }