Skip to content

Commit e5239b8

Browse files
vNeeL-codeclaude
andcommitted
Sign APK in CI so it installs on all devices
Unsigned APKs rejected on some devices ("package appears invalid"). Added signing config: - CI: uses repo secrets if set, otherwise generates ephemeral keystore - Local builds: fall back to debug signing - Release builds are now always signed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d3ff958 commit e5239b8

2 files changed

Lines changed: 47 additions & 2 deletions

File tree

.github/workflows/release.yml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,38 @@ jobs:
2727
- name: Make gradlew executable
2828
run: chmod +x ./gradlew
2929

30+
- name: Setup signing
31+
run: |
32+
# Use repo secret if available, otherwise generate ephemeral keystore
33+
if [ -n "${{ secrets.KEYSTORE_BASE64 }}" ]; then
34+
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > /tmp/release.keystore
35+
echo "KEYSTORE_FILE=/tmp/release.keystore" >> $GITHUB_ENV
36+
echo "KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
37+
echo "KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> $GITHUB_ENV
38+
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV
39+
else
40+
keytool -genkeypair -v \
41+
-keystore /tmp/release.keystore \
42+
-alias oracle_os \
43+
-keyalg RSA -keysize 2048 -validity 10000 \
44+
-storepass oracle_os_release \
45+
-keypass oracle_os_release \
46+
-dname "CN=Oracle_OS, O=ASI, L=Unknown, ST=Unknown, C=UK"
47+
echo "KEYSTORE_FILE=/tmp/release.keystore" >> $GITHUB_ENV
48+
echo "KEYSTORE_PASSWORD=oracle_os_release" >> $GITHUB_ENV
49+
echo "KEY_ALIAS=oracle_os" >> $GITHUB_ENV
50+
echo "KEY_PASSWORD=oracle_os_release" >> $GITHUB_ENV
51+
fi
52+
3053
- name: Build Release APK
3154
run: ./gradlew assembleRelease
3255

3356
- name: Rename APK
3457
run: |
3558
VERSION=${GITHUB_REF_NAME#v}
36-
cp app/build/outputs/apk/release/app-release-unsigned.apk \
37-
app/build/outputs/apk/release/Oracle_OS-${VERSION}.apk
59+
# Find the signed APK (name varies based on signing method)
60+
APK=$(find app/build/outputs/apk/release -name "*.apk" | head -1)
61+
cp "$APK" "app/build/outputs/apk/release/Oracle_OS-${VERSION}.apk"
3862
3963
- name: Create GitHub Release
4064
uses: softprops/action-gh-release@v2

app/build.gradle.kts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,30 @@ android {
2222
}
2323
}
2424

25+
signingConfigs {
26+
create("release") {
27+
// CI provides these via environment variables
28+
// Local builds fall back to debug signing
29+
val ksFile = System.getenv("KEYSTORE_FILE")
30+
if (ksFile != null && File(ksFile).exists()) {
31+
storeFile = File(ksFile)
32+
storePassword = System.getenv("KEYSTORE_PASSWORD") ?: ""
33+
keyAlias = System.getenv("KEY_ALIAS") ?: "oracle_os"
34+
keyPassword = System.getenv("KEY_PASSWORD") ?: ""
35+
}
36+
}
37+
}
38+
2539
buildTypes {
2640
release {
2741
isMinifyEnabled = false
42+
val ksFile = System.getenv("KEYSTORE_FILE")
43+
if (ksFile != null && File(ksFile).exists()) {
44+
signingConfig = signingConfigs.getByName("release")
45+
} else {
46+
// Fall back to debug signing so APK always installs
47+
signingConfig = signingConfigs.getByName("debug")
48+
}
2849
}
2950
}
3051

0 commit comments

Comments
 (0)