Deployment automation refers to the process that enables you to deploy your code to various environments at the occurrence of an event without human intervention. Deployment automation enables you to give little to no focus on the deployment process, hence saving you time that could be spent on other activities.
Firebase cloud functions is a serverless framework that lets you automatically run backend code in response to events triggered by Firebase features and HTTPS requests. You can read more about that here.
Github actions provide a workflow that can help carry out various actions such as build the code in your repository, deploy to your production or staging environment, run tests on your code before carrying out some crucial operations, and so on. You can read more about Github actions here
This article assumes that you as a reader have some experience with firebase cloud functions, npm installed on your terminal, a firebase project created, and your cloud functions defined in your firebase project.
To deploy any firebase cloud functions project, you need to be authenticated via Firebase CLI but since GitHub actions will solely be responsible for the deployment process, you need to generate an authentication token from Firebase CLI and save it as a secret in your repository settings.
To install Firebase CLI, open your terminal and run
npm install -g firebase-tools
To generate the authentication token, run
firebase ci:login
The command above opens your browser and asks you to log in to the Google account connected to your firebase project. Upon login, a new token will be generated on your terminal. Open your Github repository and go to the Settings tab, click on the Secrets pane, copy and save the token generated on your terminal as a new secret. Once that's done, click on the Action tab, and click on setup a workflow yourself.
Read and copy the following gist content to the new workflow file created.
name: Deploy | |
# Controls when the workflow will run | |
'on': | |
#triggers the workflow whenever a push is made to the main branch | |
push: | |
branches: | |
- main | |
jobs: | |
#this workfloe has only one job | |
deploy_to_production: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v2 | |
# this install the dependencies specified in your package.json file into the current workflow | |
- name: install dependencies | |
# navigates to your functions folder and install the dependencies | |
run: cd functions/ && npm install | |
# If your firebase cloud functions project uses firebase-admin | |
# you need to create a config file used to initialize your project | |
# the below task creates a config.json file in your functions directory | |
- name: create config json | |
uses: jsdaniell/create-json@1.1.2 | |
id: create-config-json | |
with: | |
name: 'config.json' | |
json: '{"type": "${{ secrets.TYPE }}","auth_uri": "${{ secrets.AUTH_URI }}","auth_provider_x509_cert_url": "${{ secrets.AUTH_PROVIDER_X509_CERT_URL }}","private_key_id": "${{ secrets.PRIVATE_KEY_ID }}","project_id": "${{ secrets.PROJECT_ID }}","private_key": "${{ secrets.PRIVATE_KEY }}","token_uri": "${{ secrets.TOKEN_URI }}", "client_email": "${{ secrets.CLIENT_EMAIL }}","client_x509_cert_url": "${{ secrets.CLIENT_X509_CERT_URL }}","client_id": "${{ secrets.CLIENT_ID }}"}' | |
dir: 'functions/' | |
# The below task uses the w9jds/firebase-action@master action with the appropriate argument | |
# to deploy your firebase cloud functions. | |
- name: deploy to production | |
uses: w9jds/firebase-action@master | |
with: | |
args: deploy --only functions | |
env: | |
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} | |
If you have custom environment variables used in your project, you need to store the environment data. You can use the below workflow code
name: Deploy | |
# Controls when the workflow will run | |
'on': | |
#triggers the workflow whenever a push is made to the main branch | |
push: | |
branches: | |
- main | |
jobs: | |
#this workfloe has only one job | |
deploy_to_production: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v2 | |
# this install the dependencies specified in your package.json file into the current workflow | |
- name: install dependencies | |
# navigates to your functions folder and install the dependencies | |
run: cd functions/ && npm install | |
# If your firebase cloud functions project uses firebase-admin | |
# you need to create a config file used to initialize your project | |
# the below task creates a config.json file in your functions directory | |
- name: create config json | |
uses: jsdaniell/create-json@1.1.2 | |
id: create-config-json | |
with: | |
name: 'config.json' | |
json: '{"type": "${{ secrets.TYPE }}","auth_uri": "${{ secrets.AUTH_URI }}","auth_provider_x509_cert_url": "${{ secrets.AUTH_PROVIDER_X509_CERT_URL }}","private_key_id": "${{ secrets.PRIVATE_KEY_ID }}","project_id": "${{ secrets.PROJECT_ID }}","private_key": "${{ secrets.PRIVATE_KEY }}","token_uri": "${{ secrets.TOKEN_URI }}", "client_email": "${{ secrets.CLIENT_EMAIL }}","client_x509_cert_url": "${{ secrets.CLIENT_X509_CERT_URL }}","client_id": "${{ secrets.CLIENT_ID }}"}' | |
dir: 'functions/' | |
# create the json file that holds your confidential environment variables | |
- name: create env json | |
uses: jsdaniell/create-json@1.1.2 | |
id: create-env-json | |
with: | |
name: 'env.json' | |
json: '{"apiKey" : "${{secrets.apiKey}}" }' | |
dir: 'functions/' | |
# the below task clears the previous env data | |
- name: clear env configs | |
uses: w9jds/firebase-action@master | |
with: | |
args: functions:config:unset env | |
env: | |
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} | |
# store the env data | |
- name: set env configs | |
uses: w9jds/firebase-action@master | |
with: | |
args: functions:config:set env=\"$(cat functions/env.json)\" | |
env: | |
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} | |
# The below task uses the w9jds/firebase-action@master action with the appropriate argument | |
# to deploy your firebase cloud functions. | |
- name: deploy to production | |
uses: w9jds/firebase-action@master | |
with: | |
args: deploy --only functions | |
env: | |
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} | |
Thanks for reading! Feel free to drop suggestions and questions in the comment box 😊.
Top comments (1)
You could set the firebase token as a top-level env variable to avoid repeating it all over the workflow