Skip to content

Commit 19a0e97

Browse files
authored
feat: add a ci mechanism to deploy UI prototypes (#928)
1 parent f093eec commit 19a0e97

File tree

3 files changed

+117
-12
lines changed

3 files changed

+117
-12
lines changed

.github/workflows/web-app-deployer.yml

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,37 @@ on:
3030
description: 1Password Slack webhook URL secret reference for add feed channel
3131
type: string
3232
required: false
33+
DEPLOY_FIREBASE_FUNCTIONS:
34+
description: When true(default), the Firebase functions will be deployed; otherwise, they will not.
35+
type: boolean
36+
default: true
3337
OP_ADD_FEED_FORM_GITHUB_TOKEN:
3438
description: 1Password GitHub token secret reference
3539
type: string
3640
required: false
41+
ENABLE_QUALITY_CHECKS:
42+
description: When true the tests and lint checks are performed(default), false will skip. This is only valid in protopype and demo deployments
43+
type: boolean
44+
default: true
45+
PREVIEW_EXPIRES_DAYS:
46+
description: The number of days the preview deployment will be active.
47+
type: string
48+
default: "7"
3749
outputs:
3850
hosting_url:
39-
description: "The URL of the deployed web app"
51+
description: The URL of the deployed web app, when applicable
4052
value: ${{ jobs.build-deploy.outputs.hosting_url }}
53+
hosting_expiration_date:
54+
description: The expiration date of the preview, when applicable
55+
value: ${{ jobs.build-deploy.outputs.hosting_expiration_date }}
4156
env:
4257
NODE_VERSION: "18"
4358

4459
jobs:
4560
lint-test:
4661
name: Test
4762
runs-on: ubuntu-latest
63+
if: ${{ inputs.ENABLE_QUALITY_CHECKS}}
4864
steps:
4965
- name: Checkout code
5066
uses: actions/checkout@v4
@@ -136,11 +152,13 @@ jobs:
136152
name: "Build & Deploy"
137153
permissions: write-all
138154
needs: [lint-test]
155+
if: success() || needs.lint-test.result == 'skipped'
139156
runs-on: ubuntu-latest
140157
outputs:
141158
# Output will be baseb4 encoded due to a false positive secret detection
142159
# More info https://github.com/orgs/community/discussions/37942
143-
hosting_url: ${{ steps.deploy-preview.outputs.hosting_url }}
160+
hosting_url: ${{ steps.deploy-preview.outputs.hosting_url }}
161+
hosting_expiration_date: ${{ steps.deploy-preview.outputs.hosting_expiration_date }}
144162
steps:
145163
- name: Checkout code
146164
uses: actions/checkout@v4
@@ -234,44 +252,50 @@ jobs:
234252
../scripts/replace-variables.sh -in_file src/.env.rename_me -out_file src/.env.${{ inputs.FIREBASE_PROJECT }} -variables REACT_APP_FIREBASE_API_KEY,REACT_APP_FIREBASE_AUTH_DOMAIN,REACT_APP_FIREBASE_PROJECT_ID,REACT_APP_FIREBASE_STORAGE_BUCKET,REACT_APP_FIREBASE_MESSAGING_SENDER_ID,REACT_APP_FIREBASE_APP_ID,REACT_APP_RECAPTCHA_SITE_KEY,REACT_APP_GOOGLE_ANALYTICS_ID,REACT_APP_REMOTE_CONFIG_MINIMUM_FETCH_INTERVAL_MILLI,REACT_APP_FEED_API_BASE_URL
235253
236254
- name: Run Install for Functions
255+
if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }}
237256
working-directory: functions
238257
run: yarn install
239258

240259
- name: Select Firebase Project for Functions
260+
if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }}
241261
working-directory: functions
242262
run: npx firebase use ${{ inputs.FIREBASE_PROJECT }}
243263

244264
- name: Run Lint for Functions
265+
if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }}
245266
working-directory: functions
246267
run: yarn lint
247268

248269
- name: Run Tests for Functions
270+
if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }}
249271
working-directory: functions
250272
run: yarn test
251273

