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
165 changes: 132 additions & 33 deletions .github/workflows/eas-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,104 @@
# This workflow is used to trigger a build on EAS.
# Can be triggered manually from the actions tab.

# This action accepts those inputs:
# `environment`, which is used to generate a build for a specific environment (development, staging, QA, production). We use staging by default.
# `android`, true by default, set to true if you don't want to trigger build for Android.
# `ios`, false by default, set to true if you want to trigger build for IOS.

# Before triggering the build, we run a pre-build script to generate the necessary native folders based on the APP_ENV.
# Based on the ANDROID and IOS inputs, we trigger the build for the corresponding platform with the corresponding flags.

# 🚨 GITHUB SECRETS REQUIRED:
# - EXPO_TOKEN: Expo token to authenticate with EAS
# - You can get it from https://expo.dev/settings/access-tokens
# - EXPO_TOKEN: Expo token to authenticate with EAS to sync version numbers and submit the build.
# You can get it from https://expo.dev/settings/access-tokens
# - NEW_VERSION_NUMBER_PAT: A fine-grained Personal Access Token.
# This token is used to commit and push to protected branches.
# You can generate one from here: https://github.com/settings/tokens?type=beta
# Set the token name to something meaningful, e.g. "New version number PAT for <Project name>".
# Set the Repository access to "Only select repositories" and select this repository.
# Set the following Repo permissions:
# - Contents: Read & write (to commit and push)
# Make sure to add it to the repo secrets with the name NEW_VERSION_NUMBER_PAT:
# - Go to Repository Settings > Secrets and variables > Actions > New repository secret
# - Name: NEW_VERSION_NUMBER_PAT
# - Value: The Personal Access Token you created

name: 'EAS Build (Android & IOS) (EAS)'
name: 'Build & Deploy'

on:
workflow_dispatch:
inputs:
environment:
platform:
type: choice
description: 'Environment'
required: true
default: 'staging'
description: Platform to build for
options:
- development
- staging
- qa
- production
android:
type: boolean
description: 'Build for Android'
required: true
default: true
ios:
- android
- ios
new-version:
type: string
description: 'New version (e.g. 1.0.0) (optional)'
auto-submit:
type: boolean
description: 'Build for iOS'
required: true
description: 'Auto-submit the build to the store'
required: false
default: true

jobs:
Build:
validate-new-version:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
if: inputs.new-version
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js
if: inputs.new-version
uses: actions/setup-node@v4
with:
node-version: 20
- name: Validate new version
if: inputs.new-version
run: |
CURRENT_VERSION=$(node -p "require('./package.json').version")
NEW_VERSION="${{ inputs.new-version }}"

echo "Current version: $CURRENT_VERSION"
echo "New version: $NEW_VERSION"

npx semver -r ">=$CURRENT_VERSION" "$NEW_VERSION" > /dev/null || (echo "❌ New version must be greater than or equal to current version ($CURRENT_VERSION)" && exit 1)

echo "✅ New version is valid"

build:
needs: validate-new-version
runs-on: ${{ inputs.platform == 'ios' && 'macos-latest' || 'ubuntu-latest' }}
permissions:
contents: write
environment: ${{ github.ref_name == 'main' && 'production' || github.ref_name == 'staging' && 'staging' || github.ref_name == 'qa' && 'qa' || github.ref_name == 'development' && 'development' }}
steps:
- name: Check for EXPO_TOKEN
- name: Set environment variable
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "ENV=production" >> $GITHUB_ENV
elif [[ "${{ github.ref_name }}" == "staging" ]]; then
echo "ENV=staging" >> $GITHUB_ENV
elif [[ "${{ github.ref_name }}" == "qa" ]]; then
echo "ENV=qa" >> $GITHUB_ENV
elif [[ "${{ github.ref_name }}" == "development" ]]; then
echo "ENV=development" >> $GITHUB_ENV
else
echo "Invalid branch: ${{ github.ref_name }}. You can only build for main, staging, qa or development branches."
exit 1
fi
- name: Check if all required secrets exist
run: |
if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions"
exit 1
fi
if [ -z "${{ secrets.NEW_VERSION_NUMBER_PAT }}" ]; then
echo "NEW_VERSION_NUMBER_PAT secret not found. Please create a fine-grained Personal Access Token following the instructions in the workflow file."
exit 1
fi

- name: 📦 Setup Expo and EAS
uses: expo/expo-github-action@v8
Expand All @@ -65,17 +115,66 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.NEW_VERSION_NUMBER_PAT }}

- name: 📦 Setup Node + PNPM + install deps
uses: ./.github/actions/setup-node-pnpm-install

- name: Create environment file
run: echo "${{ secrets.ENVIRONMENT_FILE }}" > .env.${{ env.ENV }}

- name: Update version in package.json
if: inputs.new-version
run: |
CURRENT_VERSION=$(node -p "require('./package.json').version")
if [ "$CURRENT_VERSION" == "${{inputs.new-version}}" ]; then
echo "Current version is already ${{ inputs.new-version }}, no need to update"
exit 0
fi

git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
pnpm version ${{ inputs.new-version }} -m "chore: set app version to ${{ inputs.new-version }}"

