Skip to content

Commit 7f366df

Browse files
authored
chore(core): switch to REACT_APP env variables in place of src/config.js (#120)
* chore(core): switch to `REACT_APP` env variables in place of `src/config.js` * chore(deps): update to cypress-firebase v1.4.1
1 parent 28991f6 commit 7f366df

File tree

27 files changed

+543
-399
lines changed

27 files changed

+543
-399
lines changed

.env.local renamed to .env

File renamed without changes.

.firebaserc

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,22 @@
66
"default": "fireadmin-stage"
77
},
88
"ci": {
9-
"createConfig": {
9+
"setEnv": {
1010
"master": {
11-
"version": "${npm_package_version}",
12-
"env": "stage",
13-
"firebase": {
14-
"apiKey": "AIzaSyCmw3fvlPnZtqChbIY_yEWXUcDGlemeIRQ",
15-
"authDomain": "fireadmin-stage.firebaseapp.com",
16-
"databaseURL": "https://fireadmin-stage.firebaseio.com",
17-
"projectId": "fireadmin-stage",
18-
"appId": "1:566109548798:web:29831023bb21d00edc35af",
19-
"storageBucket": "fireadmin-stage.appspot.com",
20-
"locationId": "us-central",
21-
"messagingSenderId": "566109548798",
22-
"appId": "1:566109548798:web:29831023bb21d00edc35af"
23-
},
24-
"segmentId": "HWEhRQnBTbnYCgv9b4qeA793wVcR0W5b",
25-
"sentryDsn": "https://[email protected]/1238306",
26-
"publicVapidKey": "BMQbbkyTknePwCeoqbyFVC6z4WJ6A3mdFKgIeNXDmcwUwl_DLIY6LYHKOAedvZW4rge-cD0iO4ZP7nxZ3LbFJVk",
27-
"googleApis": {
28-
"apiKey": "AIzaSyCmw3fvlPnZtqChbIY_yEWXUcDGlemeIRQ"
29-
},
30-
"algolia": {
31-
"appId": "WULRUE0M3R",
32-
"apiKey": "96c289817959585293abf860ec7aca8a"
33-
}
11+
"REACT_APP_FIREADMIN_ENV": "stage",
12+
"REACT_APP_SEGMENT_ID": "HWEhRQnBTbnYCgv9b4qeA793wVcR0W5b",
13+
"REACT_APP_SENTRY_DSN": "https://[email protected]/1238306",
14+
"REACT_APP_PUBLIC_VAPID_KEY": "BMQbbkyTknePwCeoqbyFVC6z4WJ6A3mdFKgIeNXDmcwUwl_DLIY6LYHKOAedvZW4rge-cD0iO4ZP7nxZ3LbFJVk",
15+
"REACT_APP_ALGOLIA_APP_ID": "WULRUE0M3R",
16+
"REACT_APP_ALGOLIA_API_KEY": "96c289817959585293abf860ec7aca8a"
3417
},
3518
"prod": {
36-
"version": "${npm_package_version}",
37-
"env": "production",
38-
"firebase": {
39-
"apiKey": "AIzaSyCz8fdvlyeVpwz22bjuw-MEI3wckXhSx9s",
40-
"authDomain": "fireadmin-33d82.firebaseapp.com",
41-
"databaseURL": "https://fireadmin-33d82.firebaseio.com",
42-
"projectId": "fireadmin-33d82",
43-
"storageBucket": "fireadmin-33d82.appspot.com",
44-
"messagingSenderId": "286913465508",
45-
"locationId": "us-central",
46-
"appId": "1:286913465508:web:c5b9e41062f4a42ef3aa31",
47-
"measurementId": "G-X0ZR0VFH3Y"
48-
},
49-
"segmentId": "F9YnTGtlTuDSYnOmzIqgPVvY2SRJ4efI",
50-
"sentryDsn": "https://[email protected]/1238306",
51-
"publicVapidKey": "BKcXWc4wy3PcmxBAbYZJ4qtqQQdqnEfmVJVEzNSZ95SUK89ZuqT6XjCk7VaSJWOJgXYiSN-d07m3gcvDSQnxRnA",
52-
"googleApis": {
53-
"apiKey": "AIzaSyCz8fdvlyeVpwz22bjuw-MEI3wckXhSx9s"
54-
},
55-
"algolia": {
56-
"appId": "C0D1I0GB86",
57-
"apiKey": "7327fc566154893e3834a49de6fa73c3"
58-
}
19+
"REACT_APP_FIREADMIN_ENV": "production",
20+
"REACT_APP_SEGMENT_ID": "F9YnTGtlTuDSYnOmzIqgPVvY2SRJ4efI",
21+
"REACT_APP_SENTRY_DSN": "https://[email protected]/1238306",
22+
"REACT_APP_PUBLIC_VAPID_KEY": "BKcXWc4wy3PcmxBAbYZJ4qtqQQdqnEfmVJVEzNSZ95SUK89ZuqT6XjCk7VaSJWOJgXYiSN-d07m3gcvDSQnxRnA",
23+
"REACT_APP_ALGOLIA_APP_ID": "C0D1I0GB86",
24+
"REACT_APP_ALGOLIA_API_KEY": "7327fc566154893e3834a49de6fa73c3"
5925
}
6026
}
6127
},

.github/workflows/app-deploy.yml

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,49 @@ jobs:
5959
yarn --cwd functions test:cov || echo "::warning::Functions unit tests failed"
6060
6161
- name: Upload Functions Test Coverage
62-
run: |
63-
bash <(curl -s https://codecov.io/bash) -f functions/coverage/lcov.info || 'Test Coverage Upload Failed, continuing'
62+
uses: codecov/codecov-action@v1
63+
with:
64+
file: functions/coverage/lcov.info
6465

65-
- name: Build App Config
66+
- name: Expose Application Environment Variables
6667
env:
67-
GITHUB_HEAD_REF: ${{ github.head_ref }}
6868
GITHUB_REF: ${{ github.ref }}
69+
# Firebase token needed to authenticate firebase-tools to be able to load app configs
70+
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
6971
run: |
70-
yarn build:config
72+
set -o pipefail
73+
74+
gitBranch=${GITHUB_REF##*/}
75+
76+
# Find the config associated to the firebase project in .firebaserc
77+
gcloudProject=$(cat .firebaserc | jq -r --arg alias "$gitBranch" '.projects[$alias]')
78+
79+
echo Exporting Firebase SDK Config for $gcloudProject project...
80+
81+
# Use firebase SDK API to get the app's configuration (databaseURL is removed since it is set to the emulator URL above)
82+
firebaseConfig=$($(yarn bin)/firebase --project $gcloudProject apps:sdkconfig WEB \
83+
$($(yarn bin)/firebase --project $gcloudProject apps:list WEB | grep fireadmin | awk '{ print $4}') | \
84+
tr '\n' ' ' | \
85+
sed 's/.*initializeApp(//g' | \
86+
sed 's/);//g' | \
87+
jq -r 'del(.databaseURL) | to_entries[] | [.key, (.value | tojson)] | join("::")' | \
88+
sed 's/:"/:/g; s/^/echo \"::set-env name=REACT_APP_FIREBASE_/g' \
89+
)
90+
91+
# Set emulator settings
92+
echo "::set-env name=REACT_APP_FIREBASE_DATABASE_EMULATOR_HOST::localhost:$(cat firebase.json | jq .emulators.database.port)"
93+
echo "::set-env name=REACT_APP_FIRESTORE_EMULATOR_HOST::localhost:$(cat firebase.json | jq .emulators.firestore.port)"
94+
95+
# Set other app configs (settings within .firebaserc in the ci.setEnv section)
96+
$(yarn bin)/firebase-ci setEnv
97+
98+
echo Begin evaluating project config to export as environment variables:
99+
100+
# Loop through each line of config and evaluate to export env vars
101+
while IFS= read -r line; do
102+
echo Evaluating: $line
103+
eval $line
104+
done <<< "$firebaseConfig"
71105
72106
- name: Verify App
73107
run: |
@@ -86,7 +120,6 @@ jobs:
86120
- name: Deploy to Firebase
87121
env:
88122
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
89-
GITHUB_HEAD_REF: ${{ github.head_ref }}
90123
GITHUB_REF: ${{ github.ref }}
91124
run: |
92125
targets=hosting:app$(if [ "${GITHUB_REF##*/}" = "stage" ]; then echo "Stage"; fi;),functions,storage,database,firestore
@@ -98,7 +131,6 @@ jobs:
98131
env:
99132
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
100133
GITHUB_REF: ${{ github.ref }}
101-
GITHUB_HEAD_REF: ${{ github.head_ref }}
102134
run: |
103135
gitBranch=${GITHUB_REF##*/}
104136
packageName=$(cat package.json | jq -r '.name')

.github/workflows/app-verify.yml

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,38 +41,76 @@ jobs:
4141
yarn install --frozen-lockfile
4242
yarn --cwd functions install --frozen-lockfile
4343
44-
- name: Archive Error Logs
45-
uses: actions/upload-artifact@v2
46-
if: failure()
47-
with:
48-
name: error-logs
49-
path: yarn-error.log
50-
51-
- name: Build App Config
52-
env:
53-
GITHUB_HEAD_REF: ${{ github.head_ref }}
54-
GITHUB_REF: ${{ github.ref }}
55-
run: yarn build:config
56-
5744
- name: Verify Functions
5845
# NOTE: Project name is hardcoded since emulators are being used
5946
run: |
6047
yarn functions:build
6148
yarn --cwd functions test:cov || echo "::warning::Functions unit tests failed"
6249
6350
- name: Upload Functions Test Coverage
64-
run: |
65-
bash <(curl -s https://codecov.io/bash) -f functions/coverage/lcov.info || 'Test Coverage Upload Failed, continuing'
51+
uses: codecov/codecov-action@v1
52+
with:
53+
file: functions/coverage/lcov.info
6654

6755
- name: Verify
6856
run: yarn lint
6957

58+
- name: Expose Application Environment Variables
59+
env:
60+
GITHUB_REF: ${{ github.ref }}
61+
# Firebase token needed to authenticate firebase-tools to be able to load app configs
62+
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
63+
run: |
64+
set -o pipefail
65+
66+
gitBranch=${GITHUB_REF##*/}
67+
68+
# Find the config associated to the firebase project in .firebaserc
69+
gcloudProject=$(cat .firebaserc | jq -r --arg alias "$gitBranch" '.projects[$alias] // .projects.default')
70+
71+
echo Exporting Firebase SDK Config for $gcloudProject project...
72+
73+
# Use firebase SDK API to get the app's configuration (databaseURL is removed since it is set to the emulator URL)
74+
firebaseConfig=$($(yarn bin)/firebase --project $gcloudProject apps:sdkconfig WEB \
75+
$($(yarn bin)/firebase --project $gcloudProject apps:list WEB | grep fireadmin | awk '{ print $4}') | \
76+
tr '\n' ' ' | \
77+
sed 's/.*initializeApp(//g' | \
78+
sed 's/);//g' | \
79+
jq -r 'del(.databaseURL) | to_entries[] | [.key, (.value | tojson)] | join("::")' | \
80+
sed 's/:"/:/g; s/^/echo \"::set-env name=REACT_APP_FIREBASE_/g' \
81+
)
82+
83+
# Set emulator settings
84+
echo "::set-env name=REACT_APP_FIREBASE_DATABASE_EMULATOR_HOST::localhost:$(cat firebase.json | jq .emulators.database.port)"
85+
echo "::set-env name=REACT_APP_FIRESTORE_EMULATOR_HOST::localhost:$(cat firebase.json | jq .emulators.firestore.port)"
86+
87+
# Set other app configs (settings within .firebaserc in the ci.setEnv section)
88+
$(yarn bin)/firebase-ci setEnv
89+
90+
echo Begin evaluating project config to export as environment variables:
91+
92+
# Loop through each line of config and evaluate to export env vars
93+
while IFS= read -r line; do
94+
echo Evaluating: $line
95+
eval $line
96+
done <<< "$firebaseConfig"
97+
98+
- name: Print CI Env Variables
99+
run: |
100+
echo Available ENV vars:
101+
env | sort
102+
70103
- name: Build App
71104
run: |
72-
export REACT_APP_FIREBASE_DATABASE_EMULATOR_HOST="localhost:$(cat firebase.json | jq .emulators.database.port)"
73-
export REACT_APP_FIRESTORE_EMULATOR_HOST="localhost:$(cat firebase.json | jq .emulators.firestore.port)"
74105
yarn build
75106
107+
- name: Archive Error Logs
108+
uses: actions/upload-artifact@v2
109+
if: failure()
110+
with:
111+
name: error-logs
112+
path: yarn-error.log
113+
76114
- name: Archive Build Artifact
77115
uses: actions/upload-artifact@v2
78116
with:
@@ -116,17 +154,17 @@ jobs:
116154
- name: Set Test Environment Settings
117155
id: emulator-settings
118156
env:
119-
GITHUB_HEAD_REF: ${{ github.head_ref }}
120157
GITHUB_REF: ${{ github.ref }}
121158
run: |
122-
export GIT_BRANCH=${GITHUB_REF##*/}
123-
export GCLOUD_PROJECT=$(cat .firebaserc | jq -r --arg GIT_BRANCH "$GIT_BRANCH" '.projects[$GIT_BRANCH] // .projects.master')
124-
echo "::set-env name=GCLOUD_PROJECT::$GCLOUD_PROJECT"
125-
echo "Environment set for branch: $GIT_BRANCH and project: $GCLOUD_PROJECT"
126-
echo "Setting emulator settings to environment..."
159+
gitBranch=${GITHUB_REF##*/}
160+
gcloudProject=$(cat .firebaserc | jq -r --arg branch "$gitBranch" '.projects[$branch] // .projects.master')
161+
162+
echo "Exposing settings to environment for branch: $gitBranch and project: $gcloudProject..."
163+
echo "::set-env name=GCLOUD_PROJECT::$gcloudProject"
127164
echo "::set-env name=FIREBASE_DATABASE_EMULATOR_HOST::localhost:$(cat firebase.json | jq .emulators.database.port)"
128165
echo "::set-env name=FIRESTORE_EMULATOR_HOST::localhost:$(cat firebase.json | jq .emulators.firestore.port)"
129166
echo "::set-env name=CYPRESS_BASE_URL::http://localhost:$(cat package.json | jq .config.port)"
167+
130168
echo "Generating Service Account File..."
131169
echo "$(echo $SERVICE_ACCOUNT | jq .)" > $HOME/serviceAccount.json
132170
echo "::set-env name=GOOGLE_APPLICATION_CREDENTIALS::$HOME/serviceAccount.json"

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
# React App
1111
build
12-
src/config.js
13-
.env
12+
.env.local
1413

1514
# Functions
1615
functions/etc
@@ -26,7 +25,6 @@ cypress/config.json
2625
cypress.env.json
2726
serviceAccount.json
2827

29-
3028
# Docs
3129
docs/public
3230
docs/.gatsby-context.js

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,23 @@ While developing, you will probably rely mostly on `npm start`; however, there a
127127

128128
### Local Environment Setup
129129

130-
1. Install dependencies: `npm install`
130+
1. Install dependencies: `yarn install`
131+
1. Create a Web app within the Firebase Console of your project (config will be used in next step)
132+
1. Create a `.env.local` that has the following format (with your values filled from previous step):
133+
134+
```bash
135+
REACT_APP_FIREBASE_apiKey=<- api key ->
136+
REACT_APP_FIREBASE_authDomain=<- auth domain ->
137+
REACT_APP_FIREBASE_databaseURL=<- database URL ->
138+
REACT_APP_FIREBASE_projectId=<- project ID ->
139+
REACT_APP_FIREBASE_storageBucket=<- storageBucket ->
140+
REACT_APP_FIREBASE_messagingSenderId=<- message sender ID ->
141+
REACT_APP_FIREBASE_appId=<- project app id ->
142+
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY=<- project app id ->
143+
REACT_APP_ALGOLIA_APP_ID=<- ->
144+
REACT_APP_ALGOLIA_API_KEY=<- ->
145+
```
146+
131147
1. Look for a `src/config.js` file. If one doesn't exist, create it to look like so (this is generated using [`firebase-ci`](https://www.npmjs.com/package/firebase-ci) in CI environments):
132148

133149
```js

cypress/integration/ActionTemplates/ActionTemplatesPage.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import firebase from 'firebase/app'
2+
import 'firebase/firestore'
13
import { createSelector } from '../../utils'
24

35
const testPublicTemplateId = 'testtemplate'
46
const testPublicTemplate = {
57
name: 'test public template',
68
createdBy: 'ABC123',
9+
createdAt: firebase.firestore.Timestamp.now(),
710
public: true
811
}
912
const ACTION_TEMPLATES_COLLECTION = 'actionTemplates'
@@ -63,6 +66,7 @@ describe('Actions Template Page', () => {
6366
const testPrivateTemplate = {
6467
name: 'test private template',
6568
createdBy: Cypress.env('TEST_UID'),
69+
createdAt: firebase.firestore.Timestamp.now(),
6670
public: false
6771
}
6872

cypress/integration/Project/ActionRunner.spec.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ describe('Project - Actions Page', () => {
55
// Setup before tests including creating a fake project
66
before(() => {
77
// Add a fake project owned by the test user
8-
cy.callFirestore('set', 'projects/test-project', fakeProject, {
9-
withMeta: true
8+
cy.callFirestore('set', 'projects/test-project', {
9+
...fakeProject,
10+
createdBy: Cypress.env('TEST_UID')
1011
})
1112
// Login using custom token
1213
cy.login()

cypress/integration/Project/Environments.spec.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { find } from 'lodash'
22
import { createSelector } from '../../utils'
3-
import fakeProject from '../../fixtures/fakeProject.json'
43

54
describe('Project - Environments Page', () => {
65
let openSpy // eslint-disable-line no-unused-vars
76
// Setup before tests including creating a server to listen for external requests
87
before(() => {
98
// Add a fake project owned by the test user
10-
cy.callFirestore('set', 'projects/test-project', fakeProject, {
11-
withMeta: true
12-
})
9+
cy.addProject('test-project')
1310
// Login using custom token
1411
cy.login()
1512
})

cypress/integration/Project/Events.spec.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1+
import firebase from 'firebase/app'
2+
import 'firebase/firestore'
13
import { createSelector } from '../../utils'
2-
import fakeProject from '../../fixtures/fakeProject.json'
34

45
describe('Project - Events Page', () => {
56
// Setup before tests including creating a server to listen for external requests
67
before(() => {
78
// Add a fake project owned by the test user
8-
cy.callFirestore('set', 'projects/test-project', fakeProject, {
9-
withMeta: true
10-
})
9+
cy.addProject('test-project')
1110
// Login using custom token
1211
cy.login()
1312
})
@@ -30,13 +29,15 @@ describe('Project - Events Page', () => {
3029
before(() => {
3130
// Add fake events
3231
const event1 = {
33-
createdAt: new Date('01/01/18').toISOString()
32+
createdAt: firebase.firestore.Timestamp.fromDate(new Date('01/01/18'))
3433
}
3534
const event2 = {
36-
createdAt: new Date('04/04/18').toISOString()
35+
createdAt: firebase.firestore.Timestamp.fromDate(new Date('04/04/18'))
3736
}
3837
const event3 = {
39-
createdAt: new Date(mostRecentDate).toISOString()
38+
createdAt: firebase.firestore.Timestamp.fromDate(
39+
new Date(mostRecentDate)
40+
)
4041
}
4142
cy.addProjectEvent('test-project', 'event1', event1)
4243
cy.addProjectEvent('test-project', 'event2', event2)

0 commit comments

Comments
 (0)