Skip to content

Commit

Permalink
Merge pull request #56655 from software-mansion-labs/jnowakow/build-h…
Browse files Browse the repository at this point in the history
…ybrid-adhoc-from-mobile-expensify-only

[No QA]Allow to build adhoc hybrid app from ND main and OD PR
  • Loading branch information
Julesssss authored Feb 18, 2025
2 parents 1d6d1e4 + b00c2ba commit caadb2e
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 53 deletions.
126 changes: 73 additions & 53 deletions .github/workflows/testBuildHybrid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,50 @@ name: Build and deploy hybrid apps for testing
on:
workflow_dispatch:
inputs:
PULL_REQUEST_NUMBER:
description: Pull Request number for correct placement of apps
required: true
pull_request_target:
types: [opened, synchronize, labeled]
branches: ['*ci-test/**']

env:
PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }}
APP_PULL_REQUEST_NUMBER:
description: Pull Request number from App repo for correct placement of ND app. If not specified defaults to main branch.
required: false
default: ''
HYBRIDAPP_PULL_REQUEST_NUMBER:
description: Pull Request number from Mobile-Expensify repo for correct placement of OD app. It will take precedence over MOBILE-EXPENSIFY from App's PR description if both specified. If nothing is specified defaults to Mobile-Expensify's main
required: false
default: ''

jobs:
prep:
runs-on: ubuntu-latest
outputs:
REF: ${{ github.event.pull_request.head.sha || steps.getHeadRef.outputs.REF }}
READY_TO_BUILD: ${{ steps.readyToBuild.outputs.READY_TO_BUILD }}
steps:
- name: Checkout
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: actions/checkout@v4

- 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: Check if PR has Ready to Build label
id: readyToBuild
- name: Validate input
run: |
LABELS=$(gh pr view "${{ env.PULL_REQUEST_NUMBER }}" --repo Expensify/App --json labels --jq '.labels[].name')
if echo "$LABELS" | grep -q 'Ready To Build'; then
echo "::notice::✅ PR ${{ env.PULL_REQUEST_NUMBER }} has 'Ready to Build' label"
echo "READY_TO_BUILD=true" >> "$GITHUB_OUTPUT"
else
echo "::error::❌ PR ${{ env.PULL_REQUEST_NUMBER }} does not have 'Ready to Build' label"
echo "READY_TO_BUILD=false" >> "$GITHUB_OUTPUT"
if [[ -z "${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }}" && -z "${{ github.event.inputs.HYBRIDAPP_PULL_REQUEST_NUMBER }}" ]]; then
echo "Invalid input. You have to pass at least one PR number"
exit 1
fi
env:
GITHUB_TOKEN: ${{ github.token }}
getNewDotRef:
runs-on: ubuntu-latest
needs: [prep]
outputs:
REF: ${{ steps.getHeadRef.outputs.REF }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check if pull request number is correct
if: ${{ github.event_name == 'workflow_dispatch' }}
id: getHeadRef
run: |
set -e
echo "REF=$(gh pr view ${{ github.event.inputs.PULL_REQUEST_NUMBER }} --json headRefOid --jq '.headRefOid')" >> "$GITHUB_OUTPUT"
if [[ -z "${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }}" ]]; then
echo "REF=" >> "$GITHUB_OUTPUT"
else
echo "REF=$(gh pr view ${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }} -R Expensify/App --json headRefOid --jq '.headRefOid')" >> "$GITHUB_OUTPUT"
fi
env:
GITHUB_TOKEN: ${{ github.token }}

Expand All @@ -67,10 +63,12 @@ jobs:
github-token: ${{ github.token }}
result-encoding: string
script: |
if (!'${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }}') return '';
const pullRequest = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: '${{ env.PULL_REQUEST_NUMBER }}',
pull_number: '${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }}',
});
const body = pullRequest.data.body;
Expand All @@ -79,9 +77,9 @@ jobs:
return found.trim();
getOldDotBranchRef:
getOldDotRef:
runs-on: ubuntu-latest
needs: getOldDotPR
needs: [getOldDotPR]
outputs:
OLD_DOT_REF: ${{ steps.getHeadRef.outputs.REF }}
steps:
Expand All @@ -92,20 +90,21 @@ jobs:
id: getHeadRef
run: |
set -e
if [[ -z "${{ needs.getOldDotPR.outputs.OLD_DOT_PR }}" ]]; then
if [[ -z "${{ github.event.inputs.HYBRIDAPP_PULL_REQUEST_NUMBER }}" && -z "${{ needs.getOldDotPR.outputs.OLD_DOT_PR }}" ]]; then
echo "REF=" >> "$GITHUB_OUTPUT"
else
echo "REF=$(gh pr view ${{ needs.getOldDotPR.outputs.OLD_DOT_PR }} -R Expensify/Mobile-Expensify --json headRefOid --jq '.headRefOid')" >> "$GITHUB_OUTPUT"
echo "REF=$(gh pr view ${{ github.event.inputs.HYBRIDAPP_PULL_REQUEST_NUMBER || needs.getOldDotPR.outputs.OLD_DOT_PR }} -R Expensify/Mobile-Expensify --json headRefOid --jq '.headRefOid')" >> "$GITHUB_OUTPUT"
fi
env:
GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }}


