mirror of
https://github.com/immich-app/immich.git
synced 2026-05-22 06:52:33 -04:00
8b3c9bf9c3
* feat(ci): publish PR Android APK to R2 with installable links Adds a universal debug APK to PR builds and uploads it to a public R2 bucket alongside the existing GitHub Actions artifact. Posts a sticky PR comment with tap-to-install links and a QR code so testers can install directly on their device without unzipping artifacts. Required setup: - Secrets: R2_APK_ACCESS_KEY_ID, R2_APK_SECRET_ACCESS_KEY, R2_APK_ACCOUNT_ID, R2_APK_BUCKET - Optional repo variable: APK_PUBLIC_HOST (defaults to apk.immich.app) - R2 bucket configured with a public custom domain matching APK_PUBLIC_HOST * chore(ci): drop R2 upload, link directly to GitHub artifact Surfaces the existing release-apk-signed artifact in a sticky PR comment with a QR code. Avoids new infra and secrets — the trade-off is GitHub login and a zip wrapper instead of tap-to-install. * feat(ci): build PR APK as release and publish to GitHub Release PR builds now produce a release APK signed with the release keystore. The universal APK is published as a GitHub Release asset under tag 'pr-<num>' (prerelease), giving testers a direct, unzipped, tap-to- install URL plus a QR code in the PR comment. The release-apk-signed artifact is unchanged. * chore(ci): drop GitHub Release, publish universal APK as own artifact Reverts the prerelease publish. Uploads the universal release APK as a separate single-file artifact so its download URL gives a zip containing only that APK — no extra files to dig through. The QR in the PR comment points at this universal-only artifact. * chore(ci): build only universal APK for PR, drop split artifact PR builds skip the arm64-only split — release-apk-signed now contains just the universal app-release.apk, so the download zip is a single file. Removes the redundant separate universal artifact and points the PR comment QR at the main artifact URL. * feat(mobile): suffix PR APK applicationId so it installs alongside production Each PR build now becomes app.alextran.immich.pr<num> via PR_NUMBER env read in build.gradle, so testers can install multiple PR builds and the Play Store version on the same device without uninstalling. Also tags the version with -pr<num> for visibility. * feat(ci): allow PR APK build to run on forks Forks can now run the Android build job. Steps that need repo secrets (create-workflow-token, Create Keystore) are skipped when the PR is from a fork, the checkout falls back to GITHUB_TOKEN, and build.gradle falls back to debug signing if the release keystore isn't materialised. The PR comment still requires write access, so it's gated to non-fork PRs — fork APKs are reachable from the workflow run's artifact tab.
123 lines
3.2 KiB
Groovy
123 lines
3.2 KiB
Groovy
plugins {
|
|
alias(libs.plugins.android.application)
|
|
alias(libs.plugins.kotlin.android)
|
|
id "dev.flutter.flutter-gradle-plugin"
|
|
alias(libs.plugins.ksp)
|
|
alias(libs.plugins.kotlin.serialization)
|
|
alias(libs.plugins.kotlin.compose)
|
|
}
|
|
|
|
def keystoreProperties = new Properties()
|
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
|
if (keystorePropertiesFile.exists()) {
|
|
keystorePropertiesFile.withInputStream { keystoreProperties.load(it) }
|
|
}
|
|
|
|
android {
|
|
compileSdk = flutter.compileSdkVersion
|
|
ndkVersion = flutter.ndkVersion
|
|
|
|
compileOptions {
|
|
sourceCompatibility JavaVersion.VERSION_17
|
|
targetCompatibility JavaVersion.VERSION_17
|
|
coreLibraryDesugaringEnabled true
|
|
}
|
|
|
|
kotlinOptions {
|
|
jvmTarget = '17'
|
|
}
|
|
|
|
sourceSets {
|
|
main.java.srcDirs += 'src/main/kotlin'
|
|
}
|
|
|
|
buildFeatures {
|
|
buildConfig true
|
|
compose true
|
|
}
|
|
|
|
defaultConfig {
|
|
applicationId "app.alextran.immich"
|
|
minSdk = 26
|
|
targetSdk = flutter.targetSdkVersion
|
|
versionCode flutter.versionCode
|
|
versionName flutter.versionName
|
|
}
|
|
|
|
signingConfigs {
|
|
release {
|
|
def keyAliasVal = System.getenv("ALIAS")
|
|
def keyPasswordVal = System.getenv("ANDROID_KEY_PASSWORD")
|
|
def storePasswordVal = System.getenv("ANDROID_STORE_PASSWORD")
|
|
|
|
keyAlias keyAliasVal ?: keystoreProperties['keyAlias']
|
|
keyPassword keyPasswordVal ?: keystoreProperties['keyPassword']
|
|
storeFile file("../key.jks").exists() ? file("../key.jks") : file(keystoreProperties['storeFile'] ?: '../key.jks')
|
|
storePassword storePasswordVal ?: keystoreProperties['storePassword']
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
applicationIdSuffix '.debug'
|
|
versionNameSuffix '-DEBUG'
|
|
}
|
|
|
|
release {
|
|
def hasKeystore = file("../key.jks").exists() && file("../key.jks").length() > 0
|
|
signingConfig hasKeystore ? signingConfigs.release : signingConfigs.debug
|
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
|
|
|
def prNumber = System.getenv("PR_NUMBER")
|
|
if (prNumber) {
|
|
applicationIdSuffix ".pr${prNumber}"
|
|
versionNameSuffix "-pr${prNumber}"
|
|
}
|
|
}
|
|
}
|
|
namespace 'app.alextran.immich'
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
path "CMakeLists.txt"
|
|
}
|
|
}
|
|
}
|
|
|
|
flutter {
|
|
source '../..'
|
|
}
|
|
|
|
dependencies {
|
|
implementation libs.okhttp
|
|
implementation libs.cronet.embedded
|
|
implementation libs.media3.datasource.okhttp
|
|
implementation libs.media3.datasource.cronet
|
|
implementation libs.kotlinx.coroutines.android
|
|
implementation libs.work.runtime.ktx
|
|
implementation libs.concurrent.futures
|
|
implementation libs.guava
|
|
implementation libs.glide
|
|
implementation libs.kotlinx.serialization.json
|
|
|
|
ksp libs.glide.ksp
|
|
coreLibraryDesugaring libs.desugar.jdk.libs
|
|
|
|
//Glance Widget
|
|
implementation libs.glance.appwidget
|
|
implementation libs.gson
|
|
|
|
// Glance Configure
|
|
implementation libs.activity.compose
|
|
implementation libs.compose.ui
|
|
implementation libs.compose.ui.tooling
|
|
implementation libs.compose.material3
|
|
implementation libs.lifecycle.runtime.ktx
|
|
implementation libs.material
|
|
}
|
|
|
|
// This is uncommented in F-Droid build script
|
|
//f configurations.all {
|
|
//f exclude group: 'com.google.android.gms'
|
|
//f }
|