Skip to content

Commit f59eaa3

Browse files
committed
2 parents 24a8399 + 2957f11 commit f59eaa3

3 files changed

Lines changed: 101 additions & 13 deletions

File tree

.github/workflows/android-release.yml

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ env:
1111
jobs:
1212
build-android:
1313
runs-on: ubuntu-latest
14+
environment: production
1415
env:
1516
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
1617
steps:
@@ -63,11 +64,37 @@ jobs:
6364
run: |
6465
yes | sdkmanager --licenses || true
6566
67+
- name: Setup Android Signing
68+
env:
69+
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
70+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
71+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
72+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
73+
run: |
74+
if [ -n "$KEYSTORE_BASE64" ]; then
75+
echo "$KEYSTORE_BASE64" | base64 -d > android/app/keystore.jks
76+
echo "KEYSTORE_PATH=android/app/keystore.jks" >> $GITHUB_ENV
77+
echo "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> $GITHUB_ENV
78+
echo "KEY_ALIAS=$KEY_ALIAS" >> $GITHUB_ENV
79+
echo "KEY_PASSWORD=$KEY_PASSWORD" >> $GITHUB_ENV
80+
echo "Android signing configured"
81+
else
82+
echo "No signing configuration found, using debug signature"
83+
fi
84+
6685
- name: Build Android App Bundle (AAB)
6786
run: flutter build appbundle --release --target-platform android-arm,android-arm64
6887

69-
- name: Build Android APK (debug, installable for testing)
70-
run: flutter build apk --debug
88+
- name: Build Android APK (release)
89+
run: flutter build apk --release --target-platform android-arm,android-arm64
90+
91+
- name: Verify APK Signature
92+
if: env.KEYSTORE_PATH != ''
93+
run: |
94+
echo "Verifying APK signature..."
95+
BUILD_TOOLS=$(ls -d $ANDROID_SDK_ROOT/build-tools/*/ | sort -V | tail -n 1)
96+
$BUILD_TOOLS/apksigner verify -v build/app/outputs/flutter-apk/app-release.apk || true
97+
echo "Signature verification completed"
7198
7299
- name: Prepare release metadata
73100
id: vars
@@ -95,10 +122,10 @@ jobs:
95122
else
96123
echo "AAB not found"; exit 1
97124
fi
98-
if [ -f build/app/outputs/flutter-apk/app-debug.apk ]; then
99-
cp build/app/outputs/flutter-apk/app-debug.apk "$APK_NAME"
125+
if [ -f build/app/outputs/flutter-apk/app-release.apk ]; then
126+
cp build/app/outputs/flutter-apk/app-release.apk "$APK_NAME"
100127
else
101-
echo "Debug APK not found"; exit 1
128+
echo "Release APK not found"; exit 1
102129
fi
103130
104131
- name: Upload AAB artifact
@@ -112,3 +139,9 @@ jobs:
112139
with:
113140
name: picoclaw_fui-${{ env.RELEASE_BASE }}-android-universal.apk
114141
path: picoclaw_fui-${{ env.RELEASE_BASE }}-android-universal.apk
142+
143+
- name: Cleanup signing keys
144+
if: always()
145+
run: |
146+
rm -f android/app/keystore.jks
147+
echo "Signing keys cleaned up"

.github/workflows/release_full.yml

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ env:
1414
jobs:
1515
build-android:
1616
runs-on: ubuntu-latest
17+
environment: production
1718
outputs:
1819
release_base: ${{ steps.vars.outputs.release_base }}
1920
steps:
@@ -65,17 +66,43 @@ jobs:
6566
run: |
6667
yes | sdkmanager --licenses || true
6768
69+
- name: Setup Android Signing
70+
env:
71+
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
72+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
73+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
74+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
75+
run: |
76+
if [ -n "$KEYSTORE_BASE64" ]; then
77+
echo "$KEYSTORE_BASE64" | base64 -d > android/app/keystore.jks
78+
echo "KEYSTORE_PATH=android/app/keystore.jks" >> $GITHUB_ENV
79+
echo "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> $GITHUB_ENV
80+
echo "KEY_ALIAS=$KEY_ALIAS" >> $GITHUB_ENV
81+
echo "KEY_PASSWORD=$KEY_PASSWORD" >> $GITHUB_ENV
82+
echo "Android signing configured"
83+
else
84+
echo "No signing configuration found, using debug signature"
85+
fi
86+
6887
- name: Build Android AAB, fetch/install core, and package
6988
env:
7089
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7190
run: |
7291
flutter pub run tools/fetch_core_local.dart --repo sipeed/picoclaw --tag latest --out-dir app/bin --platform android --arch arm64 --build-mode release --install-to-build
7392
74-
- name: Build Android APK (debug) and fetch/install core
93+
- name: Build Android APK (release) and fetch/install core
7594
env:
7695
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7796
run: |
78-
flutter pub run tools/fetch_core_local.dart --repo sipeed/picoclaw --tag latest --out-dir app/bin --platform android --arch arm64 --build-mode debug --install-to-build
97+
flutter pub run tools/fetch_core_local.dart --repo sipeed/picoclaw --tag latest --out-dir app/bin --platform android --arch arm64 --build-mode release --install-to-build
98+
99+
- name: Verify APK Signature
100+
if: env.KEYSTORE_PATH != ''
101+
run: |
102+
echo "Verifying APK signature..."
103+
BUILD_TOOLS=$(ls -d $ANDROID_SDK_ROOT/build-tools/*/ | sort -V | tail -n 1)
104+
$BUILD_TOOLS/apksigner verify -v build/app/outputs/flutter-apk/app-release.apk || true
105+
echo "Signature verification completed"
79106
80107
- name: Prepare release metadata
81108
id: vars
@@ -101,10 +128,10 @@ jobs:
101128
else
102129
echo "AAB not found"; exit 1
103130
fi
104-
if [ -f build/app/outputs/flutter-apk/app-debug.apk ]; then
105-
cp build/app/outputs/flutter-apk/app-debug.apk "$APK_NAME"
131+
if [ -f build/app/outputs/flutter-apk/app-release.apk ]; then
132+
cp build/app/outputs/flutter-apk/app-release.apk "$APK_NAME"
106133
else
107-
echo "Debug APK not found"; exit 1
134+
echo "Release APK not found"; exit 1
108135
fi
109136
110137
# core binaries are installed into build outputs; avoid uploading app/bin
@@ -121,6 +148,12 @@ jobs:
121148
name: picoclaw_fui-${{ env.RELEASE_BASE }}-android-universal.apk
122149
path: picoclaw_fui-${{ env.RELEASE_BASE }}-android-universal.apk
123150

