Automate Your Expo Builds with EAS Using GitHub Actions: A Step-by-Step Guide
Tags: reactnative, expo, frontend, mobile
Published: 2024-07-07 20:55:40

Developers get 30 free builds each month (up to 15 iOS builds) with EAS Build. While this seems much at first glance, it can be quickly exhausted in a serious hobby project, let alone a professional environment.

Additionally, the queue for builds can be very long, sometimes taking up to 90 minutes or more before starting. 

This wait can be problematic if you need to fix high-severity or security issues urgently. Local builds (--local) are an alternative, but the process is repetitive and unavailable to Windows users.
 

In this article, we will cover how to avoid these issues efficiently using GitHub Actions.


## Prerequisites

- React Native project 

- Must have created your first build [Create your first build](https://docs.expo.dev/build/setup/)

- An Expo user account 

**Step 1: Setup your project**

Ensure you have your Expo project set up and configured for EAS Build. If not, you can check expo docs [On creating your first build](https://docs.expo.dev/build/setup/)

**Step 2: Get your Expo access token**

You can generate expo tokens that will allow github action to access your account on your behalf. [learn more](https://docs.expo.dev/accounts/programmatic-access/)

![Getting Expo access token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkzsd9twal1034s9wydv.png)

**Step 3: Save this token to GitHub Secrets**

In your GitHub repository, navigate to Settings > Secrets and variables > Actions and add the following secrets:

EXPO_TOKEN:  your expo access token generated in step 2

**Step 4: Create a New Workflow File**
In your GitHub repository or locally, create a new directory .github/workflows  and add a file named build-apk.yml (you can name this file whatever you want and in my case I created the file inside **staging** branch).

Enter your workflow name and trigger

```
name: Build APK with EAS

on:
  push:
    branches:
      - staging
```
**NB**:
You may not understand the above code but what you need to understand is the workflow runs when code is pushed to the branch name **staging**, you can replace it with a different branch.
[Learn more about workflows](https://docs.github.com/en/actions/using-workflows).

**Jobs and Steps**
 Below code specifies the type of virtual machine to run the job: which is ubuntu-latest. you can specify **macos-latest** when building for iOS.

```
jobs:
  build:
    runs-on: ubuntu-latest
```
**Steps Within the Job**
This code is essential to get the code into the virtual machine.
```
steps:
      - name: Setup repo
        uses: actions/checkout@v4
```

**Setup node**
Uses a pre-built action to set up a Node.js environment
```
      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: 20.x
          cache: "npm"
```
**Set up JDK 17**
Uses a pre-built action to set up a Java environment
```
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: "17"
          distribution: "temurin"
```
**Setup Android SDK**
Uses a pre-built action to install and set Android SDK
```
  - name: Setup Android SDK
        uses: android-actions/setup-android@v3
```
**Setup Expo**
Uses a pre-built action to set up Expo
```
 - name: Setup Expo
        uses: expo/expo-github-action@v8
        with:
          expo-version: latest
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}
```
NB: You must save EXPO_TOKEN to Github secret you can go back to step 2 & 3 if you have not.

**Install project depencies**

```
 - name: Install dependencies
        run: yarn install --frozen-lockfile
```

**Build Android APK **

```
  - name: Build Android app
        run: eas build --platform android --profile preview --local
```

**Upload APK artifact**

```
      - name: Upload APK artifact
        uses: actions/upload-artifact@v2
        with:
          name: app-release
          path: ${{ github.workspace }}/app-release.apk
```

Your build-apk.yml should have below content by now, make changes to your code and push to github.

```
name: Android App APK Build

on:
  push:
    branches:
      - new-features
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Setup repo
        uses: actions/checkout@v4

      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: 20.x
          cache: "npm"

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: "17"
          distribution: "temurin"

      - name: Setup Android SDK
        uses: android-actions/setup-android@v3

      - name: Setup Expo
        uses: expo/expo-github-action@v8
        with:
          expo-version: latest
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Build Android app
        run: eas build --platform android --profile preview --local

      - name: Upload APK artifact
        uses: actions/upload-artifact@v2
        with:
          name: app-release
          path: ${{ github.workspace }}/app-release.apk
```
You can download the Artifact (build file apk or aab) in the job detail's page.

![Where you can download the Artifact](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdq2wbiipr6n5d6ufonp.png)

NB: For medium or large-sized companies, it is advisable to use the Production or Enterprise subscription, as it includes many additional features that cater to their needs.

**Final Thoughts**

Employing GitHub Actions for building my projects has saved me a lot of time. Previously, I could only create 2-3 builds per day. Now, I can generate unlimited builds, eliminating repetitive and boring tasks from my workflow. This allows me to focus on what truly matters: building my project.

Thanks for reading till the end.

Next time, I'll cover automating builds and submission of  android and iOS to the Play Store and Apple store respectively. Stay tuned!!!