Site icon May's Notes

EXPO + Github Action 自動化構建 React Native 應用

React Native logo

這是我在2023第十五屆 iThome 鐵人賽發表的系列文章。https://ithelp.ithome.com.tw/users/20136637/ironman/6408

這篇文章會分享的是使用 Expo + Github action 實現自動 eas update 和 eas build,主要目的是學會使用 Github action。

生成 EXPO Access Token

https://expo.dev/accounts/%5Baccount%5D/settings/access-tokens

要使用 expo cli, eas cli 做任何操作都需要經過身份驗證,也就是說需要登入 expo 帳號密碼,但還有一種更安全和方便的方式是使用 access token 來驗證身份。

點擊上方的連結後選擇帳號:

接著點擊右上方的 Create token

將這個 EXPO_TOKEN 保存起來,接下來會用到。

新增 Github Secret

因為後面需要使用 Github action workflow 來 eas update 和 eas build,所以會需要將剛剛生成的 EXPO_TOKEN 存到 repo 的 Secrets 裡面,這樣一來執行 workflow 的時候才能從 secrets 中獲取到 EXPO_TOKEN,從而進行下一步動作。

到倉庫的 Settings – Secrets and variables – Actions 新增 secret

創建 Github Action workflow

Github Action 是 Github 的 CI/CD(流程自動化) 服務,一般來說會在根目錄底下新增 .github/workflows 資料夾,並且用 YAML 檔來描述自動化流程。

想瞭解更多 Action 的內容可以參考官方文檔:https://docs.github.com/en/actions

創建 .github/workflows 資料夾,並新增 main.yml

name: preview # Action 的名字,會顯示在側邊欄

on:
  push:
    branches:
      - main # 監聽是否 push 到 main 這個分支,是的話就會執行 action

jobs: # 一個 action 裡面可以有多個 job
  build: # 這邊的 `build` 就是其中一個 job 的名稱
    runs-on: ubuntu-latest

    steps:
      # 使用 actions/checkout 操作來拉取程式碼
      - name: 🏗 Checkout Code
        uses: actions/checkout@v3
      
      # actions/setup-node 設置 Node.js 版本
      - name: 🏗 Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 18.x

      # expo-github-action 是 expo 官方為方便用 Github Action 實現流程自動化而創建,
      # 包含了安裝/更新 eas cli、用 expo access token 進行身份驗證
      - name: 🏗 Setup EAS
        # 直接用 uses 關鍵字執行 expo github action 就不需要再自己去寫這些流程
        uses: expo/expo-github-action@v8 
        with:
          eas-version: latest
          token: ${{ secrets.EAS_ACCESS_KEY }}

      # 安裝應用依賴套件
      - name: 📦 Install dependencies
        run: npm install --legacy-peer-deps

      # 創建 update
      # 設置 auto 的話 expo branch 就會是執行 action 的 branch
      - name: 🚀 Create update
        run: eas update --auto --non-interactive

      # 使用 eas build 來 build 應用
      # 這邊 build 的是 Android & iOS, 使用 preview profile
      # build iOS 需要先設置 credentials (eas credentials)
      - name: 🚀 Build Android App
        run: eas build --platform All --profile preview --non-interactive

修改 eas.json

如果你的專案中還沒有 eas.json 請使用 eas build:configure 指令生成,如果不想用 preview profile 的話可以自行新增一個或者也可以自行修改名稱。

eas.json

{
  "cli": {
    "version": ">= 3.9.1"
  },
  "build": {
    "development": {
      "channel": "development",
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "resourceClass": "m-medium"
      }
    },
    "preview": {
      "channel": "preview",
      "distribution": "internal",
      "ios": {
        "resourceClass": "m-medium"
      }
    },
    "production": {
      "channel": "production",
      "ios": {
        "resourceClass": "m-medium"
      }
    }
  },
  "submit": {
    "production": {}
  }
}

對 eas.json 這些設置不瞭解的話可以看官方文檔:https://docs.expo.dev/build/eas-json/

eas update 設置

為了能夠使用 eas update 指令更新,我們需要先進行設置

eas update:configure

輸入指令後會提示你需要將紅框處這段貼到 app.config.js 或者 app.json 中:

建議將 projectId 存在環境變數中,而不是直接寫在檔案裡面。

<em>// app.config.js</em>
module.exports = ({ config }) => {
  return {
    ...config,
    extra: {
      eas: {
        projectId: process.env.PROJECT_ID,
      },
    },
    updates: {
      url: `https://u.expo.dev/${process.env.PROJECT_ID}`,
    },
    runtimeVersion: {
      policy: 'sdkVersion',
    },
  };
};

如果不知道怎麼在應用中使用環境變數,可以看我之前發的文章:【DAY18】React Native – 環境變數的管理(env)

記得有用到的環境變數都要寫進 yaml 中:

<em># .github/workflows/main.yml</em>
name: preview

on:
  push:
    branches:
      - main

jobs:
  init:
    runs-on: ubuntu-latest

    env:
      PROJECT_ID: ${{ secrets.PROJECT_ID }}

    steps:
      <em># 略...</em>

      - name: 🏗 Set Variables
        run: | 
          echo "PROJECT_ID=${PROJECT_ID}" >> .env
          sed -i "s@.env@@g" .gitignore
<em># .env</em>
PROJECT_ID=

創建 Pull Request

將分支合併到 main 分支觸發自動化構建:

如果在開 pull request 時提示「There isn’t anything to compare… entirely different commit histories.」,需要先 pull main 分支並加上 --allow-unrelated-histories

git pull origin main --allow-unrelated-histories
git push origin <Your_branch_name>

查看 Github Action

在倉庫的 Actions 可以查看正在執行中的 workflows

Troubleshooting

Input is required, but stdin is not readable.

https://github.com/expo/eas-cli/issues/1424

eas build 時如果在 build 成功後卻 workflow 失敗且遇到下方這個 error:

Input is required, but stdin is not readable. Failed to display prompt: Install and run the Android build on an emulator?

就代表需要在 eas build 後面加上 --non-interactive

eas build --platform all --profile <profile_name> --non-interactive

Exit mobile version