Skip to content

Multi-Platform App Build and Publish #14

Multi-Platform App Build and Publish

Multi-Platform App Build and Publish #14

# Workflow name indicating its purpose
name: Multi-Platform App Build and Publish
# Trigger configuration
on:
# Manual trigger through GitHub Actions UI with configurable inputs
workflow_dispatch:
inputs:
# Release channel selection (internal/beta)
release_type:
type: choice
options:
- internal # For internal testing purposes
- beta # For beta testing with external testers
default: internal
description: Release Type
# Toggle for Android Play Store publishing
publish_android:
type: boolean
default: false
description: Publish Android App On Play Store
# Toggle for iOS App Store publishing
publish_ios:
type: boolean
default: false
description: Publish iOS App On App Store
# Toggle for Desktop app publishing (Windows/macOS/Linux)
publish_desktop:
type: boolean
default: false
description: Publish Desktop Apps On App Store
# Toggle for Web app deployment
publish_web:
type: boolean
default: true
description: Publish Web App
# Toggle for iOS build process
# Separated from publishing to allow building without deployment
build_ios:
type: boolean
default: false
description: Build iOS App
# Repository-level permissions configuration
permissions:
# Grant read/write access to repository contents for deployment
contents: write
# Concurrency management configuration
# Controls how multiple workflow runs are handled
concurrency:
# Uses "pages" group to coordinate with GitHub Pages deployments
group: "pages"
# When false, new runs are queued instead of cancelling running ones
# This ensures deployment stability and ordered releases
cancel-in-progress: false
# Job definitions for different platforms
jobs:
# Android Build Job
# Handles compilation and APK generation for Android platform
build_android:
name: Build Android Application
runs-on: ubuntu-latest
steps:
# Check out repository code
- name: Checkout
uses: actions/checkout@v4
# Setup Java development environment
- name: Set up JDK 17
uses: actions/[email protected]
with:
distribution: 'temurin'
java-version: '17'
# Configure Gradle build tool
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Cache Gradle dependencies to speed up builds
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
# Decrypt and prepare required secrets for signing
- uses: ./.github/actions/inflate-secrets
name: Inflate Secrets
with:
keystore: ${{ secrets.ORIGINAL_KEYSTORE_FILE }}
google-services: ${{ secrets.GOOGLESERVICES }}
playstore-creds: ${{ secrets.PLAYSTORECREDS }}
firebase-creds: ${{ secrets.FIREBASECREDS }}
# Build signed release APK
- name: Build Release
env:
KEYSTORE_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_FILE_PASSWORD }}
KEYSTORE_ALIAS: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS }}
KEYSTORE_ALIAS_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS_PASSWORD }}
VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
run: |
./gradlew :mifospay-android:assembleRelease
# Save built APKs as artifacts
- name: Upload Android Artifact
uses: actions/upload-artifact@v4
with:
name: android-app
retention-days: 1
compression-level: 9
path: |
./mifospay-android/build/outputs/apk/demo/release/mifospay-android-demo-release.apk
./mifospay-android/build/outputs/apk/prod/release/mifospay-android-prod-release.apk
# Firebase Distribution Job for Android
# Handles deployment to Firebase App Distribution for testing
publish_android_on_firebase:
name: Deploy Android App On Firebase
needs: [ build_android, generate_release_info ]
runs-on: macos-latest
steps:
# Basic setup steps
- name: Checkout
uses: actions/checkout@v4
# Setup Java environment
- name: Set up JDK 17
uses: actions/[email protected]
with:
distribution: 'temurin'
java-version: '17'
# Configure Gradle
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Setup Ruby for Fastlane automation
- name: Configure Ruby
uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
with:
bundler-cache: true
# Install Fastlane and required plugins for deployment automation
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle install --jobs 4 --retry 3
bundle exec fastlane add_plugin firebase_app_distribution
bundle exec fastlane add_plugin increment_build_number
# Prepare necessary secrets
- uses: ./.github/actions/inflate-secrets
name: Inflate Secrets
with:
keystore: ${{ secrets.ORIGINAL_KEYSTORE_FILE }}
google-services: ${{ secrets.GOOGLESERVICES }}
playstore-creds: ${{ secrets.PLAYSTORECREDS }}
firebase-creds: ${{ secrets.FIREBASECREDS }}
# Retrieve built Android artifacts
- name: Download Android Artifact
uses: actions/download-artifact@v4
with:
name: android-app
path: ./android-artifacts
# Debug: List downloaded artifacts
- name: List downloaded artifacts
run: |
ls -R ./android-artifacts
# Get changelog for Firebase distribution
- name: Download Beta Changelog
uses: actions/download-artifact@v4
with:
name: beta-changelog
# Organize files for Firebase deployment
- name: Move APK to build directory
run: |
mkdir -p ./mifospay-android/build/outputs/apk/prod/release/
mv ./android-artifacts/prod/release/mifospay-android-prod-release.apk ./mifospay-android/build/outputs/apk/prod/release/
mv ./changelogBeta ./mifospay-android/build/outputs/
# Deploy to Firebase App Distribution
- name: ☁️ Deploy to Firebase
env:
VERSION_CODE: ${{ needs.generate_release_info.outputs.version_code }}
run: bundle exec fastlane android deploy_on_firebase
# Play Store Publishing Job
# Handles deployment to Google Play Store
publish_android_on_playstore:
name: Publish Android App On Play Store
needs: [ build_android, generate_release_info ]
if: inputs.publish_android
runs-on: macos-latest
steps:
# Checkout with full history for versioning
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Setup Java environment
- name: Set up JDK 17
uses: actions/[email protected]
with:
distribution: 'temurin'
java-version: '17'
# Setup Ruby for Fastlane
- name: Configure Ruby
uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
with:
bundler-cache: true
# Install Fastlane and plugins for Play Store deployment
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle install --jobs 4 --retry 3
bundle exec fastlane add_plugin firebase_app_distribution
bundle exec fastlane add_plugin increment_build_number
# Setup Gradle build tool
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Prepare necessary secrets
- uses: ./.github/actions/inflate-secrets
name: Inflate Secrets
with:
keystore: ${{ secrets.UPLOAD_KEYSTORE_FILE }}
google-services: ${{ secrets.GOOGLESERVICES }}
playstore-creds: ${{ secrets.PLAYSTORECREDS }}
firebase-creds: ${{ secrets.FIREBASECREDS }}
# Build Android App Bundle for Play Store
- name: Build Release
env:
KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_FILE_PASSWORD }}
KEYSTORE_ALIAS: ${{ secrets.UPLOAD_KEYSTORE_ALIAS }}
KEYSTORE_ALIAS_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_ALIAS_PASSWORD }}
VERSION_CODE: ${{ needs.generate_release_info.outputs.version_code }}
run: |
./gradlew :mifospay-android:bundleRelease
# Save AAB files as artifacts
- name: Archive Build
uses: actions/upload-artifact@v4
with:
name: release-aabs
path: ./**/*.aab
# Deploy to Play Store Internal testing track
- name: Deploy to Playstore Internal
run: bundle exec fastlane deploy_internal
# Promote to beta if specified
- name: Promote Internal to Beta
if: github.event.inputs.release_type == 'beta'
run: bundle exec fastlane promote_to_beta
# iOS Build Job
# Handles compilation and IPA generation for iOS platform
build_ios:
name: Build iOS App
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
# Setup Ruby for Fastlane
- name: Configure Ruby
uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
with:
bundler-cache: true
# Install Fastlane and plugins for iOS automation
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle install --jobs 4 --retry 3
bundle exec fastlane add_plugin firebase_app_distribution
bundle exec fastlane add_plugin increment_build_number
# Build iOS app if enabled
- name: Build iOS App
if: inputs.build_ios
run: bundle exec fastlane ios build_ios
# Save IPA as artifact
- name: Upload iOS Artifact
if: inputs.build_ios
uses: actions/upload-artifact@v4
with:
name: ios-app
retention-days: 1
compression-level: 9
path: mifospay-ios/mifospay-ios-app.ipa
# Firebase Distribution Job for iOS
# Handles deployment to Firebase App Distribution for iOS testing
publish_ios_app_to_firebase:
name: Publish iOS App On Firebase
if: inputs.publish_ios
needs: [ build_ios, generate_release_info ]
runs-on: macos-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
# Setup Ruby for Fastlane
- name: Configure Ruby
uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
with:
bundler-cache: true
# Install Fastlane and plugins
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle install --jobs 4 --retry 3
bundle exec fastlane add_plugin firebase_app_distribution
bundle exec fastlane add_plugin increment_build_number
# Get iOS app artifact
- name: Download iOS App
uses: actions/download-artifact@v4
with:
name: ios-app
# Get changelog for Firebase distribution
- name: Download Beta Changelog
uses: actions/download-artifact@v4
with:
name: beta-changelog
# Organize files for Firebase deployment
- name: Move APK to build directory
run: |
mv *.ipa ./mifospay-ios/
mv changelogBeta ./mifospay-android/build/outputs/
# Deploy to Firebase App Distribution
- name: Upload iOS App to Firebase Distribution
run: bundle exec fastlane ios deploy_on_firebase
# Debug: Show git status
- name: Print `git status`
run: git status
# App Center Publishing Job for iOS
# Handles deployment to App Center for iOS distribution
publish_ios_app_to_app_center:
needs: [ build_ios, generate_release_info ]
name: Publish iOS App On App Center
if: inputs.publish_ios
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
# Get iOS app artifact
- name: Download iOS Artifact
uses: actions/download-artifact@v4
with:
name: ios-app
# Get changelog for App Center
- name: Download Changelog
uses: actions/download-artifact@v4
with:
name: git-changelog
# TODO: Implement App Store publishing
# Desktop Build Job
# Handles compilation for Windows, macOS, and Linux platforms
build_desktop:
name: Build Desktop App
strategy:
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
# Setup Gradle build tool
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Build desktop app for current OS
- name: Build Desktop App
env:
NOTARIZATION_APPLE_ID: ${{ secrets.NOTARIZATION_APPLE_ID }}
NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }}
NOTARIZATION_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }}
run: ./gradlew packageReleaseDistributionForCurrentOS
# Save Windows artifacts (EXE and MSI)
- name: Upload Windows Apps
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v4
with:
name: desktop-app-${{ matrix.os }}
retention-days: 1
compression-level: 9
path: |
./mifospay-desktop/build/compose/binaries/main-release/exe/*.exe
./mifospay-desktop/build/compose/binaries/main-release/msi/*.msi
# Save Linux artifact (DEB)
- name: Upload Linux App
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: desktop-app-${{ matrix.os }}
retention-days: 1
compression-level: 9
path: './mifospay-desktop/build/compose/binaries/main-release/deb/*.deb'
# Save macOS artifact (DMG)
- name: Upload MacOS App
if: matrix.os == 'macos-latest'
uses: actions/upload-artifact@v4
with:
name: desktop-app-${{ matrix.os }}
retention-days: 1
compression-level: 9
path: './mifospay-desktop/build/compose/binaries/main-release/dmg/*.dmg'
# Desktop Publishing Job
# Handles publishing desktop apps to various stores
publish_desktop:
name: Publish Desktop App
needs: [ build_desktop ]
if: inputs.publish_desktop
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Get all desktop artifacts
- name: Download Desktop Artifacts
uses: actions/download-artifact@v4
with:
pattern: desktop-app-*
path: desktop-apps
# TODO: Implement desktop store publishing
# Debug: Show git status
- name: Print `git status`
run: git status
# Web Build Job
# Handles compilation of web application using Kotlin/JS
build_web:
name: Build Web Application
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
# Setup Java environment
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17
# Cache Gradle dependencies
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
# Build web app using Kotlin/JS
- name: Build Web(JS) App
run: ./gradlew jsBrowserDistribution
# Save web app as artifact
- name: Upload Web Artifact
uses: actions/upload-artifact@v4
with:
name: web-app
path: './mifospay-web/build/dist/js/productionExecutable'
# Web Publishing Job
# Handles deployment to GitHub Pages
publish_web:
name: Publish Web App
needs: [ build_web ]
if: inputs.publish_web
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
permissions:
id-token: write
pages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17
# Get web app artifact
- name: Download Web Artifact
uses: actions/download-artifact@v4
with:
name: web-app
path: ./web-app-content
# Configure GitHub Pages
- name: Setup Pages
uses: actions/configure-pages@v5
# Upload web app to GitHub Pages
- name: Upload static files as artifact
uses: actions/upload-pages-artifact@v3
with:
path: './web-app-content'
# Deploy to GitHub Pages
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
# Release Info Generation Job
# Creates version numbers and release notes
generate_release_info:
name: Generate Release Info
runs-on: ubuntu-latest
outputs:
version: ${{ steps.rel_number.outputs.version }}
version_code: ${{ steps.rel_number.outputs.version-code }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Setup Java environment
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
# Configure Gradle
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Generate version number
- uses: ./.github/actions/create-release-number
name: Create Release Number
id: rel_number
# Create release notes
- uses: ./.github/actions/create-release-notes
name: Create Release Notes
with:
tag-name: ${{ steps.rel_number.outputs.version }}
gh-token: ${{ secrets.GITHUB_TOKEN }}
# Save GitHub changelog
- name: Upload GitHub Changelog
uses: actions/upload-artifact@v4
with:
name: git-changelog
path: './mifospay-android/build/outputs/changelogGithub'
# Save beta changelog
- name: Upload Beta Changelog
uses: actions/upload-artifact@v4
with:
name: beta-changelog
path: './mifospay-android/build/outputs/changelogBeta'
# GitHub Release Job
# Creates GitHub release with all built artifacts
github_release:
name: Create Github Release
needs: [ build_android, build_desktop, build_web, build_ios, generate_release_info ]
if: inputs.release_type == 'beta'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Get all build artifacts
- name: Download All Artifacts
uses: actions/download-artifact@v4
with:
path: ./all-artifacts
# Debug: Show downloaded files
- name: Display structure of downloaded files
run: ls -R ./all-artifacts
# Create ZIP archive of web app
- name: Archive Web Build
shell: pwsh
run: |
Compress-Archive -Path './all-artifacts/web-app/*' -DestinationPath './all-artifacts/mifospay-web-app.zip'
# Rename Ubuntu desktop artifact for consistency
- name: Rename Ubuntu Desktop Artifact
run: |
mv ./all-artifacts/desktop-app-ubuntu-latest/mifoswallet_1.0.0-1_amd64.deb ./all-artifacts/desktop-app-ubuntu-latest/MifosWallet-1.0.0.deb
# Get changelog for release
- name: Download Git Changelog
uses: actions/download-artifact@v4
with:
name: git-changelog
# Create GitHub pre-release with all artifacts
- name: Create Github Pre-Release
uses: softprops/[email protected]
with:
tag_name: ${{ needs.generate_release_info.outputs.version }}
body_path: ./all-artifacts/git-changelog/changelogGithub
draft: false
prerelease: true
files: |
./all-artifacts/android-app/prod/release/mifospay-android-prod-release.apk
./all-artifacts/android-app/demo/release/mifospay-android-demo-release.apk
./all-artifacts/desktop-app-windows-latest/exe/MifosWallet-1.0.0.exe
./all-artifacts/desktop-app-windows-latest/msi/MifosWallet-1.0.0.msi
./all-artifacts/desktop-app-macos-latest/MifosWallet-1.0.0.dmg
./all-artifacts/desktop-app-ubuntu-latest/MifosWallet-1.0.0.deb
./all-artifacts/mifospay-web-app.zip