Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 69 additions & 2 deletions .github/workflows/mobile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,72 @@ jobs:
- name: Bundle (expo export)
run: pnpm export

# Produce a standalone, installable companion-app APK without consuming EAS build
# credits. The native project remains generated output and is not committed.
android-apk:
if: github.event_name != 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v5

- uses: pnpm/action-setup@v6

- uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
cache: pnpm

- name: Set up JDK
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '17'

- name: Set up Android SDK
uses: android-actions/setup-android@v4
with:
log-accepted-android-sdk-licenses: false
packages: 'platform-tools platforms;android-36 build-tools;36.0.0 ndk;27.1.12297006'

- name: Install
working-directory: .
run: pnpm install --frozen-lockfile

- name: Generate Android project
run: pnpm exec expo prebuild --platform android --clean --no-install

# Expo/RN debuggable variants omit the embedded JS bundle and require a
# Metro server. Release embeds the bundle; Expo's generated project signs
# it with the debug keystore, making it installable but not store-ready.
- name: Build standalone APK
run: ./android/gradlew --no-daemon --stacktrace -p android :app:assembleRelease

- name: Upload standalone APK
uses: actions/upload-artifact@v4
with:
name: tronbrowser-android-preview-${{ github.sha }}
path: apps/mobile/android/app/build/outputs/apk/release/app-release.apk
if-no-files-found: error
overwrite: true
retention-days: 14

- name: Add artifact instructions
run: |
{
echo '### TronBrowser Android preview APK'
echo
echo 'Download the `tronbrowser-android-preview-*` artifact from this workflow run.'
echo 'After extracting it, install with `adb install -r app-release.apk`.'
} >> "$GITHUB_STEP_SUMMARY"

# Cloud build + optional store submit via EAS. Requires the EXPO_TOKEN repo
# secret (Expo account access token). iOS/Android signing credentials are
# managed by EAS (`eas credentials`) — not stored here.
eas-build:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- uses: actions/checkout@v5

Expand All @@ -100,9 +160,16 @@ jobs:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- name: Validate EAS request
run: |
if [[ '${{ inputs.submit }}' == 'true' && '${{ inputs.profile }}' != 'production' ]]; then
echo '::error::Store submission requires the production build profile.'
exit 1
fi

- name: EAS build
run: eas build --platform ${{ inputs.platform }} --profile ${{ inputs.profile }} --non-interactive --no-wait
run: eas build --platform ${{ inputs.platform }} --profile ${{ inputs.profile }} --non-interactive

- name: EAS submit
if: ${{ inputs.submit }}
run: eas submit --platform ${{ inputs.platform }} --profile ${{ inputs.profile }} --non-interactive --latest
run: eas submit --platform ${{ inputs.platform }} --profile production --non-interactive --latest
27 changes: 24 additions & 3 deletions apps/mobile/BUILD_READINESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ The exception is declared in `package.json`; typecheck, tests, lint, and both
platform bundles remain the CI acceptance checks. Expo Doctor is a
network-backed local diagnostic and is not run in CI.

## GitHub Actions preview APK

Every mobile pull request and push to `main` also generates the Android native
project and runs Gradle on a GitHub-hosted runner. Download the
`tronbrowser-android-preview-*` artifact from the `Mobile` workflow, extract it,
then install the APK on a connected Android device:

```bash
adb install -r app-release.apk
```

If another build of the app is installed with a different signing key, uninstall
that build before installing this preview APK.

This standalone build embeds its JavaScript bundle and is signed with the
generated debug keystore for sideload testing. It is not store-signed. The job
does not use Expo EAS credits, publish an app, or commit the generated `android/`
directory.

## EAS preview build

The app is linked to the `profullstack/tronbrowserdev` EAS project. Cloud builds
Expand All @@ -40,6 +59,8 @@ After the secret is present, run the `Mobile` workflow manually with:
- profile: `preview`
- submit: `false`

The workflow starts an asynchronous EAS build. Its EAS build URL is the handoff
artifact for review. Store submission remains a separate production step and
requires the corresponding Apple or Google developer account and signing setup.
The workflow waits for EAS to finish, so a successful Actions job means the
remote build completed rather than merely entered the queue. Its EAS build URL
is the handoff artifact for review. Store submission is only available with the
`production` build profile and still requires the corresponding Apple or Google
developer account and signing setup.
5 changes: 4 additions & 1 deletion apps/mobile/eas.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
"distribution": "internal"
},
"preview": {
"distribution": "internal"
"distribution": "internal",
"android": {
"buildType": "apk"
}
},
"production": {
"autoIncrement": true
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"devDependencies": {
"@babel/core": "^7.25.0",
"@types/react": "~19.2.17",
"babel-preset-expo": "~57.0.5",
"typescript": "^5.6.3",
"vitest": "^2.1.4"
}
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading