├── 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 |
--------------------------------------------------------------------------------