diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 1f839ce..63034ed 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -97,7 +97,7 @@ jobs: ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }} run: | - nix develop --no-warn-dirty --command dagger call --progress=plain -m ci publish-android --source . --play-store-config env:PLAY_STORE_CONFIG_JSON + nix develop --no-warn-dirty --command dagger call --progress=plain -m ci publish-android --source . --play-store-config env:PLAY_STORE_CONFIG_JSON --keystore-password env:ANDROID_KEYSTORE_PASSWORD - name: Build & Deploy APK to server continue-on-error: true @@ -108,7 +108,7 @@ jobs: ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} run: | HASH=$(git rev-parse --short HEAD) - nix develop --no-warn-dirty --command dagger call --progress=plain -m ci deploy-apk --source . --ssh-key env:SSH_PRIVATE_KEY --ssh-user "$SSH_USER" --ssh-host "$SSH_HOST" --commit-hash "$HASH" + nix develop --no-warn-dirty --command dagger call --progress=plain -m ci deploy-apk --source . --ssh-key env:SSH_PRIVATE_KEY --ssh-user "$SSH_USER" --ssh-host "$SSH_HOST" --commit-hash "$HASH" --keystore-password env:ANDROID_KEYSTORE_PASSWORD publish-website: name: Publish Website Build History diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index b1f2227..e6a9564 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -20,15 +20,18 @@ android { jvmTarget = JavaVersion.VERSION_17.toString() } - signingConfigs { - create("release") { - // Hardcoded alias matching t.sh - keyAlias = "upload" - // Use the same password for both key and keystore - val pass = System.getenv("ANDROID_KEYSTORE_PASSWORD") - storePassword = pass - keyPassword = pass - storeFile = file("upload-keystore.jks") + val keystoreFile = file("upload-keystore.jks") + val keystorePass: String? = System.getenv("ANDROID_KEYSTORE_PASSWORD") + val hasKeystore = keystoreFile.exists() && keystorePass != null + + if (hasKeystore) { + signingConfigs { + create("release") { + keyAlias = "upload" + storePassword = keystorePass + keyPassword = keystorePass + storeFile = keystoreFile + } } } @@ -44,9 +47,7 @@ android { buildTypes { release { - // Use the signing config defined above for release builds. - // If the keystore file exists (e.g. in CI or manually placed), sign it. - signingConfig = if (signingConfigs.getByName("release").storeFile?.exists() == true) { + signingConfig = if (hasKeystore) { signingConfigs.getByName("release") } else { signingConfigs.getByName("debug") diff --git a/ci/main.go b/ci/main.go index 53b6eec..fea0d6d 100644 --- a/ci/main.go +++ b/ci/main.go @@ -262,8 +262,9 @@ func (m *Ci) DeployLinux( } // Build and return the Android APK -func (m *Ci) BuildAndroidApk(source *dagger.Directory) *dagger.File { +func (m *Ci) BuildAndroidApk(source *dagger.Directory, keystorePassword *dagger.Secret) *dagger.File { return m.Setup(source). + WithSecretVariable("ANDROID_KEYSTORE_PASSWORD", keystorePassword). WithExec([]string{"flutter", "build", "apk", "--release"}). File("build/app/outputs/flutter-apk/app-release.apk") } @@ -276,9 +277,10 @@ func (m *Ci) DeployApk( sshUser string, sshHost string, commitHash string, + keystorePassword *dagger.Secret, ) (string, error) { // 1. Build the APK - apk := m.BuildAndroidApk(source) + apk := m.BuildAndroidApk(source, keystorePassword) // 2. Deploy datePath := time.Now().Format("2006/01/02") @@ -293,8 +295,9 @@ func (m *Ci) DeployApk( } // Build and return the Android App Bundle (AAB) -func (m *Ci) BuildAndroidRelease(source *dagger.Directory) *dagger.File { +func (m *Ci) BuildAndroidRelease(source *dagger.Directory, keystorePassword *dagger.Secret) *dagger.File { return m.Setup(source). + WithSecretVariable("ANDROID_KEYSTORE_PASSWORD", keystorePassword). WithExec([]string{"flutter", "build", "appbundle", "--release"}). File("build/app/outputs/bundle/release/app-release.aab") } @@ -304,9 +307,10 @@ func (m *Ci) PublishAndroid( ctx context.Context, source *dagger.Directory, playStoreConfig *dagger.Secret, + keystorePassword *dagger.Secret, ) (string, error) { // 1. Build the AAB - aab := m.BuildAndroidRelease(source) + aab := m.BuildAndroidRelease(source, keystorePassword) // 2. Prepare script source scriptSource := source.Filter(dagger.DirectoryFilterOpts{