252274
- name: Set Firebase Password Policy
275+
if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }}
253276
working-directory: functions/packages/firebase-password-policy
254277
run: |
255278
yarn build
256279
node lib/index.js
257280
258281
- name: Set Firebase Feed Form Environment
282+
if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }}
259283
working-directory: functions/packages/feed-form
260284
run: |
261285
echo "FEED_SUBMIT_GOOGLE_SHEET_ID=${{ inputs.FEED_SUBMIT_GOOGLE_SHEET_ID }}" > .env
262286
echo "SLACK_WEBHOOK_URL=${{ env.SLACK_WEBHOOK_URL }}" >> .env
263287
echo "GITHUB_TOKEN=${{ env.ADD_FEED_FORM_GITHUB_TOKEN }}" >> .env
264288
265289
- name: Deploy Firebase Functions
290+
if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }}
266291
working-directory: functions
267292
run: npx firebase deploy --only functions
268293

269-
- name: Set robots.txt
294+
- name: Set blocking robots.txt
295+
if: ${{ inputs.PREVIEW_DEPLOYMENT || inputs.FIREBASE_PROJECT != 'prod' }}
270296
working-directory: web-app
271297
run: |
272-
if [ "${{ inputs.FIREBASE_PROJECT }}" != "prod" ]; then
273-
mv public/robots.staging.txt public/robots.txt
274-
fi
298+
mv public/robots.staging.txt public/robots.txt
275299
276300
- name: Build
277301
working-directory: web-app
@@ -293,6 +317,8 @@ jobs:
293317
run: |
294318
npx firebase hosting:channel:deploy ${{ inputs.PREVIEW_HOST_NAME }}
295319
HOSTING_URL=$(npx firebase hosting:channel:list | grep ${{ inputs.PREVIEW_HOST_NAME }} | awk '{print $7}')
296-
HOSTING_URL_64=$(echo $HOSTING_URL | base64)
297-
echo "hosting_url=$HOSTING_URL_64" >> "$GITHUB_OUTPUT"
320+
HOSTING_URL=$(echo "$HOSTING_URL" | sed 's/mobility-feeds-prod/__firebase_project__/g' | base64 -w 0)
321+
HOSTING_EXPIRATION_DATE=$(npx firebase hosting:channel:list | grep ${{ inputs.PREVIEW_HOST_NAME }} | awk '{printf "%s %s\n",$9,$10;}')
322+
echo "hosting_url=$HOSTING_URL" >> "$GITHUB_OUTPUT"
323+
echo "hosting_expiration_date=$HOSTING_EXPIRATION_DATE" >> "$GITHUB_OUTPUT"
298324