- name: Setup latest version of Xcode
uses: maxim-lobanov/setup-xcode@v1
if: inputs.platform == 'ios'
with:
xcode-version: latest

- name: Set Up JDK
uses: actions/setup-java@v3
if: inputs.platform == 'android'
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '17'

- name: ⚙️ Run Prebuild
run: pnpm prebuild:${{ inputs.environment }}
run: pnpm prebuild:${{ env.ENV }}

- name: 📱 Run Android Build
if: ${{ inputs.android == true }}
run: pnpm build:${{ inputs.environment }}:android --non-interactive --no-wait --message "Build ${{ inputs.environment }}"
- name: 📱 Run Build for ${{ inputs.platform }}
run: |
pnpm build:${{ env.ENV }}:${{ inputs.platform }} --non-interactive --no-wait --message "Build ${{ env.ENV }} for ${{ inputs.platform }}" --local
if [ "${{ inputs.platform }}" = "android" ]; then
ls -1 ./*.aab > path.txt
elif [ "${{ inputs.platform }}" = "ios" ]; then
ls -1 ./*.ipa > path.txt
fi
- name: Upload ${{ inputs.platform }} Build
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.platform }}-build-${{ env.ENV }}
path: |
*.apks
*.apk
*.aab
*.ipa

- name: 📱 Submit ${{ inputs.platform }} app to the store
if: inputs.auto-submit
run: pnpm submit:${{ env.ENV }}:mobile --platform=${{ inputs.platform }} --path=$(cat path.txt) --no-wait --non-interactive

- name: 📱 Run IOS Build
if: ${{ inputs.ios == true }}
run: pnpm build:${{ inputs.environment }}:ios --non-interactive --no-wait --message "Build ${{ inputs.environment }}"
- name: 📦 Push changes to repository
if: inputs.new-version
run: |
git push || echo "Skipping push: version was already updated."
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ yarn-error.log

# macOS
.DS_Store

# artifacts
*.apks
*.apk
*.ipa

*.aab

# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb
# The following patterns were generated by expo-cli
Expand Down
3 changes: 3 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
ios: {
supportsTablet: true,
bundleIdentifier: Env.BUNDLE_ID,
config: {
usesNonExemptEncryption: false,
},
},
experiments: {
typedRoutes: true,
Expand Down
59 changes: 48 additions & 11 deletions eas.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"cli": {
"version": ">= 0.57.0"
"version": ">= 0.57.0",
"appVersionSource": "remote"
},
"build": {
"production": {
"autoIncrement": true,
"channel": "production",
"distribution": "store",
"pnpm": "8.15.4",
Expand All @@ -17,69 +19,76 @@
"env": {
"EXPO_NO_DOTENV": "1",
"APP_ENV": "production",
"FLIPPER_DISABLE": "1"
"FLIPPER_DISABLE": "1",
"EAS_NO_DOCTOR": "1"
},
"prebuildCommand": "prebuild --skip-dependency-update react",
"cache": {
"key": "eas-1"
}
},
"staging": {
"autoIncrement": true,
"channel": "staging",
"distribution": "store",
"pnpm": "8.15.4",
"ios": {
"image": "latest"
},
"android": {
"buildType": "apk",
"buildType": "app-bundle",
"image": "latest"
},
"env": {
"APP_ENV": "staging",
"EXPO_NO_DOTENV": "1",
"FLIPPER_DISABLE": "1"
"FLIPPER_DISABLE": "1",
"EAS_NO_DOCTOR": "1"
},
"prebuildCommand": "prebuild --skip-dependency-update react",
"cache": {
"key": "eas-1"
}
},
"qa": {
"autoIncrement": true,
"channel": "qa",
"distribution": "store",
"pnpm": "8.15.4",
"ios": {
"image": "latest"
},
"android": {
"buildType": "apk",
"buildType": "app-bundle",
"image": "latest"
},
"env": {
"APP_ENV": "qa",
"EXPO_NO_DOTENV": "1",
"FLIPPER_DISABLE": "1"
"FLIPPER_DISABLE": "1",
"EAS_NO_DOCTOR": "1"
},

"prebuildCommand": "prebuild --skip-dependency-update react",
"cache": {
"key": "eas-1"
}
},
"development": {
"autoIncrement": true,
"developmentClient": true,
"distribution": "internal",
"distribution": "store",
"pnpm": "8.15.4",
"ios": {
"image": "latest"
},
"android": {
"buildType": "app-bundle",
"image": "latest"
},
"env": {
"APP_ENV": "development",
"EXPO_NO_DOTENV": "1"
"EXPO_NO_DOTENV": "1",
"EAS_NO_DOCTOR": "1"
},
"prebuildCommand": "prebuild --skip-dependency-update react",
"cache": {
Expand Down Expand Up @@ -108,6 +117,34 @@
}
},
"submit": {
"production": {}
"production": {
"ios": {
"ascAppId": "6746460022"
}
},
"staging": {
"ios": {
"ascAppId": "6745524568"
},
"android": {
"releaseStatus": "draft"
}
},
"qa": {
"ios": {
"ascAppId": "6745527331"
},
"android": {
"releaseStatus": "draft"
}
},
"development": {
"ios": {
"ascAppId": "6746459808"
},
"android": {
"releaseStatus": "draft"
}
}
}
}
}
Loading
Loading