postGitHubCommentBuildStarted:
runs-on: ubuntu-latest
needs: [prep]
needs: [getNewDotRef, getOldDotPR, getOldDotRef]
steps:
- name: Add build start comment
- name: Add build start comment to ND PR
if: ${{ github.event.inputs.APP_PULL_REQUEST_NUMBER != ''}}
uses: actions/github-script@v7
with:
github-token: ${{ github.token }}
Expand All @@ -114,13 +113,27 @@ jobs:
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: process.env.PULL_REQUEST_NUMBER,
issue_number: ${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }},
body: `🚧 @${{ github.actor }} has triggered a test hybrid app build. You can view the [workflow run here](${workflowURL}).`
});
- name: Add build start comment to OD PR
if: ${{ github.event.inputs.HYBRIDAPP_PULL_REQUEST_NUMBER != '' || needs.getOldDotPR.outputs.OLD_DOT_PR != '' }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.OS_BOTIFY_TOKEN }}
script: |
const workflowURL = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
github.rest.issues.createComment({
owner: context.repo.owner,
repo: 'Mobile-Expensify',
issue_number: ${{ github.event.inputs.HYBRIDAPP_PULL_REQUEST_NUMBER || needs.getOldDotPR.outputs.OLD_DOT_PR }},
body: `🚧 @${{ github.actor }} has triggered a test hybrid app build. You can view the [workflow run here](${workflowURL}).`
});
androidHybrid:
name: Build Android HybridApp
needs: [prep, getOldDotBranchRef]
needs: [getNewDotRef, getOldDotPR, getOldDotRef]
runs-on: ubuntu-latest-xl
outputs:
S3_APK_PATH: ${{ steps.exportAndroidS3Path.outputs.S3_APK_PATH }}
Expand All @@ -129,21 +142,25 @@ jobs:
uses: actions/checkout@v4
with:
submodules: true
ref: ${{ needs.prep.outputs.REF }}
ref: ${{ needs.getNewDotRef.outputs.REF || 'main' }}
token: ${{ secrets.OS_BOTIFY_TOKEN }}
# fetch-depth: 0 is required in order to fetch the correct submodule branch
fetch-depth: 0

- name: Update submodule to match main
run: |
git submodule update --init --remote
if [[ -z "${{ needs.getOldDotRef.outputs.OLD_DOT_REF }}" ]]; then
echo "Building from Mobile-Expensify main branch"
fi
- name: Checkout Old Dot to author specified branch or commit
if: ${{ needs.getOldDotBranchRef.outputs.OLD_DOT_REF != '' }}
if: ${{ needs.getOldDotRef.outputs.OLD_DOT_REF != '' }}
run: |
cd Mobile-Expensify
git fetch origin ${{ needs.getOldDotBranchRef.outputs.OLD_DOT_REF }}
git checkout ${{ needs.getOldDotBranchRef.outputs.OLD_DOT_REF }}
git fetch origin ${{ needs.getOldDotRef.outputs.OLD_DOT_REF }}
git checkout ${{ needs.getOldDotRef.outputs.OLD_DOT_REF }}
echo "Building from https://github.com/Expensify/Mobile-Expensify/pull/${{ github.event.inputs.HYBRIDAPP_PULL_REQUEST_NUMBER || needs.getOldDotPR.outputs.OLD_DOT_PR }}"
- name: Configure MapBox SDK
run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }}
Expand All @@ -163,7 +180,7 @@ jobs:
run: |
cp .env.staging .env.adhoc
sed -i 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc
echo "PULL_REQUEST_NUMBER=${{ inputs.pull_request_number }}" >> .env.adhoc
echo "PULL_REQUEST_NUMBER=${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }}" >> .env.adhoc
- name: Setup Java
uses: actions/setup-java@v4
Expand Down Expand Up @@ -231,7 +248,7 @@ jobs:
iosHybrid:
name: Build and deploy iOS for testing
needs: [prep, getOldDotBranchRef]
needs: [getNewDotRef, getOldDotPR, getOldDotRef]
env:
DEVELOPER_DIR: /Applications/Xcode_16.2.0.app/Contents/Developer
runs-on: macos-15-xlarge
Expand All @@ -240,21 +257,25 @@ jobs:
uses: actions/checkout@v4
with:
submodules: true
ref: ${{ needs.prep.outputs.REF }}
ref: ${{ needs.getNewDotRef.outputs.REF || 'main'}}
token: ${{ secrets.OS_BOTIFY_TOKEN }}
# fetch-depth: 0 is required in order to fetch the correct submodule branch
fetch-depth: 0