.github/workflows/web-pr.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ jobs:
2929
- name: Check for Existing Comment
3030
id: check-comment
3131
run: |
32-
HOSTING_URL=$(echo "$HOSTING_URL_64" | base64 -d)
33-
COMMENT="Preview Firebase Hosting URL: $HOSTING_URL"
32+
HOSTING_URL_DECODED=$(echo "$HOSTING_URL_64" | base64 -d | sed 's/__firebase_project__/mobility-feeds-dev/g')
33+
COMMENT="Preview Firebase Hosting URL: $HOSTING_URL_DECODED"
3434
echo "PR comment: $COMMENT"
3535
COMMENTS=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/issues/${{ env.PR_ID }}/comments")
3636
JQ_CHECK=`echo "$COMMENTS" | jq -r ".[] | select(.body == \"$COMMENT\")"`
@@ -47,10 +47,12 @@ jobs:
4747
- name: Comment on PR with Hosting URL (PR Preview)
4848
if: steps.check-comment.outputs.comment_exists == 'false'
4949
run: |
50-
HOSTING_URL=$(echo "$HOSTING_URL_64" | base64 -d)
51-
COMMENT="Preview Firebase Hosting URL: $HOSTING_URL"
50+
HOSTING_URL_DECODED=$(echo "$HOSTING_URL_64" | base64 -d | sed 's/__firebase_project__/mobility-feeds-dev/g')
51+
COMMENT="Preview Firebase Hosting URL: $HOSTING_URL_DECODED"
5252
echo "$COMMENT" > comment.txt
5353
curl -d "{\"body\":\"$(cat comment.txt)\"}" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -X POST "https://api.github.com/repos/${{ github.repository }}/issues/${{ env.PR_ID }}/comments"
5454
env:
55+
# Output is baseb4 encoded due to a false positive secret detection
56+
# More info https://github.com/orgs/community/discussions/37942
5557
HOSTING_URL_64: ${{ needs.deploy-web-app.outputs.hosting_url }}
5658

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# This workflow deploys a preview environment to PROD.
2+
# The pattern of the URL is:
3+
# - https://[firebase_project_id]--protoype-[random_suffix].web.app
4+
# The firebase preview environments creates undeterministics URLs using a random suffix.
5+
# The URL will be active for 30 days(maximum). After 30 days, Firebase will generare a new URL.
6+
7+
name: Web App - Prototype
8+
on:
9+
workflow_dispatch:
10+
inputs:
11+
PREVIEW_HOST_NAME:
12+
description: Preview host name
13+
default: 'prototype'
14+
required: false
15+
DEPLOYMENT_ENV:
16+
description: Environment in which the branch will be deployed. Valid values dev, qa and prod(default).
17+
default: 'prod'
18+
required: false
19+
jobs:
20+
21+
deploy-web-app:
22+
uses: ./.github/workflows/web-app-deployer.yml
23+
with:
24+
FIREBASE_PROJECT: ${{ inputs.DEPLOYMENT_ENV || 'prod' }}
25+
PREVIEW_DEPLOYMENT: true
26+
DEPLOY_FIREBASE_FUNCTIONS: false
27+
FEED_SUBMIT_GOOGLE_SHEET_ID: "1iXwux9hM4p5Li1EGgwx-8hU3sMDnF15yTflqmGjiZqE"
28+
OP_SLACK_WEBHOOK_URL: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/wm52iemzzm2cwfaoakwaufthuq/password"
29+
PREVIEW_HOST_NAME: ${{ inputs.PREVIEW_HOST_NAME || 'prototype' }}
30+
ENABLE_QUALITY_CHECKS: false
31+
PREVIEW_EXPIRES_DAYS: 30
32+
secrets: inherit
33+
34+
notify-slack:
35+
name: Notify Slack
36+
runs-on: ubuntu-latest
37+
needs: deploy-web-app
38+
steps:
39+
- name: Load secrets from 1Password
40+
id: onepw_secrets
41+
uses: 1password/[email protected]
42+
with:
43+
export-env: true
44+
env:
45+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
46+
CREDENTIALS: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/ifkeehu5gzi7wy5ub5qvwkaire/credential"
47+
SLACK_WEBHOOK_URL: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/Slack webhook URLs/internal-github-action-alerts/internal-github-action-alerts"
48+
49+
- name: Process Hosting URL
50+
id: process_hosting_url
51+
run: |
52+
HOSTING_URL_DECODED=$(echo "$HOSTING_URL" | base64 -d | sed 's/__firebase_project__/mobility-feeds-prod/g')
53+
echo "hosting_url_decoded=$HOSTING_URL_DECODED" >> "$GITHUB_OUTPUT"
54+
echo "hosting_url: $HOSTING_URL"
55+
echo "hosting_url_decoded: $HOSTING_URL_DECODED"
56+
env:
57+
# Output is baseb4 encoded due to a false positive secret detection
58+
# More info https://github.com/orgs/community/discussions/37942
59+
HOSTING_URL: ${{ needs.deploy-web-app.outputs.hosting_url }}
60+
61+
- name: Send Slack Notification
62+
uses: slackapi/[email protected]
63+
with:
64+
webhook: ${{ env.SLACK_WEBHOOK_URL }}
65+
webhook-type: incoming-webhook
66+
payload: |
67+
text: "Prototype Web App Deployed!\n"
68+
blocks:
69+
- type: "section"
70+
text:
71+
type: "mrkdwn"
72+
text: ":rocket: *Prototype Web App Deployed!* \n - *Prototype URL:* ${{ env.HOSTING_URL_ENCODED }} \n - *Expires on:* ${{ env.HOSTING_EXPIRATION_DATE }}"
73+
env:
74+
SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }}
75+
HOSTING_URL_ENCODED: ${{ steps.process_hosting_url.outputs.hosting_url_decoded }}
76+
HOSTING_EXPIRATION_DATE: ${{ needs.deploy-web-app.outputs.hosting_expiration_date }}
77+

0 commit comments

Comments
 (0)