Skip to content

Commit

Permalink
fix(ci): use load-config script in place of inline bash (#567)
Browse files Browse the repository at this point in the history
  • Loading branch information
prescottprue committed Jul 14, 2021
1 parent 2acfabc commit 75aca19
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 40 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ module.exports = {
'global-require': 0,
'import/no-dynamic-require': 0
}
},
{
files: ['./bin/*'],
rules: {
'no-console': 0
}
}
]
}
37 changes: 16 additions & 21 deletions .github/workflows/app-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ jobs:
run: |
set -o pipefail
# Find the config associated to the firebase project in .firebaserc
gitBranch=${GITHUB_REF##*/}
gcloudProject=$(cat .firebaserc | jq -r --arg alias "$gitBranch" '.projects[$alias]')
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]')
Expand All @@ -91,26 +91,21 @@ jobs:
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
echo Exporting Firebase SDK Config for $gcloudProject project...
# Use firebase SDK API to get the app's configuration (databaseURL is removed since it is set to the emulator URL above)
firebaseConfig=$($(yarn bin)/firebase --project $gcloudProject apps:sdkconfig WEB \
$($(yarn bin)/firebase --project $gcloudProject apps:list WEB | grep fireadmin | awk '{ print $4}') | \
tr '\n' ' ' | \
sed 's/.*initializeApp(//g' | \
sed 's/);//g' | \
jq -r 'to_entries[] | [.key, (.value | tojson)] | join("=")' | \
sed 's/"//1' | \
sed 's/:"/:/g; s/^/echo \"REACT_APP_FIREBASE_/g' \
)
echo Begin evaluating project config to export as environment variables:
# Loop through each line of config and evaluate to export env vars
while IFS= read -r line; do
echo Evaluating: $line
eval $line >> $GITHUB_ENV
done <<< "$firebaseConfig"
- name: Generate Firebase SDK config for ${{ env.GCLOUD_PROJECT }}
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: Verify App
run: |
Expand Down
36 changes: 17 additions & 19 deletions .github/workflows/app-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ jobs:
# 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')
Expand All @@ -83,30 +84,27 @@ jobs:
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
echo Exporting Firebase SDK Config for $gcloudProject project...
# Use firebase SDK API to get the app's configuration (databaseURL is removed since it is set to the emulator URL)
firebaseConfig=$($(yarn bin)/firebase --project $gcloudProject apps:sdkconfig WEB \
$($(yarn bin)/firebase --project $gcloudProject apps:list WEB | grep fireadmin | awk '{ print $4}') | \
tr '\n' ' ' | \
sed 's/.*initializeApp(//g' | \
sed 's/);//g' | \
jq -r 'del(.databaseURL) | to_entries[] | [.key, (.value | tojson)] | join("=")' | \
sed 's/"//1' | \
sed 's/:"/:/g; s/^/echo \"REACT_APP_FIREBASE_/g' \
)
# 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
echo Begin evaluating project config to export as environment variables:
- 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
# Loop through each line of config and evaluate to export env vars
while IFS= read -r line; do
echo Evaluating: $line
eval $line >> $GITHUB_ENV
done <<< "$firebaseConfig"
bin/generate-firebase-sdk-config.js --outputEnv >> .env
- name: Print CI Env Variables
run: |
Expand Down
52 changes: 52 additions & 0 deletions bin/generate-firebase-sdk-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env node

const fsp = require('fs').promises
const firebase = require('firebase-tools')
const argv = require('minimist')(process.argv.slice(2))

const project = process.env.GCLOUD_PROJECT

if (!project) {
console.error('Missing GCLOUD_PROJECT environment variable.')
process.exit(1)
}

async function getFirebaseConfig() {
const apps = await firebase.apps.list('WEB', {
project
})
// NOTE: find is used because displayName is not a supported config option in firebase-tools
const { appId, platform } = argv.appName
? apps.find((appConfig) => appConfig.displayName === argv.appName) || {}
: apps[0]

if (!appId) {
throw new Error('No app found matching the provided app name')
}

const { sdkConfig } = await firebase.apps.sdkconfig(platform, appId)
return sdkConfig
}

async function run() {
const sdkConfig = await getFirebaseConfig()
const content = JSON.stringify({ firebase: sdkConfig }, null, 2)

if (argv.file) {
await fsp.writeFile(argv.file, content)
console.log(`Successfully written Firebase SDK config to ${argv.file}`)
}
if (argv.outputEnv) {
const envString = Object.entries(sdkConfig)
.map(([key, val]) => `REACT_APP_FIREBASE_${key}=${val}`)
.join('\n')
console.log(`\n${envString}`)
} else {
console.log(content)
}
}

run().catch((err) => {
console.error(err)
process.exit(1)
})

0 comments on commit 75aca19

Please sign in to comment.