151+
- name: Cleanup signing keys
152+
if: always()
153+
run: |
154+
rm -f android/app/keystore.jks
155+
echo "Signing keys cleaned up"
156+
124157
build-macos:
125158
runs-on: macos-latest
126159
needs: []

android/app/build.gradle.kts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,33 @@ android {
3131
versionName = flutter.versionName
3232
}
3333

34+
signingConfigs {
35+
create("release") {
36+
// Signing configuration loaded from environment variables
37+
// For CI/CD: set KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD as secrets
38+
val keystorePath = System.getenv("KEYSTORE_PATH") ?: ""
39+
val keystorePassword = System.getenv("KEYSTORE_PASSWORD") ?: ""
40+
val keyAlias = System.getenv("KEY_ALIAS") ?: ""
41+
val keyPassword = System.getenv("KEY_PASSWORD") ?: ""
42+
43+
if (keystorePath.isNotEmpty() && keystorePassword.isNotEmpty() &&
44+
keyAlias.isNotEmpty() && keyPassword.isNotEmpty()) {
45+
storeFile = file(keystorePath)
46+
storePassword = keystorePassword
47+
this.keyAlias = keyAlias
48+
this.keyPassword = keyPassword
49+
}
50+
}
51+
}
52+
3453
buildTypes {
3554
release {
36-
// TODO: Add your own signing config for the release build.
37-
// Signing with the debug keys for now, so `flutter run --release` works.
38-
signingConfig = signingConfigs.getByName("debug")
55+
signingConfig = if (signingConfigs.named("release").get().storeFile?.exists() == true) {
56+
signingConfigs.getByName("release")
57+
} else {
58+
// Fallback to debug signing for local development
59+
signingConfigs.getByName("debug")
60+
}
3961
}
4062
}
4163

0 commit comments

Comments
 (0)