- name: Update submodule to match main
run: |
git submodule update --init --remote
if [[ -z "${{ needs.getOldDotRef.outputs.OLD_DOT_REF }}" ]]; then
echo "Building from Mobile-Expensify main branch"
fi
- name: Checkout Old Dot to author specified branch or commit
if: ${{ needs.getOldDotBranchRef.outputs.OLD_DOT_REF != '' }}
if: ${{ needs.getOldDotRef.outputs.OLD_DOT_REF != '' }}
run: |
cd Mobile-Expensify
git fetch origin ${{ needs.getOldDotBranchRef.outputs.OLD_DOT_REF }}
git checkout ${{ needs.getOldDotBranchRef.outputs.OLD_DOT_REF }}
git fetch origin ${{ needs.getOldDotRef.outputs.OLD_DOT_REF }}
git checkout ${{ needs.getOldDotRef.outputs.OLD_DOT_REF }}
echo "Building from https://github.com/Expensify/Mobile-Expensify/pull/${{ github.event.inputs.HYBRIDAPP_PULL_REQUEST_NUMBER || needs.getOldDotPR.outputs.OLD_DOT_PR }}"
- name: Configure MapBox SDK
run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }}
Expand All @@ -269,7 +290,7 @@ jobs:
run: |
cp .env.staging .env.adhoc
sed -i '' 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc
echo "PULL_REQUEST_NUMBER=$PULL_REQUEST_NUMBER" >> .env.adhoc
echo "PULL_REQUEST_NUMBER=${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }}" >> .env.adhoc
- name: Setup Ruby
uses: ruby/[email protected]
Expand Down Expand Up @@ -337,13 +358,12 @@ jobs:
postGithubComment:
runs-on: ubuntu-latest
name: Post a GitHub comment with app download links for testing
needs: [prep, androidHybrid, iosHybrid]
if: ${{ always() && needs.prep.outputs.READY_TO_BUILD == 'true' }}
needs: [getNewDotRef, androidHybrid, iosHybrid]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.prep.outputs.REF }}
ref: ${{ needs.getNewDotRef.outputs.REF }}

- name: Download Artifact
uses: actions/download-artifact@v4
Expand All @@ -362,7 +382,7 @@ jobs:
- name: Publish links to apps for download
uses: ./.github/actions/javascript/postTestBuildComment
with:
PR_NUMBER: ${{ env.PULL_REQUEST_NUMBER }}
PR_NUMBER: ${{ github.event.inputs.APP_PULL_REQUEST_NUMBER }}
GITHUB_TOKEN: ${{ github.token }}
ANDROID: ${{ needs.androidHybrid.result }}
IOS: ${{ needs.iosHybrid.result }}
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,16 @@ The [`lockDeploys` workflow](https://github.com/Expensify/App/blob/main/.github/
### finishReleaseCycle
The [`finishReleaseCycle` workflow](https://github.com/Expensify/App/blob/main/.github/workflows/finishReleaseCycle.yml) executes when the `StagingDeployCash` is closed. It updates the `production` branch from `staging` (triggering a production deploy), deploys `main` to staging (with a new `PATCH` version), and creates a new `StagingDeployCash` deploy checklist.

### testBuild
The [`testBuild` workflow](https://github.com/Expensify/App/blob/main/.github/workflows/testBuild.yml) builds ad-hoc staging apps (standalone iOS, standalone Android, web, and desktop) directly from pull requests in the App repository. This process enables testers to review modifications before they are merged into the main branch and deployed to the staging environment. To initiate this workflow, the PR number from the App repository is required as input.

### testBuildHybrid
The [`testBuildHybrid` workflow](https://github.com/Expensify/App/blob/main/.github/workflows/testBuildHybrid.yml) builds ad-hoc staging versions of hybrid apps (iOS and Android) from pull requests submitted to the App and Mobile-Expensify repositories. This workflow facilitates testing changes by accepting up to two inputs:
- A PR number from the App repository for testing New Dot (ND) changes.
- A PR number from the Mobile-Expensify repository for testing Old Dot (OD) changes.

Both PR numbers can be entered simultaneously if the changes from both repositories need to be combined and tested. Additionally, contributors can explicitly link related PRs from the Mobile-Expensify repository in the App repository PR description if required. Guidance on linking PRs can be found [in PR template](https://github.com/Expensify/App/blob/main/.github/PULL_REQUEST_TEMPLATE.md?plain=1#L25-L30)

## Local production builds
Sometimes it might be beneficial to generate a local production version instead of testing on production. Follow the steps below for each client:

Expand Down

0 comments on commit caadb2e

Please sign in to comment.