66# This workflow is used to trigger a build on EAS.
77# Can be triggered manually from the actions tab.
88
9- # This action accepts those inputs:
10- # `environment`, which is used to generate a build for a specific environment (development, staging, QA, production). We use staging by default.
11- # `android`, true by default, set to true if you don't want to trigger build for Android.
12- # `ios`, false by default, set to true if you want to trigger build for IOS.
13-
149# Before triggering the build, we run a pre-build script to generate the necessary native folders based on the APP_ENV.
1510# Based on the ANDROID and IOS inputs, we trigger the build for the corresponding platform with the corresponding flags.
1611
1712# 🚨 GITHUB SECRETS REQUIRED:
18- # - EXPO_TOKEN: Expo token to authenticate with EAS
19- # - You can get it from https://expo.dev/settings/access-tokens
13+ # - EXPO_TOKEN: Expo token to authenticate with EAS to sync version numbers and submit the build.
14+ # You can get it from https://expo.dev/settings/access-tokens
15+ # - NEW_VERSION_NUMBER_PAT: A fine-grained Personal Access Token.
16+ # This token is used to commit and push to protected branches.
17+ # You can generate one from here: https://github.com/settings/tokens?type=beta
18+ # Set the token name to something meaningful, e.g. "New version number PAT for <Project name>".
19+ # Set the Repository access to "Only select repositories" and select this repository.
20+ # Set the following Repo permissions:
21+ # - Contents: Read & write (to commit and push)
22+ # Make sure to add it to the repo secrets with the name NEW_VERSION_NUMBER_PAT:
23+ # - Go to Repository Settings > Secrets and variables > Actions > New repository secret
24+ # - Name: NEW_VERSION_NUMBER_PAT
25+ # - Value: The Personal Access Token you created
2026
21- name : ' EAS Build (Android & IOS) (EAS) '
27+ name : ' Build & Deploy '
2228
2329on :
2430 workflow_dispatch :
2531 inputs :
26- environment :
32+ platform :
2733 type : choice
28- description : ' Environment'
29- required : true
30- default : ' staging'
34+ description : Platform to build for
3135 options :
32- - development
33- - staging
34- - qa
35- - production
36- android :
37- type : boolean
38- description : ' Build for Android'
39- required : true
40- default : true
41- ios :
36+ - android
37+ - ios
38+ new-version :
39+ type : string
40+ description : ' New version (e.g. 1.0.0) (optional)'
41+ auto-submit :
4242 type : boolean
43- description : ' Build for iOS '
44- required : true
43+ description : ' Auto-submit the build to the store '
44+ required : false
4545 default : true
4646
4747jobs :
48- Build :
48+ validate-new-version :
4949 runs-on : ubuntu-latest
50+ permissions :
51+ contents : read
52+ steps :
53+ - name : Checkout
54+ if : inputs.new-version
55+ uses : actions/checkout@v3
56+ with :
57+ fetch-depth : 0
58+ - name : Install Node.js
59+ if : inputs.new-version
60+ uses : actions/setup-node@v4
61+ with :
62+ node-version : 20
63+ - name : Validate new version
64+ if : inputs.new-version
65+ run : |
66+ CURRENT_VERSION=$(node -p "require('./package.json').version")
67+ NEW_VERSION="${{ inputs.new-version }}"
68+
69+ echo "Current version : $CURRENT_VERSION"
70+ echo "New version : $NEW_VERSION"
71+
72+ 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)
73+
74+ echo "✅ New version is valid"
75+
76+ build :
77+ needs : validate-new-version
78+ runs-on : ${{ inputs.platform == 'ios' && 'macos-latest' || 'ubuntu-latest' }}
79+ permissions :
80+ contents : write
81+ environment : ${{ github.ref_name == 'main' && 'production' || github.ref_name == 'staging' && 'staging' || github.ref_name == 'qa' && 'qa' || github.ref_name == 'development' && 'development' }}
5082 steps :
51- - name : Check for EXPO_TOKEN
83+ - name : Set environment variable
84+ run : |
85+ if [[ "${{ github.ref_name }}" == "main" ]]; then
86+ echo "ENV=production" >> $GITHUB_ENV
87+ elif [[ "${{ github.ref_name }}" == "staging" ]]; then
88+ echo "ENV=staging" >> $GITHUB_ENV
89+ elif [[ "${{ github.ref_name }}" == "qa" ]]; then
90+ echo "ENV=qa" >> $GITHUB_ENV
91+ elif [[ "${{ github.ref_name }}" == "development" ]]; then
92+ echo "ENV=development" >> $GITHUB_ENV
93+ else
94+ echo "Invalid branch: ${{ github.ref_name }}. You can only build for main, staging, qa or development branches."
95+ exit 1
96+ fi
97+ - name : Check if all required secrets exist
5298 run : |
5399 if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
54100 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"
55101 exit 1
56102 fi
103+ if [ -z "${{ secrets.NEW_VERSION_NUMBER_PAT }}" ]; then
104+ echo "NEW_VERSION_NUMBER_PAT secret not found. Please create a fine-grained Personal Access Token following the instructions in the workflow file."
105+ exit 1
106+ fi
57107
58108 - name : 📦 Setup Expo and EAS
59109 uses : expo/expo-github-action@v8
@@ -65,17 +115,66 @@ jobs:
65115 uses : actions/checkout@v3
66116 with :
67117 fetch-depth : 0
118+ token : ${{ secrets.NEW_VERSION_NUMBER_PAT }}
68119
69120 - name : 📦 Setup Node + PNPM + install deps
70121 uses : ./.github/actions/setup-node-pnpm-install
71122
123+ - name : Create environment file
124+ run : echo "${{ secrets.ENVIRONMENT_FILE }}" > .env.${{ env.ENV }}
125+
126+ - name : Update version in package.json
127+ if : inputs.new-version
128+ run : |
129+ CURRENT_VERSION=$(node -p "require('./package.json').version")
130+ if [ "$CURRENT_VERSION" == "${{inputs.new-version}}" ]; then
131+ echo "Current version is already ${{ inputs.new-version }}, no need to update"
132+ exit 0
133+ fi
134+
135+ git config --global user.name "github-actions[bot]"
136+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
137+ pnpm version ${{ inputs.new-version }} -m "chore: set app version to ${{ inputs.new-version }}"
138+
139+ - name : Setup latest version of Xcode
140+ uses : maxim-lobanov/setup-xcode@v1
141+ if : inputs.platform == 'ios'
142+ with :
143+ xcode-version : latest
144+
145+ - name : Set Up JDK
146+ uses : actions/setup-java@v3
147+ if : inputs.platform == 'android'
148+ with :
149+ distribution : ' zulu' # See 'Supported distributions' for available options
150+ java-version : ' 17'
151+
72152 - name : ⚙️ Run Prebuild
73- run : pnpm prebuild:${{ inputs.environment }}
153+ run : pnpm prebuild:${{ env.ENV }}
74154
75- - name : 📱 Run Android Build
76- if : ${{ inputs.android == true }}
77- run : pnpm build:${{ inputs.environment }}:android --non-interactive --no-wait --message "Build ${{ inputs.environment }}"
155+ - name : 📱 Run Build for ${{ inputs.platform }}
156+ run : |
157+ pnpm build:${{ env.ENV }}:${{ inputs.platform }} --non-interactive --no-wait --message "Build ${{ env.ENV }} for ${{ inputs.platform }}" --local
158+ if [ "${{ inputs.platform }}" = "android" ]; then
159+ ls -1 ./*.aab > path.txt
160+ elif [ "${{ inputs.platform }}" = "ios" ]; then
161+ ls -1 ./*.ipa > path.txt
162+ fi
163+ - name : Upload ${{ inputs.platform }} Build
164+ uses : actions/upload-artifact@v4
165+ with :
166+ name : ${{ inputs.platform }}-build-${{ env.ENV }}
167+ path : |
168+ *.apks
169+ *.apk
170+ *.aab
171+ *.ipa
172+
173+ - name : 📱 Submit ${{ inputs.platform }} app to the store
174+ if : inputs.auto-submit
175+ run : pnpm submit:${{ env.ENV }}:mobile --platform=${{ inputs.platform }} --path=$(cat path.txt) --no-wait --non-interactive
78176
79- - name : 📱 Run IOS Build
80- if : ${{ inputs.ios == true }}
81- run : pnpm build:${{ inputs.environment }}:ios --non-interactive --no-wait --message "Build ${{ inputs.environment }}"
177+ - name : 📦 Push changes to repository
178+ if : inputs.new-version
179+ run : |
180+ git push || echo "Skipping push: version was already updated."
0 commit comments