CICD with firebase hosting
Technology used
- CICD Pipeline: Azure DevOps Pipeline
- Hosting Service: Firebase Hosting
- Source Code: Github
- Secret Management: Azure KeyVault
Step1: Create an App in Firebase
From Firebase Console, you want to create an “App”. For exact steps, you can refer to the document here, https://support.google.com/firebase/answer/9326094?hl=en
or
you can also run following command
firebase hosting:sites:create SITE_IDMake sure to tick “Also set up Firebase Hosting for this app.”
For our use case, we created three projects (dev, stage, and prod) and each contains one web app.
Tip: you can label the project to be Prod. This helps engineers to visually differentiate between different projects.
Step2: Get the required secrets
we need the project id and firebase deploy token.
project id can be fetched from
firebase console > project settings > general firebase deploy token needs to be generated
firebase login:ciStep3: Set up secrets in Azure KeyVault
You need secrets to deploy frontend projects to firebase hosting. Since we are using Azure DevOps for the cicd pipeline, KeyVault was the de facto standard to share secrets.
Step3.1: Manually add secrets in Azure KeyVault
Step3.2: Link it with the library from Azure DevOps
Step4: Prep YAML for the pipeline
I just added dev env in the sample below but you can extend YAML by just adding more env as you need. (Spacing might be wrong as copy&paste directly from vscode did not help with the correct spacing)
# webhosting.yaml
stages:
- stage: dev
jobs:
- template: templates/cicd.yaml
parameters:
env: dev# templates/cicd.yaml
parameters:
- name: env
type: string
default: 'dev'jobs:
- job: CI${{ parameters.env }}
displayName: CI ${{ parameters.env }}
variables:
- group: kv-${{ parameters.env }}
steps:
- task: NodeTool@0
inputs:
versionSpec: '16.x'
displayName: 'Install Node.js'
- task: Bash@3
inputs:
targetType: 'inline'
script: |
yarn install
yarn run build
- task: CopyFiles@2
inputs:
sourceFolder: '$(System.DefaultWorkingDirectory)/dist'
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop${{ parameters.env }}/dist'
- task: CopyFiles@2
inputs:
sourceFolder: $(System.DefaultWorkingDirectory)
contents: 'firebase.json'
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop${{ parameters.env }}
- deployment:
condition: in(variables['Build.SourceBranch'], 'refs/heads/main')
variables:
- group: kv-${{ parameters.env }}
strategy:
runOnce:
deploy:
steps:
- task: DownloadBuildArtifacts@1
inputs:
buildType: 'current'
artifactName: drop${{ parameters.env }}
- script: |
npm install -g firebase-tools
- script: |
cd drop${{ parameters.env }}
firebase deploy --token $(token) --project $(projectId) --force -m $(Build.BuildNumber)
