diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9baa71a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,15 @@ +LICENSE.md +README.md +analysis_options.yaml +android +assets +build +build.sh +data +docker +fastlane +lib +pubspec.lock +pubspec.yaml +sign.sh +test diff --git a/.flutter b/.flutter index ea121f8..fcf2c11 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit ea121f8859e4b13e47a8f845e4586164519588bc +Subproject commit fcf2c11572af6f390246c056bc905eca609533a0 diff --git a/.github/workflows/fastlane.yml b/.github/workflows/fastlane.yml new file mode 100644 index 0000000..b88c5eb --- /dev/null +++ b/.github/workflows/fastlane.yml @@ -0,0 +1,16 @@ +name: Validate Fastlane metadata + +on: + workflow_dispatch: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + go: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Validate Fastlane Supply Metadata + uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22362c2..d767af9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' # See 'Supported distributions' for available options - java-version: '17' + java-version: '21' - name: Flutter Doctor id: flutter_doctor @@ -44,7 +44,7 @@ jobs: - name: Build APKs run: | - sed -i 's/signingConfig signingConfigs.release//g' android/app/build.gradle + sed -i 's/signingConfig = signingConfigs.getByName("release")//g' android/app/build.gradle.kts flutter build apk --flavor normal && flutter build apk --split-per-abi --flavor normal for file in build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done flutter build apk --flavor fdroid -t lib/main_fdroid.dart && flutter build apk --split-per-abi --flavor fdroid -t lib/main_fdroid.dart diff --git a/.gitignore b/.gitignore index 12e500c..0349890 100644 --- a/.gitignore +++ b/.gitignore @@ -48,4 +48,5 @@ app.*.map.json /android/app/.cxx # Custom -TODO.txt \ No newline at end of file +TODO.txt +data \ No newline at end of file diff --git a/README.md b/README.md index 6518041..229979b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -#  Obtainium +
-[](https://techforpalestine.org/learn-more) +#  Obtainium Get Android app updates straight from the source. @@ -31,6 +31,7 @@ Currently supported App sources: - [Huawei AppGallery](https://appgallery.huawei.com/) - [Tencent App Store](https://sj.qq.com/) - [CoolApk](https://coolapk.com/) + - [vivo App Store (CN)](https://h5.appstore.vivo.com.cn/) - [RuStore](https://rustore.ru/) - Jenkins Jobs - [APKMirror](https://apkmirror.com/) (Track-Only) @@ -62,7 +63,7 @@ Or, contribute some configurations to the website by creating a PR at [this repo Verification info: - Package ID: `dev.imranr.obtainium` -- SHA-256 Hash of Signing Certificate: `B3:53:60:1F:6A:1D:5F:D6:60:3A:E2:F5:0B:E8:0C:F3:01:36:7B:86:B6:AB:8B:1F:66:24:3D:A9:6C:D5:73:62` +- SHA-256 hash of signing certificate: `B3:53:60:1F:6A:1D:5F:D6:60:3A:E2:F5:0B:E8:0C:F3:01:36:7B:86:B6:AB:8B:1F:66:24:3D:A9:6C:D5:73:62` - Note: The above signature is also valid for the F-Droid flavour of Obtainium, thanks to [reproducible builds](https://f-droid.org/docs/Reproducible_Builds/). - [PGP Public Key](https://keyserver.ubuntu.com/pks/lookup?search=contact%40imranr.dev&fingerprint=on&op=index) (to verify APK hashes) diff --git a/android/app/build.gradle b/android/app/build.gradle deleted file mode 100644 index d6c5d7b..0000000 --- a/android/app/build.gradle +++ /dev/null @@ -1,105 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. - id "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -def keystoreProperties = new Properties() -def keystorePropertiesFile = rootProject.file('key.properties') -if (keystorePropertiesFile.exists()) { - keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) -} - -android { - namespace = "dev.imranr.obtainium" - compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8 - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId = "dev.imranr.obtainium" - // You can update the following values to match your application needs. - // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = 24 - targetSdk = flutter.targetSdkVersion - versionCode = flutter.versionCode - versionName = flutter.versionName - } - - flavorDimensions "flavor" - - productFlavors { - normal { - dimension "flavor" - applicationIdSuffix "" - } - fdroid { - dimension "flavor" - applicationIdSuffix ".fdroid" - } - } - - signingConfigs { - release { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] - } - } - - buildTypes { - release { - signingConfig signingConfigs.release - } - debug { - applicationIdSuffix = ".debug" - versionNameSuffix = "-debug" - } - } -} - -flutter { - source = "../.." -} - -ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3] -import com.android.build.OutputFile -android.applicationVariants.all { variant -> - variant.outputs.each { output -> - def abiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) - if (abiVersionCode != null) { - output.versionCodeOverride = variant.versionCode * 10 + abiVersionCode - } else { - output.versionCodeOverride = variant.versionCode * 10 - } - } -} \ No newline at end of file diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts new file mode 100644 index 0000000..a684a7f --- /dev/null +++ b/android/app/build.gradle.kts @@ -0,0 +1,107 @@ +import java.io.FileInputStream +import java.util.Properties +import com.android.build.api.variant.FilterConfiguration.FilterType.* + +plugins { + id("com.android.application") + id("kotlin-android") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +val localProperties = Properties() +val localPropertiesFile = rootProject.file("local.properties") +if (localPropertiesFile.exists()) { + localPropertiesFile.reader(Charsets.UTF_8).use { reader -> + localProperties.load(reader) + } +} + +var flutterVersionCode = localProperties.getProperty("flutter.versionCode") ?: "1" +var flutterVersionName = localProperties.getProperty("flutter.versionName") ?: "1.0" + +val keystoreProperties = Properties() +val keystorePropertiesFile = rootProject.file("key.properties") +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(FileInputStream(keystorePropertiesFile)) +} + +android { + namespace = "dev.imranr.obtainium" + compileSdk = flutter.compileSdkVersion + ndkVersion = "27.0.12077973" // 'flutter.ndkVersion' produces warnings (TODO can/should we switch back?) + + compileOptions { + isCoreLibraryDesugaringEnabled = true + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11.toString() + } + + defaultConfig { + applicationId = "dev.imranr.obtainium" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = 24 + targetSdk = flutter.targetSdkVersion + versionCode = flutterVersionCode.toInt() + versionName = flutterVersionName + } + + flavorDimensions("flavor") + + productFlavors { + create("normal") { + dimension = "flavor" + applicationIdSuffix = "" + } + create("fdroid") { + dimension = "flavor" + applicationIdSuffix = ".fdroid" + } + } + + signingConfigs { + create("release") { + keyAlias = keystoreProperties["keyAlias"].toString() + keyPassword = keystoreProperties["keyPassword"].toString() + storeFile = keystoreProperties["storeFile"]?.let { file(it) } + storePassword = keystoreProperties["storePassword"].toString() + } + } + + buildTypes { + getByName("release") { + signingConfig = signingConfigs.getByName("release") + } + getByName("debug") { + applicationIdSuffix = ".debug" + versionNameSuffix = "-debug" + } + } +} + +val abiCodes = mapOf("x86_64" to 1, "armeabi-v7a" to 2, "arm64-v8a" to 3) + +androidComponents { + onVariants { variant -> + variant.outputs.forEach { output -> + val name = output.filters.find { it.filterType == ABI }?.identifier + val baseAbiCode = abiCodes[name] ?: 0 + if (baseAbiCode != null) { + output.versionCode.set(baseAbiCode + ((output.versionCode.get() ?: 0) * 10)) + } + } + } +} + +dependencies { + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") +} + +flutter { + source = "../.." +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d461e3b..0bd0614 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -61,6 +61,13 @@ android:enabled="true" android:exported="true" android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" /> +