Created
January 24, 2021 16:00
-
-
Save anshajk/2ac022116732d7e2c0b3f9a66a0841c4 to your computer and use it in GitHub Desktop.
Continuous deployment using GitHub Actions for Firebase Remote Config
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: remote-config-deployer | |
on: [push] | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v2 | |
- name: Set up Python | |
uses: actions/setup-python@v2 | |
with: | |
python-version: '3.8' | |
- name: Cache pip | |
uses: actions/cache@v2 | |
with: | |
path: ~/.cache/pip | |
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} | |
restore-keys: | | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | |
deploy: | |
runs-on: ubuntu-latest | |
needs: build | |
if: success() && github.ref == 'refs/heads/main' | |
steps: | |
- uses: actions/checkout@v2 | |
- name: Set up Python | |
uses: actions/setup-python@v2 | |
with: | |
python-version: '3.8' | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | |
- name: Publish | |
env: | |
PROJECT_ID: ${{ secrets.PROJECT_ID }} | |
CREDENTIALS: ${{ secrets.CREDENTIALS }} | |
run: | | |
python remote_config_manager.py --action=publish |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import requests | |
import io | |
from oauth2client.service_account import ServiceAccountCredentials | |
import json | |
import os | |
PROJECT_ID = os.getenv("PROJECT_ID") | |
CREDENTIALS = json.loads(os.getenv("CREDENTIALS")) | |
BASE_URL = "https://firebaseremoteconfig.googleapis.com" | |
REMOTE_CONFIG_ENDPOINT = "v1/projects/" + PROJECT_ID + "/remoteConfig" | |
REMOTE_CONFIG_URL = BASE_URL + "/" + REMOTE_CONFIG_ENDPOINT | |
SCOPES = ["https://www.googleapis.com/auth/firebase.remoteconfig"] | |
# [START retrieve_access_token] | |
def _get_access_token(): | |
"""Retrieve a valid access token that can be used to authorize requests. | |
:return: Access token. | |
""" | |
credentials = ServiceAccountCredentials.from_json_keyfile_dict(CREDENTIALS, SCOPES) | |
access_token_info = credentials.get_access_token() | |
return access_token_info.access_token | |
# [END retrieve_access_token] | |
def _get(save=False): | |
"""Retrieve the current Firebase Remote Config template from server. | |
Retrieve the current Firebase Remote Config template from server and store it | |
locally. | |
""" | |
headers = {"Authorization": "Bearer " + _get_access_token()} | |
resp = requests.get(REMOTE_CONFIG_URL, headers=headers) | |
if save != False and resp.status_code == 200: | |
with io.open("config.json", "wb") as f: | |
f.write(resp.text.encode("utf-8")) | |
print("Retrieved template has been written to config.json") | |
return resp.headers["ETag"] | |
def _listVersions(): | |
"""Print the last 5 Remote Config version's metadata.""" | |
headers = {"Authorization": "Bearer " + _get_access_token()} | |
resp = requests.get(REMOTE_CONFIG_URL + ":listVersions?pageSize=5", headers=headers) | |
if resp.status_code == 200: | |
print("Versions:") | |
print(resp.text) | |
else: | |
print("Request to print template versions failed.") | |
print(resp.text) | |
def _rollback(version): | |
"""Roll back to an available version of Firebase Remote Config template. | |
:param version: The version of the template to roll back to. | |
""" | |
headers = {"Authorization": "Bearer " + _get_access_token()} | |
json = {"version_number": version} | |
resp = requests.post(REMOTE_CONFIG_URL + ":rollback", headers=headers, json=json) | |
if resp.status_code == 200: | |
print("Rolled back to version: " + version) | |
print(resp.text) | |
print("ETag from server: {}".format(resp.headers["ETag"])) | |
else: | |
print("Request to roll back to version " + version + " failed.") | |
print(resp.text) | |
def _publish(): | |
"""Publish local template to Firebase server. | |
Args: | |
etag: ETag for safe (avoid race conditions) template updates. | |
* can be used to force template replacement. | |
""" | |
etag = _get() | |
with open("remoteconfig.template.json", "r", encoding="utf-8") as f: | |
content = f.read() | |
headers = { | |
"Authorization": "Bearer " + _get_access_token(), | |
"Content-Type": "application/json; UTF-8", | |
"If-Match": etag, | |
} | |
resp = requests.put( | |
REMOTE_CONFIG_URL, data=content.encode("utf-8"), headers=headers | |
) | |
if resp.status_code == 200: | |
print("Template has been published.") | |
print("ETag from server: {}".format(resp.headers["ETag"])) | |
else: | |
print("Unable to publish template.") | |
print(resp.text) | |
def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument("--action") | |
parser.add_argument("--etag") | |
parser.add_argument("--version") | |
args = parser.parse_args() | |
if args.action and args.action == "get": | |
_get() | |
elif args.action and args.action == "publish": | |
_publish() | |
elif args.action and args.action == "versions": | |
_listVersions() | |
elif args.action and args.action == "rollback" and args.version: | |
_rollback(args.version) | |
else: | |
print( | |
"""Invalid command. Please use one of the following commands: | |
python configure.py --action=get | |
python configure.py --action=publish | |
python configure.py --action=versions | |
python configure.py --action=rollback --version=<TEMPLATE_VERSION_NUMBER>""" | |
) | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
oauth2client | |
requests | |
python-dotenv |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment