Deploy via CI.
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy-playstore:
|
||||||
|
name: Build & Deploy to Play Store
|
||||||
|
runs-on: self-hosted
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Prepare Keystore
|
||||||
|
env:
|
||||||
|
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||||
|
run: |
|
||||||
|
if [ -n "$ANDROID_KEYSTORE_BASE64" ]; then
|
||||||
|
echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > android/app/upload-keystore.jks
|
||||||
|
else
|
||||||
|
echo "Error: ANDROID_KEYSTORE_BASE64 secret is not set."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build App Bundle
|
||||||
|
env:
|
||||||
|
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||||
|
run: nix develop --command task build-android-bundle
|
||||||
|
|
||||||
|
# Placeholder for Play Store upload.
|
||||||
|
# Once you have the Service Account JSON and everything is ready,
|
||||||
|
# you can uncomment this or use a specialized action.
|
||||||
|
# - name: Upload to Play Store
|
||||||
|
# env:
|
||||||
|
# PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }}
|
||||||
|
# run: |
|
||||||
|
# echo "$PLAY_STORE_CONFIG_JSON" > play-store-key.json
|
||||||
|
# # Example using a tool like 'fastlane supply' or a dedicated flutter package
|
||||||
|
# # nix develop --command fvm flutter pub run ...
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
IMAP/SMTP email client written in [Flutter](https://flutter.dev).
|
IMAP/SMTP email client written in [Flutter](https://flutter.dev).
|
||||||
|
|
||||||
Targets **Android, iOS, and Desktop** (Linux done; macOS, Windows, Android, iOS scaffolded).
|
Targets **Android, iOS, and Desktop** (Linux done; macOS, Windows, Android, iOS scaffolded).
|
||||||
Supports **multiple accounts** — each synced independently via IMAP IDLE.
|
Supports **multiple accounts** — each synced independently via IMAP IDLE.
|
||||||
|
|
||||||
## Design philosophy: offline-first
|
## Design philosophy: offline-first
|
||||||
@@ -41,9 +41,9 @@ The UI never touches the network. The sync engine runs in the background and wri
|
|||||||
|
|
||||||
## For users
|
## For users
|
||||||
|
|
||||||
Download the latest release from the [Releases page](https://github.com/guettli/sharedinbox3/releases) *(not yet published)*.
|
Run the app, tap **+**, and enter your IMAP/SMTP server details. The app syncs your INBOX in the
|
||||||
|
background using IMAP IDLE and works offline — the network is only needed during initial sync and
|
||||||
Run the app, tap **+**, and enter your IMAP/SMTP server details. The app syncs your INBOX in the background using IMAP IDLE and works offline — the network is only needed during initial sync and when sending mail.
|
when sending mail.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -268,6 +268,19 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- ANDROID_HOME=${ANDROID_HOME:-$HOME/Android/Sdk} fvm flutter build apk --release --no-pub | grep -Ev "was tree-shaken|Tree-shaking can be disabled"
|
- ANDROID_HOME=${ANDROID_HOME:-$HOME/Android/Sdk} fvm flutter build apk --release --no-pub | grep -Ev "was tree-shaken|Tree-shaking can be disabled"
|
||||||
|
|
||||||
|
build-android-bundle:
|
||||||
|
desc: Build a release App Bundle (AAB)
|
||||||
|
deps: [_preflight, _android-sdk-check, _pub-get, generate-changelog]
|
||||||
|
method: timestamp
|
||||||
|
sources:
|
||||||
|
- lib/**/*.dart
|
||||||
|
- android/**/*
|
||||||
|
- pubspec.yaml
|
||||||
|
generates:
|
||||||
|
- build/app/outputs/bundle/release/app-release.aab
|
||||||
|
cmds:
|
||||||
|
- ANDROID_HOME=${ANDROID_HOME:-$HOME/Android/Sdk} fvm flutter build appbundle --release --no-pub | grep -Ev "was tree-shaken|Tree-shaking can be disabled"
|
||||||
|
|
||||||
deploy-android:
|
deploy-android:
|
||||||
desc: Build release APK and upload via scp to $ANDROID_APK_SCP_USER@$ANDROID_APK_SCP_HOST:$ANDROID_APK_SCP_PATH
|
desc: Build release APK and upload via scp to $ANDROID_APK_SCP_USER@$ANDROID_APK_SCP_HOST:$ANDROID_APK_SCP_PATH
|
||||||
deps: [check, build-android]
|
deps: [check, build-android]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.example.sharedinbox"
|
namespace = "de.sharedinbox.mua"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion = flutter.ndkVersion
|
ndkVersion = flutter.ndkVersion
|
||||||
|
|
||||||
@@ -19,9 +19,20 @@ android {
|
|||||||
jvmTarget = JavaVersion.VERSION_17.toString()
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
applicationId = "de.sharedinbox.mua"
|
||||||
applicationId = "com.example.sharedinbox"
|
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
minSdk = flutter.minSdkVersion
|
minSdk = flutter.minSdkVersion
|
||||||
@@ -32,11 +43,14 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
// Use the signing config defined above for release builds.
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
// If the keystore file exists (e.g. in CI or manually placed), sign it.
|
||||||
signingConfig = signingConfigs.getByName("debug")
|
signingConfig = if (signingConfigs.getByName("release").storeFile?.exists() == true) {
|
||||||
// Minification is disabled: R8 strips plugin classes (flutter_secure_storage,
|
signingConfigs.getByName("release")
|
||||||
// sqlite3) that are needed at runtime, causing an immediate crash on launch.
|
} else {
|
||||||
|
signingConfigs.getByName("debug")
|
||||||
|
}
|
||||||
|
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
isShrinkResources = false
|
isShrinkResources = false
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.example.sharedinbox
|
package de.sharedinbox.mua
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
@@ -135,10 +135,10 @@ cd "$ROOT"
|
|||||||
|
|
||||||
# Clear any leftover app state from previous runs (stale DB, cached APK process).
|
# Clear any leftover app state from previous runs (stale DB, cached APK process).
|
||||||
# Only run if the package is installed — that way any failure is a real error.
|
# Only run if the package is installed — that way any failure is a real error.
|
||||||
if "$ADB" -s "$EMULATOR_ID" shell pm list packages | grep -qF "com.example.sharedinbox"; then
|
if "$ADB" -s "$EMULATOR_ID" shell pm list packages | grep -qF "de.sharedinbox.mua"; then
|
||||||
"$ADB" -s "$EMULATOR_ID" shell am force-stop com.example.sharedinbox
|
"$ADB" -s "$EMULATOR_ID" shell am force-stop de.sharedinbox.mua
|
||||||
"$ADB" -s "$EMULATOR_ID" shell pm clear com.example.sharedinbox
|
"$ADB" -s "$EMULATOR_ID" shell pm clear de.sharedinbox.mua
|
||||||
"$ADB" -s "$EMULATOR_ID" uninstall com.example.sharedinbox
|
"$ADB" -s "$EMULATOR_ID" uninstall de.sharedinbox.mua
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ts "flutter test start"
|
ts "flutter test start"
|
||||||
|
|||||||
Reference in New Issue
Block a user