Skip to content

Commit 735e2f7

Browse files
committed
Experimental android build
1 parent 42f4745 commit 735e2f7

56 files changed

Lines changed: 1647 additions & 447 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.bashrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export ANDROID_HOME=$HOME/Android/Sdk
2+
export PATH=$PATH:$ANDROID_HOME/platform-tools
Lines changed: 140 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,140 @@
1-
# name: Build Android APK
2-
3-
# on:
4-
# workflow_dispatch:
5-
# push:
6-
# tags:
7-
# - "v*"
8-
9-
# jobs:
10-
# build-android:
11-
# name: Build Android APK
12-
# runs-on: ubuntu-latest
13-
14-
# steps:
15-
# - name: Checkout code
16-
# uses: actions/checkout@v4
17-
18-
# - name: Set up Node.js
19-
# uses: actions/setup-node@v4
20-
# with:
21-
# node-version: "20"
22-
23-
# - name: Set up JDK 17
24-
# uses: actions/setup-java@v4
25-
# with:
26-
# distribution: 'temurin'
27-
# java-version: '17'
28-
29-
# - name: Install dependencies
30-
# run: |
31-
# node -e "const fs = require('fs'); try { fs.unlinkSync('package-lock.json'); } catch (e) { /* ignore */ }"
32-
# npm install
33-
34-
# - name: Prepare SvelteKit
35-
# run: npx @sveltejs/kit sync
36-
37-
# - name: Build SvelteKit app
38-
# run: npm run build
39-
40-
# - name: Prepare production dependencies
41-
# run: |
42-
# npm install --production
43-
# npm rebuild
44-
45-
# - name: Prepare Android assets
46-
# run: node scripts/build-android.js
47-
48-
# - name: Decode keystore
49-
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
50-
# env:
51-
# KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
52-
# run: |
53-
# if [ -n "$KEYSTORE_BASE64" ]; then
54-
# echo "$KEYSTORE_BASE64" | base64 -d > android/app/release.keystore
55-
# echo "Keystore decoded successfully"
56-
# else
57-
# echo "No keystore found, will build unsigned APK"
58-
# fi
59-
60-
# - name: Make gradlew executable
61-
# run: chmod +x android/gradlew
62-
63-
# - name: Build Release APK
64-
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
65-
# env:
66-
# KEYSTORE_FILE: release.keystore
67-
# KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
68-
# KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
69-
# KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
70-
# working-directory: android
71-
# run: |
72-
# if [ -f "app/release.keystore" ]; then
73-
# ./gradlew assembleRelease
74-
# else
75-
# echo "Building unsigned APK (no keystore)"
76-
# ./gradlew assembleRelease
77-
# fi
78-
79-
# - name: Build Debug APK
80-
# if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/v')
81-
# working-directory: android
82-
# run: ./gradlew assembleDebug
83-
84-
# - name: Get version from tag
85-
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
86-
# id: get_version
87-
# run: |
88-
# VERSION=${GITHUB_REF#refs/tags/v}
89-
# echo "version=$VERSION" >> $GITHUB_OUTPUT
90-
91-
# - name: Rename APK
92-
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
93-
# run: |
94-
# VERSION=${{ steps.get_version.outputs.version }}
95-
# mkdir -p dist
96-
# if [ -f "android/app/build/outputs/apk/release/app-release.apk" ]; then
97-
# cp android/app/build/outputs/apk/release/app-release.apk \
98-
# dist/serene-pub-${VERSION}-android.apk
99-
# else
100-
# echo "Release APK not found"
101-
# exit 1
102-
# fi
103-
104-
# - name: Upload APK artifact
105-
# uses: actions/upload-artifact@v4
106-
# with:
107-
# name: android-apk
108-
# path: |
109-
# dist/*.apk
110-
# android/app/build/outputs/apk/**/*.apk
111-
112-
# - name: Upload to Release
113-
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
114-
# uses: softprops/action-gh-release@v1
115-
# with:
116-
# files: dist/*.apk
117-
# draft: false
118-
# prerelease: false
119-
# env:
120-
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1+
name: Build Android APK
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*.*.*"
7+
- "v*.*.*-dev"
8+
- "v*.*.*-alpha"
9+
- "v*.*.*-beta"
10+
- "v*.*.*-pr-*"
11+
- "v*.*.*-rc-*"
12+
13+
jobs:
14+
build-android:
15+
name: Build Android APK
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
# Mirrors release.yml's own prerelease detection exactly, so this
22+
# workflow's APK lands as an asset on the same tagged release with
23+
# a prerelease flag that never disagrees with the main build.
24+
- name: Determine prerelease status
25+
id: release_info
26+
shell: bash
27+
run: |
28+
TAG="${{ github.ref_name }}"
29+
VERSION="${TAG#v}"
30+
31+
if [[ "$VERSION" =~ ^([0-9]+\.[0-9]+\.[0-9]+)(-(.+))?$ ]]; then
32+
SUFFIX="${BASH_REMATCH[3]}"
33+
if [ -z "$SUFFIX" ] || [ "$SUFFIX" = "beta" ]; then
34+
IS_PRERELEASE="false"
35+
else
36+
IS_PRERELEASE="true"
37+
fi
38+
else
39+
IS_PRERELEASE="true"
40+
fi
41+
42+
echo "version=$VERSION" >> $GITHUB_OUTPUT
43+
echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
44+
echo "Version: $VERSION"
45+
echo "Is Pre-release: $IS_PRERELEASE"
46+
47+
- name: Set up Node.js
48+
uses: actions/setup-node@v4
49+
with:
50+
node-version: "24"
51+
52+
- name: Set up JDK 17
53+
uses: actions/setup-java@v4
54+
with:
55+
distribution: "temurin"
56+
java-version: "17"
57+
58+
- name: Install dependencies
59+
run: |
60+
node -e "const fs = require('fs'); try { fs.unlinkSync('package-lock.json'); } catch (e) { /* ignore */ }"
61+
npm install
62+
63+
- name: Prepare SvelteKit
64+
run: npx @sveltejs/kit sync
65+
66+
- name: Build SvelteKit app
67+
run: npm run build
68+
69+
- name: Prepare production dependencies
70+
run: |
71+
npm install --omit=dev
72+
npm rebuild
73+
74+
- name: Prepare Android assets
75+
run: node scripts/build-android.js
76+
77+
- name: Decode keystore
78+
env:
79+
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
80+
run: |
81+
if [ -n "$KEYSTORE_BASE64" ]; then
82+
echo "$KEYSTORE_BASE64" | base64 -d > android/app/release.keystore
83+
echo "Keystore decoded successfully"
84+
else
85+
echo "No keystore configured, building an unsigned APK"
86+
fi
87+
88+
- name: Make gradlew executable
89+
run: chmod +x android/gradlew
90+
91+
- name: Build Release APK
92+
env:
93+
KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
94+
KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
95+
KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
96+
working-directory: android
97+
run: |
98+
# Only set KEYSTORE_FILE if the keystore was actually decoded —
99+
# build.gradle treats its mere presence as "sign this build", so
100+
# an unconditionally-set env var would make it try to sign with a
101+
# keystore that doesn't exist whenever the secrets aren't configured.
102+
# Gradle's file() in app/build.gradle resolves relative to the
103+
# app/ project directory, so this must be a bare filename, not a
104+
# path relative to this step's android/ working directory.
105+
if [ -f "app/release.keystore" ]; then
106+
export KEYSTORE_FILE=release.keystore
107+
fi
108+
./gradlew assembleRelease
109+
110+
# Signed and unsigned release builds produce differently-named APKs
111+
# (app-release.apk vs. app-release-unsigned.apk) — this always
112+
# results in exactly one renamed file in dist/, regardless of which
113+
# case occurred, so exactly one APK ever reaches the release.
114+
- name: Rename APK
115+
id: rename_apk
116+
run: |
117+
VERSION="${{ steps.release_info.outputs.version }}"
118+
mkdir -p dist
119+
SRC=""
120+
if [ -f "android/app/build/outputs/apk/release/app-release.apk" ]; then
121+
SRC="android/app/build/outputs/apk/release/app-release.apk"
122+
elif [ -f "android/app/build/outputs/apk/release/app-release-unsigned.apk" ]; then
123+
SRC="android/app/build/outputs/apk/release/app-release-unsigned.apk"
124+
else
125+
echo "Error: no release APK found in android/app/build/outputs/apk/release/"
126+
ls -la android/app/build/outputs/apk/release/ || true
127+
exit 1
128+
fi
129+
DEST="dist/serene-pub-${VERSION}-android.apk"
130+
cp "$SRC" "$DEST"
131+
echo "apk_path=$DEST" >> $GITHUB_OUTPUT
132+
echo "Renamed $SRC -> $DEST"
133+
134+
- name: Upload to Release
135+
uses: softprops/action-gh-release@v2
136+
with:
137+
files: ${{ steps.rename_apk.outputs.apk_path }}
138+
prerelease: ${{ steps.release_info.outputs.is_prerelease }}
139+
env:
140+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ package-lock.json
4343
/android/local.properties
4444
/android/build
4545
/android/app/build
46+
/android/app/.cxx
4647
/android/app/src/main/assets/serene-pub
48+
/android/app/src/main/cpp/libnode
49+
/android/gradle/wrapper/dists
4750
*.apk
4851
*.aab
4952
keystore.jks

0 commit comments

Comments
 (0)