Skip to content

Work on CI builds

Work on CI builds #157

#-------------------------------------------------------------------------------
# Workflow configuration
#-------------------------------------------------------------------------------
name: "Mobile CI builds (cmake)"
on:
push:
pull_request:
workflow_dispatch:
#-------------------------------------------------------------------------------
# Define application name & version
#-------------------------------------------------------------------------------
env:
APP_NAME: "QmlAppTemplate"
APP_VERSION: "0.8"
QT_VERSION: "6.8.0"
#-------------------------------------------------------------------------------
# SECRETS
#-------------------------------------------------------------------------------
# convert to base64 (linux) : cat file.keystore | base64 | tr -d '\n' > file.base64
# convert to base64 (apple) : cat file.keystore | base64 | tr -d '\n' > file.base64
## Android secrets:
# create a keystore file, convert it to base64
# save the keystore base64 file under the name ANDROID_SIGNINGKEY_BASE64
# save the keystore alias under the name ANDROID_SIGNINGKEY_ALIAS
# save the keystore password under the name ANDROID_SIGNINGKEY_PASSWORD
## Android upload:
# - https://developers.google.com/android-publisher/getting_started
# - https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md
# create the gplay service account, download the json key, convert it to base64
# save the base64 under the name GPLAY_SERVICEACCOUNTKEY_BASE64
## Apple secrets:
# - https://developer.apple.com/help/account/reference/certificate-types
# - https://docs.github.com/en/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development
# a valid apple developer account is required
# create a build certificate with xcode, download it, convert it to base64
# save the build certificate base64 file under the name APPLE_BUILD_CERTIFICATE_BASE64
# save the build certificate password under the name APPLE_BUILD_CERTIFICATE_PASSWORD
# create a provisioning profile for your app bundle id, download it, convert it to base64
# save the provisioning profile under the name APPLE_PROVISIONING_PROFILE_BASE64
# a new keychain will be created on the runner to store these certificates, choose a new password under the name APPLE_KEYCHAIN_PASSWORD
## iOS upload:
# TODO
#-------------------------------------------------------------------------------
# Workflow jobs
#-------------------------------------------------------------------------------
jobs:
## Android build #############################################################
build-android:
name: "Android CI build"
runs-on: ubuntu-20.04
steps:
# Checkout repository (and submodules)
- name: Checkout repository (and submodules)
uses: actions/checkout@v4
with:
submodules: recursive
# Java environment (already installed in 'ubuntu-20.04')
- name: Setup Java environment
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
# Android environment (already installed in 'ubuntu-20.04')
#- name: Setup Android environment
# uses: android-actions/setup-android@v3
#- name: Install Android SDK / NDK / tools
# run: |
# sdkmanager "platforms;android-35"
# sdkmanager "ndk;26.1.10909125"
# sdkmanager "build-tools;35.0.0"
# Install Qt (desktop & Android)
- name: Install Qt (desktop)
uses: jurplel/install-qt-action@v4
with:
version: ${{env.QT_VERSION}}
- name: Install Qt (Android armv7)
uses: jurplel/install-qt-action@v4
with:
version: ${{env.QT_VERSION}}
host: 'linux'
target: 'android'
arch: 'android_armv7'
- name: Install Qt (Android armv8)
uses: jurplel/install-qt-action@v4
with:
version: ${{env.QT_VERSION}}
host: 'linux'
target: 'android'
arch: 'android_arm64_v8a'
- name: Install Qt (Android x86)
uses: jurplel/install-qt-action@v4
with:
version: ${{env.QT_VERSION}}
host: 'linux'
target: 'android'
arch: 'android_x86'
- name: Install Qt (Android x86_64)
uses: jurplel/install-qt-action@v4
with:
version: ${{env.QT_VERSION}}
host: 'linux'
target: 'android'
arch: 'android_x86_64'
# Install dependencies (from package manager)
- name: Install dependencies (from package manager)
run: |
sudo apt-get install cmake ninja-build -y;
# Setup env
- name: Setup env
run: |
echo "QT_HOST_PATH=/home/runner/work/${{env.APP_NAME}}/Qt/${{env.QT_VERSION}}/gcc_64" >> $GITHUB_ENV
echo "QT_TARGET_PATH=/home/runner/work/${{env.APP_NAME}}/Qt/${{env.QT_VERSION}}/android_arm64_v8a" >> $GITHUB_ENV
qmake --version
cmake --version
# Build application
- name: Build application
run: |
${{env.QT_TARGET_PATH}}/bin/qt-cmake --version
${{env.QT_TARGET_PATH}}/bin/qt-cmake -B build/ -G Ninja \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_FIND_ROOT_PATH:PATH=${{env.QT_TARGET_PATH}} \
-DCMAKE_PREFIX_PATH:PATH=${{env.QT_TARGET_PATH}} \
-DANDROID_SDK_ROOT=$ANDROID_SDK_ROOT \
-DANDROID_NDK_ROOT=$ANDROID_NDK_ROOT \
-DANDROID_PLATFORM=android-23 \
-DANDROID_ABI="arm64-v8a" \
-DQT_HOST_PATH:PATH=${{env.QT_HOST_PATH}} \
-DQT_ANDROID_BUILD_ALL_ABIS=ON \
-DQT_ANDROID_ABIS="armeabi-v7a;arm64-v8a;x86;x86_64"
cmake --build build/ --config Release
# Package & sign application
- name: Package & sign application
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo ${{ secrets.ANDROID_SIGNINGKEY_BASE64 }} > release.keystore.base64
base64 -d release.keystore.base64 > release.keystore
${{env.QT_HOST_PATH}}/bin/androiddeployqt --input build/android-${{env.APP_NAME}}-deployment-settings.json --output build/android-build/ --android-platform android-34 --aab --release --sign release.keystore ${{ secrets.ANDROID_SIGNINGKEY_ALIAS }} --storepass ${{ secrets.ANDROID_SIGNINGKEY_PASSWORD }}
# Upload Android app bundle (GitHub CI)
- name: Upload Android app bundle (GitHub CI)
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: actions/upload-artifact@v4
with:
name: ${{env.APP_NAME}}-${{env.APP_VERSION}}-Android.aab
path: build/android-build/build/outputs/bundle/release/android-build-release.aab
# Upload Android app bundle (Play Store)
- name: Upload Android app bundle (Play Store)
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo ${{ secrets.GPLAY_SERVICEACCOUNTKEY_BASE64 }} > assets/android/fastlane/gplay_serviceaccountkey.base64
base64 -d assets/android/fastlane/gplay_serviceaccountkey.base64 > assets/android/fastlane/gplay_serviceaccountkey.json
mv assets/android/fastlane/ fastlane/
fastlane android deploy
## iOS build #################################################################
build-ios:
name: "iOS CI build"
runs-on: macos-13
steps:
# Checkout repository (and submodules)
- name: Checkout repository (and submodules)
uses: actions/checkout@v4
with:
submodules: recursive
# Install Qt (desktop & iOS)
- name: Install Qt (desktop & iOS)
uses: jurplel/install-qt-action@v4
with:
version: ${{env.QT_VERSION}}
host: 'mac'
target: 'ios'
extra: '--autodesktop'
# Install dependencies (from package manager)
#- name: Install dependencies (from package manager)
# run: |
# brew install cmake ninja
# Setup env
- name: Setup env
run: |
echo "QT_HOST_PATH=/Users/runner/work/${{env.APP_NAME}}/Qt/${{env.QT_VERSION}}/macos" >> $GITHUB_ENV
echo "QT_TARGET_PATH=/Users/runner/work/${{env.APP_NAME}}/Qt/${{env.QT_VERSION}}/ios" >> $GITHUB_ENV
qmake --version
cmake --version
# Build application
- name: Build application
if: ${{ github.event_name != 'workflow_dispatch' }}
run: |
${{env.QT_TARGET_PATH}}/bin/qt-cmake --version
${{env.QT_TARGET_PATH}}/bin/qt-cmake -B build/ -G Xcode \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_FIND_ROOT_PATH:PATH=${{env.QT_TARGET_PATH}} \
-DCMAKE_PREFIX_PATH:PATH=${{env.QT_TARGET_PATH}} \
-DQT_HOST_PATH:PATH=${{env.QT_HOST_PATH}}
cmake --build build/ --config Release -- CODE_SIGNING_ALLOWED=NO
# Setup developer certificate and provisioning profile
- name: Setup developer certificate and provisioning profile
if: ${{ github.event_name == 'workflow_dispatch' }}
env:
APPLE_BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }}
APPLE_BUILD_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_BUILD_CERTIFICATE_PASSWORD }}
APPLE_PROVISIONING_PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }}
APPLE_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
run: |
# create variables
CERT_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision # .mobileprovision for iOS # .provisionprofile for macOS
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$APPLE_BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERT_PATH
echo -n "$APPLE_PROVISIONING_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$APPLE_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$APPLE_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERT_PATH -P "$APPLE_BUILD_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
# Build application (signed)
- name: Build application (signed)
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
${{env.QT_TARGET_PATH}}/bin/qt-cmake --version
${{env.QT_TARGET_PATH}}/bin/qt-cmake -B build/ -G Xcode \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_FIND_ROOT_PATH:PATH=${{env.QT_TARGET_PATH}} \
-DCMAKE_PREFIX_PATH:PATH=${{env.QT_TARGET_PATH}} \
-DQT_HOST_PATH:PATH=${{env.QT_HOST_PATH}} \
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED="YES" \
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE="Manual" \
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY="iPhone Developer" \
-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM="24Q8SM98H5" \
-DCMAKE_XCODE_ATTRIBUTE_PROVISIONING_PROFILE="a8ac7ee1-5f4e-4e9c-a0f2-be05df16c179"
cmake --build build/ --config Release
# Recap stuff
- name: Recap stuff
continue-on-error: true
run: |
ls build/