Skip to content

Build and deploy apps for testing #2270

Build and deploy apps for testing

Build and deploy apps for testing #2270

Workflow file for this run

name: Build and deploy 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 }}
jobs:
validateActor:
runs-on: ubuntu-latest
outputs:
READY_TO_BUILD: ${{ fromJSON(steps.isExpensifyEmployee.outputs.IS_EXPENSIFY_EMPLOYEE) && fromJSON(steps.hasReadyToBuildLabel.outputs.HAS_READY_TO_BUILD_LABEL) }}
steps:
- name: Is Expensify employee
id: isExpensifyEmployee
run: |
if gh api /orgs/Expensify/teams/expensify-expensify/memberships/${{ github.actor }} --silent; then
echo "IS_EXPENSIFY_EMPLOYEE=true" >> "$GITHUB_OUTPUT"
else
echo "IS_EXPENSIFY_EMPLOYEE=false" >> "$GITHUB_OUTPUT"
fi
env:
GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }}
- id: hasReadyToBuildLabel
name: Set HAS_READY_TO_BUILD_LABEL flag
run: |
echo "HAS_READY_TO_BUILD_LABEL=$(gh pr view "${{ env.PULL_REQUEST_NUMBER }}" --repo Expensify/App --json labels --jq '.labels[].name' | grep -q 'Ready To Build' && echo 'true')" >> "$GITHUB_OUTPUT"
if [[ "$HAS_READY_TO_BUILD_LABEL" != 'true' ]]; then
echo "The 'Ready to Build' label is not attached to the PR #${{ env.PULL_REQUEST_NUMBER }}"
fi
env:
GITHUB_TOKEN: ${{ github.token }}
getBranchRef:
runs-on: ubuntu-latest
needs: validateActor
if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }}
outputs:
REF: ${{ steps.getHeadRef.outputs.REF }}
steps:
- name: Checkout
if: ${{ github.event_name == 'workflow_dispatch' }}
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"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
buildAndroid:
name: Build Android app for testing
uses: ./.github/workflows/buildAndroid.yml
if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }}
needs: [validateActor, getBranchRef]
secrets: inherit
with:
type: adhoc
ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }}
pull_request_number: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }}
uploadAndroid:
name: Upload Android app to S3
needs: [buildAndroid]
runs-on: ubuntu-latest
env:
RUBYOPT: '-rostruct'
outputs:
S3_APK_PATH: ${{ steps.exportS3Path.outputs.S3_APK_PATH }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1.190.0
with:
bundler-cache: true
- name: Download Android build artifacts
uses: actions/download-artifact@v4
with:
path: /tmp/artifacts
pattern: android-artifact-*
merge-multiple: true
- name: Log downloaded artifact paths
run: ls -R /tmp/artifacts
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Upload AdHoc build to S3
run: bundle exec fastlane android upload_s3
env:
apkPath: /tmp/artifacts/${{ needs.buildAndroid.outputs.APK_FILE_NAME }}
S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }}
S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
S3_BUCKET: ad-hoc-expensify-cash
S3_REGION: us-east-1
- name: Export S3 paths
id: exportS3Path
run: |
# $s3APKPath is set from within the Fastfile, android upload_s3 lane
echo "S3_APK_PATH=$s3APKPath" >> "$GITHUB_OUTPUT"
buildIOS:
name: Build iOS app for testing
uses: ./.github/workflows/buildIOS.yml
if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }}
needs: [validateActor, getBranchRef]
secrets: inherit
with:
type: adhoc
ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }}
pull_request_number: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }}
uploadIOS:
name: Upload IOS app to S3
needs: buildIOS
runs-on: ubuntu-latest
outputs:
S3_IPA_PATH: ${{ steps.exportS3Path.outputs.S3_IPA_PATH }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1.190.0
with:
bundler-cache: true
- name: Download IOS build artifacts
uses: actions/download-artifact@v4
with:
path: /tmp/artifacts
pattern: ios-artifact-*
merge-multiple: true
- name: Log downloaded artifact paths
run: ls -R /tmp/artifacts
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Upload AdHoc build to S3
run: bundle exec fastlane ios upload_s3
env:
ipaPath: /tmp/artifacts/${{ needs.buildIOS.outputs.IPA_FILE_NAME }}
S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }}
S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
S3_BUCKET: ad-hoc-expensify-cash
S3_REGION: us-east-1
- name: Export S3 paths
id: exportS3Path
run: |
# $s3IpaPath is set from within the Fastfile, ios upload_s3 lane
echo "S3_IPA_PATH=$s3IpaPath" >> "$GITHUB_OUTPUT"
desktop:
name: Build and deploy Desktop for testing
needs: [validateActor, getBranchRef]
if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }}
runs-on: macos-14-large
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }}
- name: Create .env.adhoc file based on staging and add PULL_REQUEST_NUMBER env to it
run: |
cp .env.staging .env.adhoc
sed -i '' 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc
echo "PULL_REQUEST_NUMBER=$PULL_REQUEST_NUMBER" >> .env.adhoc
- name: Setup Node
uses: ./.github/actions/composite/setupNode
- name: Decrypt Developer ID Certificate
run: cd desktop && gpg --quiet --batch --yes --decrypt --passphrase="$DEVELOPER_ID_SECRET_PASSPHRASE" --output developer_id.p12 developer_id.p12.gpg
env:
DEVELOPER_ID_SECRET_PASSPHRASE: ${{ secrets.DEVELOPER_ID_SECRET_PASSPHRASE }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Build desktop app for testing
run: npm run desktop-build-adhoc
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GCP_GEOLOCATION_API_KEY: $${{ secrets.GCP_GEOLOCATION_API_KEY_STAGING }}
web:
name: Build and deploy Web
needs: [validateActor, getBranchRef]
if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }}
runs-on: ubuntu-latest-xl
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }}
- name: Create .env.adhoc file based on staging and add PULL_REQUEST_NUMBER env to it
run: |
cp .env.staging .env.adhoc
sed -i 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc
echo "PULL_REQUEST_NUMBER=$PULL_REQUEST_NUMBER" >> .env.adhoc
- name: Setup Node
uses: ./.github/actions/composite/setupNode
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Build web for testing
run: npm run build-adhoc
- name: Deploy to S3 for internal testing
run: aws s3 cp --recursive --acl public-read "$GITHUB_WORKSPACE"/dist s3://ad-hoc-expensify-cash/web/"$PULL_REQUEST_NUMBER"
postGithubComment:
runs-on: ubuntu-latest
name: Post a GitHub comment with app download links for testing
needs: [validateActor, getBranchRef, uploadAndroid, uploadIOS, desktop, web]
if: ${{ always() && fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }}
- name: Download Artifact
uses: actions/download-artifact@v4
- name: Publish links to apps for download
uses: ./.github/actions/javascript/postTestBuildComment
with:
PR_NUMBER: ${{ env.PULL_REQUEST_NUMBER }}
GITHUB_TOKEN: ${{ github.token }}
ANDROID: ${{ needs.uploadAndroid.result }}
DESKTOP: ${{ needs.desktop.result }}
IOS: ${{ needs.uploadIOS.result }}
WEB: ${{ needs.web.result }}
ANDROID_LINK: ${{ needs.uploadAndroid.outputs.S3_APK_PATH }}
DESKTOP_LINK: https://ad-hoc-expensify-cash.s3.amazonaws.com/desktop/${{ env.PULL_REQUEST_NUMBER }}/NewExpensify.dmg
IOS_LINK: ${{ needs.uploadIOS.outputs.S3_IPA_PATH }}
WEB_LINK: https://${{ env.PULL_REQUEST_NUMBER }}.pr-testing.expensify.com