.github/workflows/app-verify.yml
name: Verify App
on:
pull_request:
paths-ignore:
- 'docs/**'
jobs:
verify-build:
name: Verify + Build
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.0
with:
access_token: ${{ github.token }}
- name: Checkout Repo
uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2.2.0
with:
node-version: 14
- name: Get cache settings
id: cache-settings
run: |
echo "::set-output name=dir::$(yarn cache dir)"
echo "::set-output name=firebase-tools::$(yarn list -s --depth=0 --pattern firebase-tools | tail -n 1 | sed 's/.*@//g')"
- name: Get Yarn Cache
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache NPM Dependencies
uses: actions/cache@v2.1.6
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- name: Install Dependencies
env:
CYPRESS_INSTALL_BINARY: 0 # Skip installing of cypress
run: |
yarn install --frozen-lockfile
yarn --cwd functions install --frozen-lockfile
- name: Verify Functions
# NOTE: Project name is hardcoded since emulators are being used
run: |
yarn functions:build
yarn --cwd functions test:cov
- name: Upload Functions Test Coverage
uses: codecov/codecov-action@v1
with:
file: functions/coverage/lcov.info
- name: Verify
run: yarn lint
- name: Expose Application Environment Variables
env:
GITHUB_REF: ${{ github.ref }}
# Firebase token needed to authenticate firebase-tools to be able to load app configs
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
run: |
set -o pipefail
gitBranch=${GITHUB_REF##*/}
# Find the config associated to the firebase project in .firebaserc
gcloudProject=$(cat .firebaserc | jq -r --arg alias "$gitBranch" '.projects[$alias] // .projects.default')
echo "GCLOUD_PROJECT=$gcloudProject" >> $GITHUB_ENV
# Set other app configs (settings within .firebaserc in the ci.setEnv section)
config=$(cat .firebaserc | jq -r --arg alias "$gitBranch" '.ci.setEnv[$alias] // .ci.setEnv.master')
echo "REACT_APP_FIREADMIN_ENV=$(echo $config | jq -r '.REACT_APP_FIREADMIN_ENV')" >> $GITHUB_ENV
echo "REACT_APP_SEGMENT_ID=$(echo $config | jq -r '.REACT_APP_SEGMENT_ID')" >> $GITHUB_ENV
echo "REACT_APP_SENTRY_DSN=$(echo $config | jq -r '.REACT_APP_SENTRY_DSN')" >> $GITHUB_ENV
echo "REACT_APP_PUBLIC_VAPID_KEY=$(echo $config | jq -r '.REACT_APP_PUBLIC_VAPID_KEY')" >> $GITHUB_ENV
echo "REACT_APP_ALGOLIA_APP_ID=$(echo $config | jq -r '.REACT_APP_ALGOLIA_APP_ID')" >> $GITHUB_ENV
echo "REACT_APP_ALGOLIA_API_KEY=$(echo $config | jq -r '.REACT_APP_ALGOLIA_API_KEY')" >> $GITHUB_ENV
# Set emulator settings
echo "REACT_APP_FIREBASE_DATABASE_EMULATOR_HOST=localhost:$(cat firebase.json | jq .emulators.database.port)" >> $GITHUB_ENV
echo "REACT_APP_FIRESTORE_EMULATOR_HOST=localhost:$(cat firebase.json | jq .emulators.firestore.port)" >> $GITHUB_ENV
- name: Generate Firebase SDK config for ${{ env.GCLOUD_PROJECT }}
# Skip for forks (since they don't have access to secrets)
if: github.event.pull_request.head.repo.full_name == github.repository
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
run: |
set -o pipefail
# Throw a clear error if FIREBASE_TOKEN secret is not set
if [ -z "$FIREBASE_TOKEN" ];
then
missingTokenErrMsg="\"FIREBASE_TOKEN\" github secret is required to load project configuration. Visit https://github.com/${{ github.repository }}/settings/secrets to set."
echo "::error ::$missingTokenErrMsg"
exit 1
fi
bin/generate-firebase-sdk-config.js --outputEnv >> .env
- name: Print CI Env Variables
run: |
echo Available ENV vars:
env | sort
- name: Build App
run: |
yarn build
- name: Archive Error Logs
uses: actions/upload-artifact@v2
if: failure()
with:
name: error-logs
path: yarn-error.log
- name: Archive Build Artifact
uses: actions/upload-artifact@v2
with:
name: build
path: build
ui-tests:
name: UI Test Emulated App
needs: verify-build
runs-on: ubuntu-20.04
timeout-minutes: 20
strategy:
# Keep all in-progress jobs running if any matrix job fails. Needed to prevent
# the Cypress Dashboard from being stuck in "in progress" state since not all tests run.
# See the following for more details:
# * Cypress Action Issue: https://github.com/cypress-io/github-action/issues/48
# * Docs for fail-fast: https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategyfail-fast
fail-fast: false
matrix:
# Run multiple copies of the current job in parallel
containers: [1, 2, 3, 4]
steps:
- name: Setup Node
uses: actions/setup-node@v2.2.0
with:
node-version: 14
- name: Checkout Repo
uses: actions/checkout@v2
- name: Get Cache Settings
id: cache-settings
run: |
echo "::set-output name=firebase-tools::$(yarn list -s --depth=0 --pattern firebase-tools | tail -n 1 | sed 's/.*@//g')"
- name: Cache Firebase Emulator Binaries
uses: actions/cache@v2.1.6
with:
path: ~/.cache/firebase/emulators
key: ${{ runner.os }}-firebase-${{ steps.cache-settings.outputs.firebase-tools }}
- name: Set Test Environment Settings
env:
GITHUB_REF: ${{ github.ref }}
SKIP_CYPRESS_RECORDING: ${{ secrets.SKIP_CYPRESS_RECORDING }}
run: |
gitBranch=${GITHUB_REF##*/}
gcloudProject=$(cat .firebaserc | jq -r --arg branch "$gitBranch" '.projects[$branch] // .projects.master')
echo "Exposing settings to environment for branch: $gitBranch and project: $gcloudProject..."
echo "GCLOUD_PROJECT=$gcloudProject" >> $GITHUB_ENV
echo "FIREBASE_DATABASE_EMULATOR_HOST=localhost:$(cat firebase.json | jq .emulators.database.port)" >> $GITHUB_ENV
echo "FIRESTORE_EMULATOR_HOST=localhost:$(cat firebase.json | jq .emulators.firestore.port)" >> $GITHUB_ENV
echo "CYPRESS_BASE_URL=http://localhost:$(cat package.json | jq .config.port)" >> $GITHUB_ENV
echo "Generating Service Account File..."
echo "$(echo $SERVICE_ACCOUNT | jq .)" > $HOME/serviceAccount.json
echo "GOOGLE_APPLICATION_CREDENTIALS=$HOME/serviceAccount.json" >> $GITHUB_ENV
- name: Print CI Env Variables
run: |
echo Available ENV vars:
env | sort
- name: Download Build Artifact
uses: actions/download-artifact@v2
with:
name: build
path: build
# Cypress action manages installing/caching npm dependencies and Cypress binary.
# Because of "record" and "parallel" parameters these containers will load
# balance all found tests among themselves. The step tests a version of the app
# which is running locally in the container on port 3000
- name: Cypress Run
uses: cypress-io/github-action@v2
with:
browser: chrome
parallel: true
record: true
headless: true
group: 'UI Integration Tests'
tag: emulated
start: yarn emulators:no-functions --project ${{ env.GCLOUD_PROJECT }}
wait-on: ${{ env.CYPRESS_BASE_URL }}
wait-on-timeout: 120
env:
TZ: America/Los_Angeles
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_KEY }}
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_REF: ${{ github.ref }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }}
CYPRESS_TEST_UID: ${{ secrets.TEST_UID }}