Skip to content

Build and deploy apps for testing #7719

Build and deploy apps for testing

Build and deploy apps for testing #7719

Workflow file for this run

name: Build and deploy apps for testing
on:
workflow_dispatch:
inputs:
# If not specified, only build iOS and Android apps from the main branch of Expensify/App
APP_PULL_REQUEST_URL:
description: The Expensify/App pull request URL (e.g., https://github.com/Expensify/App/pull/12345). Defaults to main.
required: false
default: ''
# Pull Request URL from Mobile-Expensify repo for correct placement of OD app. It will take precedence over MOBILE-EXPENSIFY from App's PR description if both are specified. If nothing is specified defaults to Mobile-Expensify's main
MOBILE_EXPENSIFY_PULL_REQUEST_URL:
description: The Expensify/Mobile-Expensify pull request URL. Defaults to main. Overrides MOBILE-EXPENSIFY set in App's PR description.
required: false
default: ''
REVIEWED_CODE:
description: I reviewed this pull request and verified that it does not contain any malicious code.
type: boolean
required: true
default: false
WEB:
description: Should build web app?
type: boolean
default: true
IOS:
description: Should build iOS app?
type: boolean
default: true
ANDROID:
description: Should build android app?
type: boolean
default: true
FORCE_NATIVE_BUILD:
description: Force a full native build, bypassing Rock remote cache
type: boolean
default: false
jobs:
prep:
runs-on: blacksmith-4vcpu-ubuntu-2404
outputs:
APP_REF: ${{ steps.getHeadRef.outputs.REF || 'main' }}
APP_PR_NUMBER: ${{ steps.extractAppPRNumber.outputs.PR_NUMBER }}
steps:
- name: Checkout
uses: useblacksmith/checkout@c9796daa2a4bdebdab5bd16be2c09a70cd4e1121 # v1
- name: Validate that user is an Expensify employee
uses: ./.github/actions/composite/validateActor
with:
REQUIRE_APP_DEPLOYER: false
OS_BOTIFY_TOKEN: ${{ secrets.OS_BOTIFY_COMMIT_TOKEN }}
- name: Validate that the user reviewed the pull request before running a test build
if: ${{ !inputs.REVIEWED_CODE }}
run: |
echo "::error::🕵️‍♀️ Please carefully review the pull request before running a test build to ensure it does not contain any malicious code"
exit 1
- name: Extract App PR number from URL
id: extractAppPRNumber
if: ${{ inputs.APP_PULL_REQUEST_URL != '' }}
run: |
PR_NUMBER=$(echo '${{ inputs.APP_PULL_REQUEST_URL }}' | sed -E 's|.*/pull/([0-9]+).*|\1|')
if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
echo "::error::❌ Could not extract PR number from URL. Please provide a valid GitHub PR URL (e.g., https://github.com/Expensify/App/pull/12345)"
exit 1
fi
echo "PR_NUMBER=$PR_NUMBER" >> "$GITHUB_OUTPUT"
- name: Check if App pull request number is correct
id: getHeadRef
run: |
set -e
if [ -z "${{ steps.extractAppPRNumber.outputs.PR_NUMBER }}" ]; then
echo "REF=" >> "$GITHUB_OUTPUT"
else
echo "REF=$(gh pr view ${{ steps.extractAppPRNumber.outputs.PR_NUMBER }} --json headRefOid --jq '.headRefOid')" >> "$GITHUB_OUTPUT"
fi
env:
GITHUB_TOKEN: ${{ github.token }}
# Resolves the Mobile-Expensify ref from the explicit ME PR URL or the App PR's MOBILE-EXPENSIFY entry.
# `needs: [prep]` gates this behind prep's actor validation before any token is used.
getMobileExpensifyRef:
needs: [prep]
uses: ./.github/workflows/resolveMobileExpensifyRef.yml
with:
APP_PULL_REQUEST_URL: ${{ inputs.APP_PULL_REQUEST_URL }}
MOBILE_EXPENSIFY_PULL_REQUEST_URL: ${{ inputs.MOBILE_EXPENSIFY_PULL_REQUEST_URL }}
secrets:
OS_BOTIFY_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }}
buildApps:
needs: [prep, getMobileExpensifyRef]
uses: ./.github/workflows/buildAdHoc.yml
with:
APP_REF: ${{ needs.prep.outputs.APP_REF }}
APP_PR_NUMBER: ${{ needs.prep.outputs.APP_PR_NUMBER }}
# Fall back to Mobile-Expensify main when nothing is resolved (test builds track the latest OldDot).
MOBILE_EXPENSIFY_REF: ${{ needs.getMobileExpensifyRef.outputs.MOBILE_EXPENSIFY_REF || 'main' }}
MOBILE_EXPENSIFY_PR: ${{ needs.getMobileExpensifyRef.outputs.MOBILE_EXPENSIFY_PR }}
BUILD_WEB: ${{ inputs.WEB && 'true' || 'false' }}
BUILD_IOS: ${{ inputs.IOS && 'true' || 'false' }}
BUILD_ANDROID: ${{ inputs.ANDROID && 'true' || 'false' }}
FORCE_NATIVE_BUILD: ${{ inputs.FORCE_NATIVE_BUILD && 'true' || 'false' }}
secrets: inherit