├── action.yml ├── .github ├── workflows │ ├── main-update.yml │ ├── preview-cleanup.yml │ └── preview-deploy.yml └── actions │ └── install │ └── action.yml ├── README.md └── LICENSE /action.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Expo Preview Branches 3 | author: Theodo-UK 4 | description: | 5 | Actions workflow that generates a preview deployment on opening/updating a PR, with auto cleanup. 6 | branding: 7 | icon: git-branch 8 | color: green 9 | runs: 10 | using: "composite" 11 | inputs: 12 | token: 13 | description: > 14 | GitHub token for GitHub API requests. This should be set automatically, but can be overridden. 15 | default: ${{ github.token }} 16 | required: true 17 | -------------------------------------------------------------------------------- /.github/workflows/main-update.yml: -------------------------------------------------------------------------------- 1 | name: update 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | update: 9 | name: EAS Update 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v3 14 | 15 | - name: Install 16 | uses: ./.github/actions/install 17 | with: 18 | EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} 19 | 20 | - name: Publish update 21 | run: eas update --auto --branch main 22 | -------------------------------------------------------------------------------- /.github/workflows/preview-cleanup.yml: -------------------------------------------------------------------------------- 1 | name: Cleanup Preview Deployments 2 | on: 3 | pull_request: 4 | types: 5 | - closed 6 | 7 | jobs: 8 | update: 9 | name: Cleanup Preview Channel and Branch 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v3 14 | 15 | - name: Install 16 | uses: ./.github/actions/install 17 | with: 18 | EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} 19 | 20 | - name: Delete Channel 21 | run: eas channel:delete ${{ github.head_ref }} --non-interactive 22 | 23 | - name: Delete Branch 24 | run: eas branch:delete ${{ github.head_ref }} --non-interactive 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Expo Preview Branches 🚀 2 | 3 | A Github Action to automatically generate preview branches using EAS (Expo Application Services) as part of a CI/CD workflow, creating live deployments that allow the reviewer to functionally check any changes in the app. Automatically pushes updates to `main` after merge and cleans up the preview deployment. 4 | 5 | ## Setup 6 | 7 | 1. Follow the Expo [docs](https://docs.expo.dev/eas-update/github-actions/) on setting up EAS CLI within your Github actions. This will require you to add a secret called `EXPO_TOKEN` which is mentioned in the Expo docs above. 8 | 2. Copy the entirety of `.github` folder into your app and push the changes. 9 | 10 | Alternatively, you should be able to add the pre-existing action from the Github Marketplace. However, if you want to customise the workflow, then you'll need to follow the steps above. 11 | 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Theodo UK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/actions/install/action.yml: -------------------------------------------------------------------------------- 1 | name: Install 2 | description: installs yarn dependencies with caching 3 | inputs: 4 | EXPO_TOKEN: 5 | description: Used for eas and expo commands 6 | required: true 7 | 8 | runs: 9 | using: composite 10 | steps: 11 | - name: Check for EXPO_TOKEN 12 | shell: bash 13 | run: | 14 | if [ -z "${{ inputs.EXPO_TOKEN }}" ]; then 15 | 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" 16 | exit 1 17 | fi 18 | 19 | - name: Setup Node 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: 16.10.x 23 | cache: yarn 24 | 25 | - name: Setup Expo 26 | uses: expo/expo-github-action@v7 27 | with: 28 | expo-version: latest 29 | eas-version: latest 30 | token: ${{ inputs.EXPO_TOKEN }} 31 | 32 | - name: Find yarn cache 33 | shell: bash 34 | id: yarn-cache-path 35 | run: echo "::set-output name=dir::$(yarn cache dir)" 36 | 37 | - name: Restore cache 38 | uses: actions/cache@v2 39 | with: 40 | path: ${{ steps.yarn-cache-path.outputs.dir }} 41 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 42 | restore-keys: ${{ runner.os }}-yarn- 43 | 44 | - name: Install dependencies 45 | shell: bash 46 | run: yarn install --immutable 47 | -------------------------------------------------------------------------------- /.github/workflows/preview-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Preview Deployment 2 | on: 3 | pull_request: 4 | types: [opened, reopened, synchronize] 5 | 6 | jobs: 7 | update: 8 | name: Update Preview Branch 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | 14 | - name: Install 15 | uses: ./.github/actions/install 16 | with: 17 | EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} 18 | 19 | - name: Publish Update 20 | id: publish-update 21 | run: | 22 | update_output=$(eas update --branch ${{ github.head_ref }} --auto --non-interactive --json) 23 | ios_update_id=$(echo "$update_output" | jq -r '.[] | select(.platform == "ios") | .id ') 24 | ios_update_uri=$(echo "$update_output" | jq -r '.[] | select(.platform == "ios") | .manifestPermalink ') 25 | android_update_id=$(echo "$update_output" | jq -r '.[] | select(.platform == "android") | .id ') 26 | android_update_uri=$(echo "$update_output" | jq -r '.[] | select(.platform == "android") | .manifestPermalink ') 27 | echo "::set-output name=ios_update_id::$ios_update_id" 28 | echo "::set-output name=ios_update_uri::$ios_update_uri" 29 | echo "::set-output name=android_update_id::$android_update_id" 30 | echo "::set-output name=android_update_uri::$android_update_uri" 31 | 32 | - name: Comment PR 33 | uses: marocchino/sticky-pull-request-comment@v2 34 | with: 35 | recreate: true 36 | message: | 37 | :rocket: Published to Expo Preview Branch: `${{github.head_ref}}`: 38 | | Platform | Deployment | 39 | | ---------------- | ----------- | 40 | | iOS :apple: |
Expand for link
${{ steps.publish-update.outputs.ios_update_uri }}
| 41 | | Android :robot: |
Expand for link
${{ steps.publish-update.outputs.android_update_uri }}
| 42 | --------------------------------------------------------------------------------