Skip to content

Commit 3ccbe7e

Browse files
danryupljones
authored andcommitted
Android: CI changes for Play Store
* android build conf changes * fix shellcheck warnings android fix audio permission handling android fix androidextras include android remove redundant jdk install add ANDROID_NDK_ROOT comment fix for clang-format style check android add all ABI support android: remove redundant minSdkVersion clang-format fixes android: fix manifest xml, remove old boilerplate add ANDROID_SDK_ROOT shellcheck fix android fix assignments in pro file fix typo
1 parent d4dd153 commit 3ccbe7e

File tree

5 files changed

+238
-107
lines changed

5 files changed

+238
-107
lines changed

.github/autobuild/android.sh

Lines changed: 169 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,51 @@
2626

2727
set -eu
2828

29-
# Some of the following version pinnings are semi-automatically checked for
30-
# updates. Update .github/workflows/bump-dependencies.yaml when renaming those:
31-
COMMANDLINETOOLS_VERSION=6858069
32-
ANDROID_NDK_VERSION=r21d
33-
ANDROID_PLATFORM=android-30
34-
ANDROID_BUILD_TOOLS=30.0.2
35-
AQTINSTALL_VERSION=3.1.18
36-
QT_VERSION=5.15.2
37-
38-
# Only variables which are really needed by sub-commands are exported.
39-
# Definitions have to stay in a specific order due to dependencies.
29+
## TODO: Decide whether we want to use this action.
30+
## TODO: The patch not only adopts the new action but changes dependencies:
31+
## TODO: - COMMANDLINETOOLS_VERSION from 6858069 to 7.0
32+
## TODO: - ANDROID_NDK_VERSION from r21d to 25.1.8937393
33+
## TODO: - ANDROID_PLATFORM from android-30 to android-33
34+
## TODO: - ANDROID_BUILD_TOOLS from 30.0.2 to 33.0.0
35+
## TODO: - AQTINSTALL_VERSION from 3.1.18 to 2.1.0
36+
## TODO: - QT_VERSION from 5.15.2 to 6.3.2
37+
38+
# # Some of the following version pinnings are semi-automatically checked for
39+
# # updates. Update .github/workflows/bump-dependencies.yaml when renaming those:
40+
# COMMANDLINETOOLS_VERSION=6858069
41+
# ANDROID_NDK_VERSION=r21d
42+
# ANDROID_PLATFORM=android-30
43+
# ANDROID_BUILD_TOOLS=30.0.2
44+
# AQTINSTALL_VERSION=3.1.18
45+
# QT_VERSION=5.15.2
46+
47+
## From https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md
48+
# Tools already installed:
49+
# Android Command Line Tools 7.0
50+
# Android SDK Build-tools 33.0.0
51+
# Android SDK Platform-Tools 33.0.3
52+
# Android SDK Platforms android-33 (rev 2)
53+
# Android SDK Tools 26.1.1
54+
55+
# Env vars set:
56+
# ANDROID_HOME /usr/local/lib/android/sdk
57+
# ANDROID_NDK /usr/local/lib/android/sdk/ndk/25.1.8937393
58+
# ANDROID_NDK_HOME /usr/local/lib/android/sdk/ndk/25.1.8937393
59+
# ANDROID_NDK_LATEST_HOME /usr/local/lib/android/sdk/ndk/25.1.8937393
60+
# ANDROID_NDK_ROOT /usr/local/lib/android/sdk/ndk/25.1.8937393
61+
# ANDROID_SDK_ROOT /usr/local/lib/android/sdk
62+
63+
ANDROID_PLATFORM=android-33
64+
AQTINSTALL_VERSION=2.1.0
65+
QT_VERSION=6.3.2
4066
QT_BASEDIR="/opt/Qt"
41-
ANDROID_BASEDIR="/opt/android"
4267
BUILD_DIR=build
43-
export ANDROID_SDK_ROOT="${ANDROID_BASEDIR}/android-sdk"
44-
COMMANDLINETOOLS_DIR="${ANDROID_SDK_ROOT}"/cmdline-tools/latest/
45-
export ANDROID_NDK_ROOT="${ANDROID_BASEDIR}/android-ndk"
4668
ANDROID_NDK_HOST="linux-x86_64"
47-
ANDROID_SDKMANAGER="${COMMANDLINETOOLS_DIR}/bin/sdkmanager"
48-
export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/"
69+
# Github CI image-provided env vars, but explicitly re-assign to placate shellcheck
70+
ANDROID_NDK_ROOT="${ANDROID_NDK_ROOT:?ANDROID_NDK_ROOT should be provided}"
71+
ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT:?ANDROID_SDK_ROOT should be provided}"
72+
# Only variables which are really needed by sub-commands are exported.
73+
export JAVA_HOME=${JAVA_HOME_11_X64}
4974
export PATH="${PATH}:${ANDROID_SDK_ROOT}/tools"
5075
export PATH="${PATH}:${ANDROID_SDK_ROOT}/platform-tools"
5176

