When Building the Android app in Debug Mode, The Standard Github Hosted Runner for Private Repos is fine. But for building an app in release mode, the 7GB RAM and 2cpu might not be sufficient and the action fails with out of memory exception.
Here, I have applied some tricks to make the release variant apk to succeed
name: Build Android
on:
workflow_dispatch:
inputs:
app_variant:
type: choice
description: Pick App Variant
options:
- development
- qa
- uat
- nextProd
- beta
required: true
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Remove unused software
run: |
echo "Available storage before:"
sudo df -h
echo
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
echo "Available storage after:"
sudo df -h
echo
echo "Ram Details"
free -h
- name: Increase swapfile
run: |
sudo swapoff -a
sudo fallocate -l 10G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon --show
- name: Checkout
uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- uses: actions/setup-java@v4
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '17'
- name: Setup EAS
uses: expo/expo-github-action@v8
with:
expo-version: latest
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
packager: 'bun'
expo-cache: true
eas-cache: true
- name: Cache Gradle Dependencies and Wrapper
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Make Gradlew Executable
run: cd android && chmod +x ./gradlew
- name: Fetch version from eas config
id: fetch_version
run: |
VERSION=$(eas config --profile production --platform android | grep '"version"' | head -n 1 | sed -E 's/.*"version": "(.*)".*/\1/')
echo "APP_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Fetch Last Commit ID
id: vars
run: |
calculatedSha=$(git rev-parse --short ${{ github.sha }})
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
- name: Create Deployment
id: deployment
uses: bobheadxi/deployments@v1
with:
step: start
token: ${{ secrets.GITHUB_TOKEN }}
env: ${{ github.event.inputs.app_variant }}
desc: 'Deploying to ${{ github.event.inputs.app_variant }}'
ref: ${{ github.ref_name }}
- name: Build Android Release
run: eas build --profile ${{github.event.inputs.app_variant}} --platform android --local --output ${{ github.workspace }}/${{github.event.inputs.app_variant}}-${{env.APP_VERSION}}.apk
- name: Notify on Slack
uses: MeilCli/slack-upload-file@v4.0.17
with:
slack_token: ${{ secrets.SLACK_BOT_TOKEN }}
channel_id: 'C0635NKP2TE'
file_path: ${{github.event.inputs.app_variant}}-${{env.APP_VERSION}}.apk
initial_comment: |
Android Build Successful 🎉
*Build Variant:* `${{github.event.inputs.app_variant}}`
*Version:* `${{env.APP_VERSION}}`
*Branch:* `${{ github.ref_name }}`
*Commit:* <https://github.com/${{ github.repository }}/commit/${{ github.sha }}|${{ env.COMMIT_SHORT_SHA }}>
- name: update deployment status
uses: bobheadxi/deployments@v1
if: always()
with:
step: finish
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
env: ${{ github.event.inputs.app_variant }}
deployment_id: ${{ steps.deployment.outputs.deployment_id }}In the above Github Action, uat and nextProd are release variants.
Increase Build Time
Increase the Build time to 120 minutes so the build will still run even after 60 minutes, if it’s taking more time
timeout-minutes: 120
Remove unused software
GtiHub Runner provides lots of packages that are not necessary for the Android Build which can be deleted.
The Step Remove unused software Deletes unnecessary files and folders in the runner. After running this step, you get around 10GB of space
Increase swapfile
The Standard GitHub Runner Specs is
| Ram Details | Total |
|---|---|
| Memory | 7 GB |
| Swap | 3 GB |
Overall, there is 10GB of RAM. Let’s utilize the 10GB freed-up space in the storage and increase the swapfile size to 10GB
The Step Increase swapfile increases the swapfile size. Now you have virtually 16GB of RAM which should be sufficient to build release variant of apk.
| Ram Details | Total |
|---|---|
| Memory | 7 GB |
| Swap | 10 GB |
Improve Gradle Properties
The Gradle properties in the newly created project allocated bare minimum RAM to build the apk. With the following changes we can utilise the Runner to the Max
org.gradle.jvmargs=-Xmx6g -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.daemon=false
The jvmargs initially was 2g and it can be changed upto 14g. Let’s use 6g which means 6 GB
Note: In the latest versions of gradle 8 and above -XX:MaxPermSize name is changed to -XX:MaxMetaspaceSize=512m
Finally, you can now build with the least resources possible.