Skip to content

Build app for target platforms #144

Build app for target platforms

Build app for target platforms #144

Workflow file for this run

name: Build app for target platforms
on:
# Trigger workflow when new tag is pushed.
push:
tags:
- 'v*'
# Allow running this workflow manually from the Actions tab.
workflow_dispatch:
# Allow only one concurrent build and deployment workflow
concurrency:
group: "build"
cancel-in-progress: true
jobs:
build_android:
name: Build for Android
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run shared environment setup steps
uses: ./.github/actions/environment_setup
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
- name: Create Android keystore file
run: echo -n "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 --decode > key.jks
# See: https://docs.flutter.dev/deployment/android#reference-the-keystore-from-the-app
# The key store and key password should be identical according to
# https://developer.android.com/studio/publish/app-signing#generate-key
# Don't touch: Keep the line breaks as they are even though it's ugly
- name: Create key.properties
run: |-
echo -e "storePassword=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
keyPassword=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}
storeFile=$(readlink -f key.jks)" >> android/key.properties
- name: Build App Bundle
run: >-
flutter build appbundle
--dart-define=THUNDERFOREST_API_KEY=${{ secrets.THUNDERFOREST_API_KEY }}
--dart-define=IS_RELEASE=true
- name: Build APK
run: >-
flutter build apk
--dart-define=THUNDERFOREST_API_KEY=${{ secrets.THUNDERFOREST_API_KEY }}
--dart-define=IS_RELEASE=true
- name: Upload AAB artifact
uses: actions/upload-artifact@v4
with:
name: aab
path: build/app/outputs/bundle/release/app-release.aab
- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: apk
path: build/app/outputs/flutter-apk/app-release.apk
# F-Droid Build
- name: Override dependencies in pubspec.yaml to be FLOSS
run: |
yq -y -i '.dependency_overrides.geolocator_android.git = {"url": "https://github.com/Zverik/flutter-geolocator.git", "ref": "floss", "path": "geolocator_android"}' pubspec.yaml
- name: Download pub dependencies
run: flutter pub get
- name: Build F-Droid APK
run: >-
flutter build apk
--dart-define=THUNDERFOREST_API_KEY=${{ secrets.THUNDERFOREST_API_KEY }}
--dart-define=IS_RELEASE=true
# Required because F-Droid signs its apk with apksigner which produces a slightly different output than gradle signingConfig
# see: https://f-droid.org/docs/Reproducible_Builds/#reproducible-signatures
- name: Sign with apksigner
run: >-
$(find $ANDROID_SDK_ROOT/build-tools -name apksigner | sort -r | head -n 1) sign
--ks-key-alias ${{ secrets.ANDROID_KEY_ALIAS }}
--ks-pass pass:"${{ secrets.ANDROID_KEYSTORE_PASSWORD }}"
--ks key.jks
build/app/outputs/flutter-apk/app-release.apk
- name: Upload F-Droid APK artifact
uses: actions/upload-artifact@v4
with:
name: apk-fdroid
path: build/app/outputs/flutter-apk/app-release.apk
build_ios:
name: Build for iOS
runs-on: macos-13
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_DISTRIBUTION_CERT_BASE64 }}
P12_PASSWORD: ${{ secrets.APPLE_DISTRIBUTION_CERT_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_MOBILEPROVISION_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
BUILD_EXPORTOPTIONS_BASE64: ${{ secrets.APPLE_EXPORTOPTIONS_BASE64 }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run shared environment setup steps
uses: ./.github/actions/environment_setup
- name: Install Apple certificate and provisioning profile
run: |
# Create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# Import certificate and provisioning profile
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode > $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode > $PP_PATH
# Create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_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
- name: Create IPA
run: |
# Set path to and import ExportOptions.plist
EXPORTOPTIONS_PATH=$RUNNER_TEMP/ExportOptions.plist
echo -n "$BUILD_EXPORTOPTIONS_BASE64" | base64 --decode > $EXPORTOPTIONS_PATH
# Build IPA
flutter build ipa \
--release \
--dart-define=THUNDERFOREST_API_KEY=${{ secrets.THUNDERFOREST_API_KEY }} \
--dart-define=IS_RELEASE=true \
--export-options-plist=$EXPORTOPTIONS_PATH
- name: Upload IPA artifact
uses: actions/upload-artifact@v4
with:
name: ipa
path: build/ios/ipa/*.ipa
- name: Clean up keychain and provisioning profile
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision
release_app:
name: Release App
runs-on: ubuntu-latest
needs: [ build_android, build_ios ]
steps:
- name: Collect artifacts
id: download
uses: actions/download-artifact@v4
with:
path: app
- name: Rename Android Standard APK
run: >-
mv app/apk/app-release.apk
app/OpenStop_${{ github.ref_name }}.apk
- name: Rename Android F-Droid APK
run: >-
mv app/apk-fdroid/app-release.apk
app/OpenStop_fdroid_${{ github.ref_name }}.apk
- name: Rename App Bundle
run: >-
mv app/aab/app-release.aab
app/OpenStop_${{ github.ref_name }}.aab
- name: Rename IPA
run: >-
mv app/ipa/OpenStop.ipa
app/OpenStop_${{ github.ref_name }}.ipa
- name: Upload AAB, APK, IPA to draft release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref }}
name: OpenStop ${{ github.ref_name }}
files: |
app/OpenStop_${{ github.ref_name }}.apk
app/OpenStop_fdroid_${{ github.ref_name }}.apk
app/OpenStop_${{ github.ref_name }}.aab
app/OpenStop_${{ github.ref_name }}.ipa
draft: true
build_web:
name: Build for Web
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run shared environment setup steps
uses: ./.github/actions/environment_setup
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Build web
run: >-
flutter build web
--dart-define=THUNDERFOREST_API_KEY=${{ secrets.THUNDERFOREST_API_KEY }}
--dart-define=IS_RELEASE=true
# This step is mainly required because Google considers a link to a Github markdown file as "editable" which violates their policy.
# Therefore we convert the markdown file to HTML and publish it together with the App via Github pages here.
- name: Convert Privacy Policy to HTML
uses: BaileyJM02/[email protected]
with:
input_path: PRIVACY_POLICY.md
output_dir: build/web/
build_html: true
build_pdf: false
- name: Upload web artifact
uses: actions/upload-pages-artifact@v1
with:
path: 'build/web'
deploy_web:
name: Deploy Webpage
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build_web
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1