Skip to content

Commit

Permalink
feat: updated .env deployment to demo-api
Browse files Browse the repository at this point in the history
  • Loading branch information
dereekb committed May 27, 2022
1 parent 96fb516 commit d88ea62
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 204 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ jobs:
- attach_workspace:
at: ~/code
- run:
# NOTE: this uses make-env.js to produce a .env file that is uploaded. Ensure CircleCI has all required variables before release.
name: deploy updated projects
command: npx nx run-many --target=ci-deploy --all --parallel=false # deploy all projects
- run:
Expand Down
1 change: 1 addition & 0 deletions .env.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CLIENT_APP_URL=https://components.dereekb.com
3 changes: 2 additions & 1 deletion .firebaserc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"projects": {
"default": "dereekb-components"
"default": "dereekb-components",
"prod": "dereekb-components"
}
}
12 changes: 12 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,16 @@ By default, Firebase API calls have their body parsed by express. This occurs be
Firebase's emulators only support hot reloading of rules. To achieve hot reloading we use a combination of demo-api's `build-base` target along with the `entr` command, which watches for changes produced by `nx build-base demo-api`. Currently the emulators do not [shut down gracefully](https://github.com/firebase/firebase-tools/issues/3034) and/or communicate they have closed. We use the `./wait-for-ports.sh` script to shut these processes down within the docker container before attempting to restart the emulators. The script waits for about 5 seconds before hard-stopping the processes and waiting for the ports to be released.

### Deploying Firebase Functions

#### .env
The CI is responsible for deployments. It will generate a .env file directly into demo-api, but also copy .env.prod over from the root. This .env.prod contains all of our public environment variables, while the generated one contains the private variables.

These are deployed to cloud functions. Note that anyone with access to your Google Cloud Console can read the runtime variables.

#### CORS Issue
If you run into what looks like CORS issues, [check this issue comment out](https://github.com/firebase/firebase-js-sdk/issues/6182#issuecomment-1133525775). Most likely your cloud functions were deployed and are set to "authenticated only", which is incorrect.

### Firebase App Check
The dbx-components library has AppCheck enabled, so you will only be able to run the app against the emulators.

You can read more about AppCheck configuration [here](https://firebase.google.com/docs/app-check/web/recaptcha-provider).
62 changes: 31 additions & 31 deletions apps/demo-api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@
"build-base": {
"executor": "@nrwl/node:webpack",
"outputs": ["{options.outputPath}"],
"dependsOn": [
{
"target": "build",
"projects": "dependencies"
}
],
"dependsOn": [{
"target": "build",
"projects": "dependencies"
}],
"options": {
"outputPath": "dist/apps/demo-api",
"main": "apps/demo-api/src/main.ts",
Expand All @@ -28,14 +26,13 @@
"configurations": {
"production": {
"optimization": true,
"extractLicenses": true,
"extractLicenses": false,
"sourceMap": false,
"inspect": false,
"fileReplacements": [
{
"replace": "apps/demo-api/src/environments/environment.ts",
"with": "apps/demo-api/src/environments/environment.prod.ts"
}
]
"fileReplacements": [{
"replace": "apps/demo-api/src/environments/environment.ts",
"with": "apps/demo-api/src/environments/environment.prod.ts"
}]
}
}
},
Expand All @@ -54,8 +51,7 @@
"serve": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
{
"commands": [{
"command": "npx nx build-base demo-api --watch"
},
{
Expand All @@ -80,7 +76,10 @@
},
"run-tests": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/apps/demo-api", "./.reports/jest/demo-api.junit.xml"],
"outputs": [
"coverage/apps/demo-api",
"./.reports/jest/demo-api.junit.xml"
],
"options": {
"jestConfig": "apps/demo-api/jest.config.ts",
"passWithNoTests": true
Expand All @@ -92,28 +91,29 @@
"command": "./exec-with-emulator.sh 'npx nx run-tests demo-api --watch'"
}
},
"deploy": {
"make-env": {
"executor": "@nrwl/workspace:run-commands",
"dependsOn": [
{
"target": "build",
"projects": "self"
}
],
"options": {
"command": "npx firebase deploy --only functions"
"command": "node ./make-env.js > dist/apps/demo-api/.env && cp .env.prod dist/apps/demo-api/.env.prod"
}
},
"ci-deploy": {
"executor": "@nrwl/workspace:run-commands",
"dependsOn": [
{
"target": "build",
"projects": "self"
}
],
"dependsOn": [{
"target": "build",
"projects": "self"
}],
"options": {
"command": "npx firebase deploy --only functions --token \"$FIREBASE_TOKEN\""
"commands": [{
"command": "npx nx run demo-api:build-base:production"
}, {
"command": "npx nx make-env demo-api"
},
{
"command": "npx firebase deploy --only functions --project=prod --token \"$FIREBASE_TOKEN\""
}
],
"parallel": false
}
}
},
Expand Down
47 changes: 47 additions & 0 deletions make-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* This is a stand-alone tool used to generate .env files for your deployments.
*
* The expected usage is:
*
* node make-env.js
*/
const fs = require('fs');
const {
parse,
stringify
} = require('envfile');

// NOTE: If run within nx, remember that nx adds all variables within .env to the environment and, thus, process.env.
// Variables that are within bash take prority.
const templateFilePath = '.env';
const templateEnv = fs.readFileSync(templateFilePath).toString();
const template = parse(templateEnv);

const env = {}; // this is the object that is parsed

const keysToIgnoreFromTemplate = ['PUT_YOUR_REAL_SECRETS_INTO_ENV_SECRET', 'THIS_FILE_IS_COMMITTED_TO_GITHUB']; // these keys are ignored
const keysToIgnore = new Set(keysToIgnoreFromTemplate);

Object.keys(template)
.filter((x) => !keysToIgnore.has(x))
.forEach((key) => (env[key] = ''));

function copyToEnvFromProcessEnv(key, defaultValue = '') {
env[key] = process.env[key] || defaultValue;
}

function initWithProcessEnv(defaultValue, keysSource = env) {
Object.keys(keysSource).forEach((key) => copyToEnvFromProcessEnv(key, defaultValue));
}

// ======================================
// Configure Here using JS
// ======================================

const placeholderValue = 'plc';
initWithProcessEnv(placeholderValue); // Init with process.env, copying values from process.env onto the existing keys of our env variable

// ======================================
// Finish Configuration
// ======================================
console.log(stringify(env)); // output to console/stdout to allow piping.
Loading

0 comments on commit d88ea62

Please sign in to comment.