@@ -58,36 +83,7 @@ setup_ubuntu_dependencies() {
5883
export DEBIAN_FRONTEND="noninteractive"
5984

6085
sudo apt-get -qq update
61-
sudo apt-get -qq --no-install-recommends -y install build-essential zip unzip bzip2 p7zip-full curl chrpath openjdk-8-jdk-headless
62-
}
63-
64-
setup_android_sdk() {
65-
mkdir -p "${ANDROID_BASEDIR}"
66-
67-
if [[ -d "${COMMANDLINETOOLS_DIR}" ]]; then
68-
echo "Using commandlinetools installation from previous run (actions/cache)"
69-
else
70-
mkdir -p "${COMMANDLINETOOLS_DIR}"
71-
curl -s -o downloadfile "https://dl.google.com/android/repository/commandlinetools-linux-${COMMANDLINETOOLS_VERSION}_latest.zip"
72-
unzip -q downloadfile
73-
mv cmdline-tools/* "${COMMANDLINETOOLS_DIR}"
74-
fi
75-
76-
yes | "${ANDROID_SDKMANAGER}" --licenses
77-
"${ANDROID_SDKMANAGER}" --update
78-
"${ANDROID_SDKMANAGER}" "platforms;${ANDROID_PLATFORM}"
79-
"${ANDROID_SDKMANAGER}" "build-tools;${ANDROID_BUILD_TOOLS}"
80-
}
81-
82-
setup_android_ndk() {
83-
mkdir -p "${ANDROID_BASEDIR}"
84-
if [[ -d "${ANDROID_NDK_ROOT}" ]]; then
85-
echo "Using NDK installation from previous run (actions/cache)"
86-
else
87-
curl -s -o downloadfile "https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip"
88-
unzip -q downloadfile
89-
mv "android-ndk-${ANDROID_NDK_VERSION}" "${ANDROID_NDK_ROOT}"
90-
fi
86+
sudo apt-get -qq --no-install-recommends -y install build-essential zip unzip bzip2 p7zip-full curl chrpath
9187
}
9288

9389
setup_qt() {
@@ -96,54 +92,151 @@ setup_qt() {
9692
else
9793
echo "Installing Qt..."
9894
python3 -m pip install "aqtinstall==${AQTINSTALL_VERSION}"
99-
local qtmultimedia=()
100-
if [[ ! "${QT_VERSION}" =~ 5\..* ]]; then
101-
# From Qt6 onwards, qtmultimedia is a module and cannot be installed
102-
# as an archive anymore.
103-
qtmultimedia=("--modules")
104-
fi
105-
qtmultimedia+=("qtmultimedia")
106-
107-
python3 -m aqt install-qt --outputdir "${QT_BASEDIR}" linux android "${QT_VERSION}" \
108-
--archives qtbase qttools qttranslations qtandroidextras \
109-
"${qtmultimedia[@]}"
110-
# Delete libraries, which we don't use, but which bloat the resulting package and might introduce unwanted dependencies.
111-
find "${QT_BASEDIR}" -name 'libQt5*Quick*.so' -delete
112-
rm -r "${QT_BASEDIR}/${QT_VERSION}/android/qml/"
95+
# icu needs explicit installation
96+
# otherwise: "qmake: error while loading shared libraries: libicui18n.so.56: cannot open shared object file: No such file or directory"
97+
python3 -m aqt install-qt --outputdir "${QT_BASEDIR}" linux desktop "${QT_VERSION}" \
98+
--archives qtbase qtdeclarative qtsvg qttools icu \
99+
--modules qtmultimedia
100+
101+
# - 64bit required for Play Store
102+
python3 -m aqt install-qt --outputdir "${QT_BASEDIR}" linux android "${QT_VERSION}" android_arm64_v8a \
103+
--archives qtbase qtdeclarative qtsvg qttools \
104+
--modules qtmultimedia
105+
106+
# Also install for arm_v7 to build for 32bit devices
107+
python3 -m aqt install-qt --outputdir "${QT_BASEDIR}" linux android "${QT_VERSION}" android_armv7 \
108+
--archives qtbase qtdeclarative qtsvg qttools \
109+
--modules qtmultimedia
110+
113111
fi
114112
}
115113

116-
build_app_as_apk() {
117-
local QT_DIR="${QT_BASEDIR}/${QT_VERSION}/android"
114+
build_app() {
115+
local ARCH_ABI="${1}"
116+
118117
local MAKE="${ANDROID_NDK_ROOT}/prebuilt/${ANDROID_NDK_HOST}/bin/make"
119118

120-
"${QT_DIR}/bin/qmake" -spec android-clang
119+
echo "${GOOGLE_RELEASE_KEYSTORE}" | base64 --decode > android/android_release.keystore
120+
121+
echo ">>> Compiling for ${ARCH_ABI} ..."
122+
123+
# Override ANDROID_ABIS according to build target
124+
# note: seems ANDROID_ABIS can be set here at cmdline, but ANDROID_VERSION_CODE cannot - must be in qmake file
125+
if [ "${ARCH_ABI}" == "android_armv7" ]; then
126+
echo ">>> Running qmake with ANDROID_ABIS=armeabi-v7a ..."
127+
ANDROID_ABIS=armeabi-v7a \
128+
"${QT_BASEDIR}/${QT_VERSION}/${ARCH_ABI}/bin/qmake" -spec android-clang
129+
elif [ "${ARCH_ABI}" == "android_arm64_v8a" ]; then
130+
echo ">>> Running qmake with ANDROID_ABIS=arm64-v8a ..."
131+
ANDROID_ABIS=arm64-v8a \
132+
"${QT_BASEDIR}/${QT_VERSION}/${ARCH_ABI}/bin/qmake" -spec android-clang
133+
elif [ "${ARCH_ABI}" == "android_x86" ]; then
134+
echo ">>> Running qmake with ANDROID_ABIS=arm64-v8a ..."
135+
ANDROID_ABIS=x86 \
136+
"${QT_BASEDIR}/${QT_VERSION}/${ARCH_ABI}/bin/qmake" -spec android-clang
137+
elif [ "${ARCH_ABI}" == "android_x86_64" ]; then
138+
echo ">>> Running qmake with ANDROID_ABIS=arm64-v8a ..."
139+
ANDROID_ABIS=x86_64 \
140+
"${QT_BASEDIR}/${QT_VERSION}/${ARCH_ABI}/bin/qmake" -spec android-clang
141+
fi
121142
"${MAKE}" -j "$(nproc)"
122-
"${MAKE}" INSTALL_ROOT="${BUILD_DIR}" -f Makefile install
123-
"${QT_DIR}"/bin/androiddeployqt --input android-Jamulus-deployment-settings.json --output "${BUILD_DIR}" \
124-
--android-platform "${ANDROID_PLATFORM}" --jdk "${JAVA_HOME}" --gradle
143+
"${MAKE}" INSTALL_ROOT="${BUILD_DIR}_${ARCH_ABI}" -f Makefile install
144+
}
145+
146+
build_make_clean() {
147+
echo ">>> Doing make clean ..."
148+
local MAKE="${ANDROID_NDK_ROOT}/prebuilt/${ANDROID_NDK_HOST}/bin/make"
149+
"${MAKE}" clean
150+
rm -f Makefile
151+
}
152+
153+
build_aab() {
154+
local ARCH_ABI="${1}"
155+
156+
if [ "${ARCH_ABI}" == "android_armv7" ]; then
157+
TARGET_ABI=armeabi-v7a
158+
elif [ "${ARCH_ABI}" == "android_arm64_v8a" ]; then
159+
TARGET_ABI=arm64-v8a
160+
elif [ "${ARCH_ABI}" == "android_x86" ]; then
161+
TARGET_ABI=x86
162+
elif [ "${ARCH_ABI}" == "android_x86_64" ]; then
163+
TARGET_ABI=x86_64
164+
fi
165+
echo ">>> Building .aab file for ${TARGET_ABI}...."
166+
167+
ANDROID_ABIS=${TARGET_ABI} ${QT_BASEDIR}/${QT_VERSION}/gcc_64/bin/androiddeployqt --input android-Jamulus-deployment-settings.json \
168+
--verbose \
169+
--output "${BUILD_DIR}_${ARCH_ABI}" \
170+
--aab \
171+
--release \
172+
--sign android/android_release.keystore jamulus \
173+
--storepass "${GOOGLE_KEYSTORE_PASS}" \
174+
--android-platform "${ANDROID_PLATFORM}" \
175+
--jdk "${JAVA_HOME}" \
176+
--gradle
125177
}
126178

127179
pass_artifact_to_job() {
128-
mkdir deploy
129-
local artifact="jamulus_${JAMULUS_BUILD_VERSION}_android.apk"
130-
echo "Moving ${BUILD_DIR}/build/outputs/apk/debug/build-debug.apk to deploy/${artifact}"
131-
mv "./${BUILD_DIR}/build/outputs/apk/debug/build-debug.apk" "./deploy/${artifact}"
132-
echo "artifact_1=${artifact}" >> "$GITHUB_OUTPUT"
180+
local ARCH_ABI="${1}"
181+
echo ">>> Deploying .aab file for ${ARCH_ABI}...."
182+
183+
if [ "${ARCH_ABI}" == "android_armv7" ]; then
184+
NUM="1"
185+
BUILDNAME="arm"
186+
elif [ "${ARCH_ABI}" == "android_arm64_v8a" ]; then
187+
NUM="2"
188+
BUILDNAME="arm64"
189+
elif [ "${ARCH_ABI}" == "android_x86" ]; then
190+
NUM="3"
191+
BUILDNAME="x86"
192+
elif [ "${ARCH_ABI}" == "android_x86_64" ]; then
193+
NUM="4"
194+
BUILDNAME="x86_64"
195+
fi
196+
197+
#mkdir deploy
198+
#local artifact="jamulus_${JAMULUS_BUILD_VERSION}_android.apk"
199+
mkdir -p deploy
200+
local artifact="Jamulus_${JAMULUS_BUILD_VERSION}_android_${BUILDNAME}.aab"
201+
# debug to check for filenames
202+
ls -alR "${BUILD_DIR}_${ARCH_ABI}/build/outputs/bundle/release/"
203+
ls -al "${BUILD_DIR}_${ARCH_ABI}/build/outputs/bundle/release/build_${ARCH_ABI}-release.aab"
204+
205+
#echo "Moving ${BUILD_DIR}/build/outputs/apk/debug/build-debug.apk to deploy/${artifact}"
206+
#mv "./${BUILD_DIR}/build/outputs/apk/debug/build-debug.apk" "./deploy/${artifact}"
207+
echo ">>> Moving ${BUILD_DIR}_${ARCH_ABI}/build/outputs/bundle/release/build_${ARCH_ABI}-release.aab to deploy/${artifact}"
208+
mv "./${BUILD_DIR}_${ARCH_ABI}/build/outputs/bundle/release/build_${ARCH_ABI}-release.aab" "./deploy/${artifact}"
209+
echo ">>> Moved .aab file to deploy/${artifact}"
210+
echo ">>> Artifact number is: ${NUM}"
211+
echo ">>> Setting output as such: name=artifact_${NUM}::${artifact}"
212+
#echo "artifact_1=${artifact}" >> "$GITHUB_OUTPUT"
213+
echo "::set-output name=artifact_${NUM}::${artifact}"
133214
}
134215

135216
case "${1:-}" in
136217
setup)
137218
setup_ubuntu_dependencies
138-
setup_android_ndk
139-
setup_android_sdk
140219
setup_qt
141220
;;
142221
build)
143-
build_app_as_apk
222+
# Build all targets in sequence
223+
build_app "android_armv7"
224+
build_aab "android_armv7"
225+
build_make_clean
226+
build_app "android_arm64_v8a"
227+
build_aab "android_arm64_v8a"
228+
build_make_clean
229+
build_app "android_x86"
230+
build_aab "android_x86"
231+
build_make_clean
232+
build_app "android_x86_64"
233+
build_aab "android_x86_64"
144234
;;
145235
get-artifacts)
146-
pass_artifact_to_job
236+
pass_artifact_to_job "android_armv7"
237+
pass_artifact_to_job "android_arm64_v8a"
238+
pass_artifact_to_job "android_x86"
239+
pass_artifact_to_job "android_x86_64"
147240
;;
148241
*)
149242
echo "Unknown stage '${1:-}'"

.github/workflows/autobuild.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,9 @@ jobs:
377377
NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }}
378378
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
379379
MACOS_CA_PUBLICKEY: ${{ secrets.MACOS_CA_PUBKEY }}
380+
GOOGLE_RELEASE_KEYSTORE: ${{ secrets.GOOGLE_KEYSTORE }}
381+
GOOGLE_KEYSTORE_PASS: ${{ secrets.GOOGLE_KEYSTORE_PASS }}
382+
380383
- name: Post-Build for ${{ matrix.config.config_name }}
381384
id: get-artifacts
382385
run: ${{ matrix.config.base_command }} get-artifacts
@@ -427,6 +430,25 @@ jobs:
427430
JAMULUS_BUILD_VERSION: ${{ needs.create_release.outputs.build_version }}
428431
ARTIFACT_PATH: deploy/${{ steps.get-artifacts.outputs.artifact_1 }}
429432

433+
## RELEASE PROCEDURE FOR:
434+
## - Android Play Store - aab
435+
## Requirement: Service Account JSON setup:
436+
## - Google Play Console -> Setup -> API Access -> Create/Link Google Cloud Project
437+
## - Google Cloud console -> IAM & Admin -> Service Accounts -> Create (Wizard). Then create JSON key and export/save
438+
- name: Publish all Android ABI builds to Play Store
439+
if: >-
440+
needs.create_release.outputs.publish_to_release == 'true' &&
441+
matrix.config.target_os == 'android'
442+
id: publish_android
443+
uses: r0adkll/upload-google-play@v1
444+
with:
445+
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_JSON }}
446+
packageName: io.jamulus.jamulus
447+
releaseFiles: deploy/Jamulus*.aab
448+
releaseName: ${{ needs.create_release.outputs.build_version }}
449+
track: beta
450+
status: draft
451+
430452
- name: Deploy Artifact 1 to Release
431453
if: needs.create_release.outputs.publish_to_release == 'true'
432454
id: upload-release-asset1

Jamulus.pro

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,53 @@ win32 {
244244
LIBS += -framework AVFoundation \
245245
-framework AudioToolbox
246246
} else:android {
247-
ANDROID_ABIS = armeabi-v7a arm64-v8a x86 x86_64
247+
# By default build for all the ABIs
248+
# ANDROID_ABIS = armeabi-v7a arm64-v8a x86 x86_64
249+
250+
# get ANDROID_ABIS from environment - passed directly to qmake
251+
ANDROID_ABIS = $$getenv(ANDROID_ABIS)
252+
253+
# Optional: if ANDROID_ABIS is passed as env var to qmake, will override this
254+
# !defined(ANDROID_ABIS, var):ANDROID_ABIS = arm64-v8a
255+
256+
# Experiments show likely better results with Android 10+ devices
257+
ANDROID_MIN_SDK_VERSION = 29
258+
ANDROID_TARGET_SDK_VERSION = 32
248259
ANDROID_VERSION_NAME = $$VERSION
249-
ANDROID_VERSION_CODE = $$system(git log --oneline | wc -l)
260+
261+
## For local Dev use on Windows/WSA:
262+
equals(QMAKE_HOST.os, Windows) {
263+
ANDROID_ABIS = x86_64
264+
ANDROID_VERSION_CODE = 1234 # dummy int value
265+
} else {
266+
# date-based unique integer value for Play Store submission
267+
!defined(ANDROID_VERSION_CODE, var):ANDROID_VERSION_CODE = $$system(date +%s | cut -c 2-)
268+
}
269+
270+
# make separate version codes for each abi build otherwise Play Store rejects
271+
contains (ANDROID_ABIS, armeabi-v7a) {
272+
ANDROID_VERSION_CODE = $$num_add($$ANDROID_VERSION_CODE, 1)
273+
message("Setting for armeabi-v7a: ANDROID_VERSION_CODE=$${ANDROID_VERSION_CODE}")
274+
}
275+
contains (ANDROID_ABIS, x86) {
276+
ANDROID_VERSION_CODE = $$num_add($$ANDROID_VERSION_CODE, 2)
277+
message("Setting for x86: ANDROID_VERSION_CODE=$${ANDROID_VERSION_CODE}")
278+
}
279+
contains (ANDROID_ABIS, x86_64) {
280+
ANDROID_VERSION_CODE = $$num_add($$ANDROID_VERSION_CODE, 3)
281+
message("Setting for x86_64: ANDROID_VERSION_CODE=$${ANDROID_VERSION_CODE}")
282+
}
283+
250284
message("Setting ANDROID_VERSION_NAME=$${ANDROID_VERSION_NAME} ANDROID_VERSION_CODE=$${ANDROID_VERSION_CODE}")
251285

252286
# liboboe requires C++17 for std::timed_mutex
253287
CONFIG += c++17
254288

255-
QT += androidextras
289+
# For device recording permissions
290+
QT += core-private # for Qt6
256291

257292
# enabled only for debugging on android devices
258-
DEFINES += ANDROIDDEBUG
293+
#DEFINES += ANDROIDDEBUG
259294

260295
target.path = /tmp/your_executable # path on device
261296
INSTALLS += target

0 commit comments

Comments
 (0)